#!/bin/bash set -euo pipefail exec > >(tee /var/log/cloud-init-app.log) 2>&1 echo "=== OCI CIS Agent cloud-init started at $(date) ===" # ----------------------------------------------------------------------------- # 1. Install Docker CE + docker-compose-plugin # ----------------------------------------------------------------------------- echo ">>> Installing Docker CE..." dnf install -y dnf-utils dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin --allowerasing systemctl enable docker systemctl start docker echo ">>> Docker version: $(docker --version)" echo ">>> Docker Compose version: $(docker compose version)" # ----------------------------------------------------------------------------- # 2. Wait for block device # ----------------------------------------------------------------------------- DATA_DEVICE="${data_device}" echo ">>> Waiting for block device $DATA_DEVICE..." ATTEMPTS=0 MAX_ATTEMPTS=60 while [ ! -e "$DATA_DEVICE" ] && [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do echo " Waiting for $DATA_DEVICE (attempt $((ATTEMPTS+1))/$MAX_ATTEMPTS)..." sleep 5 ATTEMPTS=$((ATTEMPTS+1)) done if [ ! -e "$DATA_DEVICE" ]; then echo "ERROR: Block device $DATA_DEVICE not found after $MAX_ATTEMPTS attempts" exit 1 fi echo ">>> Block device $DATA_DEVICE is available" # ----------------------------------------------------------------------------- # 3. Format and mount /data # ----------------------------------------------------------------------------- if ! blkid "$DATA_DEVICE" | grep -q ext4; then echo ">>> Formatting $DATA_DEVICE as ext4..." mkfs.ext4 -F "$DATA_DEVICE" fi mkdir -p /data mount "$DATA_DEVICE" /data if ! grep -q "$DATA_DEVICE" /etc/fstab; then echo "$DATA_DEVICE /data ext4 defaults,_netdev,nofail 0 2" >> /etc/fstab fi echo ">>> /data mounted successfully" df -h /data # ----------------------------------------------------------------------------- # 4. Docker login to OCIR # ----------------------------------------------------------------------------- OCIR_ENDPOINT="${ocir_region}.ocir.io" echo ">>> Logging into OCIR at $OCIR_ENDPOINT..." echo '${ocir_auth_token}' | docker login "$OCIR_ENDPOINT" \ -u "${ocir_namespace}/${ocir_username}" \ --password-stdin # ----------------------------------------------------------------------------- # 5. Pull image # ----------------------------------------------------------------------------- IMAGE="$OCIR_ENDPOINT/${ocir_namespace}/${ocir_repo_prefix}:latest" echo ">>> Pulling image: $IMAGE" docker pull "$IMAGE" # ----------------------------------------------------------------------------- # 6. Write docker-compose.yml # ----------------------------------------------------------------------------- APP_DIR="/opt/oci-cis-agent" mkdir -p "$APP_DIR" cat > "$APP_DIR/docker-compose.yml" <<'COMPOSE_EOF' services: agent: image: ${ocir_region}.ocir.io/${ocir_namespace}/${ocir_repo_prefix}:latest container_name: oci-cis-agent restart: unless-stopped environment: - APP_SECRET=${app_secret} - JWT_EXPIRY_HOURS=${jwt_expiry_hours} - DATA_DIR=/data - CORS_ORIGINS=${cors_origins} - TZ=${app_timezone} - OCI_CLI_SUPPRESS_FILE_PERMISSIONS_WARNING=True ports: - "8080:8080" volumes: - /data:/data mem_limit: 4g healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"] interval: 30s timeout: 10s retries: 3 start_period: 30s COMPOSE_EOF echo ">>> docker-compose.yml written to $APP_DIR" # ----------------------------------------------------------------------------- # 7. Start application # ----------------------------------------------------------------------------- echo ">>> Starting application..." cd "$APP_DIR" docker compose up -d # ----------------------------------------------------------------------------- # 8. Health check wait loop # ----------------------------------------------------------------------------- echo ">>> Waiting for application to become healthy..." ATTEMPTS=0 MAX_ATTEMPTS=60 while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do if curl -sf http://localhost:8080/api/health > /dev/null 2>&1; then echo ">>> Application is healthy!" break fi echo " Health check attempt $((ATTEMPTS+1))/$MAX_ATTEMPTS..." sleep 10 ATTEMPTS=$((ATTEMPTS+1)) done if [ $ATTEMPTS -eq $MAX_ATTEMPTS ]; then echo "WARNING: Application did not become healthy within expected time" echo ">>> Container status:" docker compose ps echo ">>> Logs:" docker compose logs --tail 50 fi echo "=== OCI CIS Agent cloud-init finished at $(date) ==="