Deploy Cube Cloud Services #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright (c) Ultraviolet | |
| # SPDX-License-Identifier: Apache-2.0 | |
| name: Deploy Cube Cloud Services | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - "docker/compose.yaml" | |
| - "docker/supermq-compose.yaml" | |
| - "docker/cube-compose.yaml" | |
| - "docker/.env" | |
| - "docker/config.json" | |
| - "docker/fluent-bit.conf" | |
| - "docker/parsers.conf" | |
| - "docker/opensearch-index-template.json" | |
| - "docker/traefik/traefik.toml" | |
| - "docker/traefik/dynamic.toml" | |
| - ".github/workflows/deploy-cloud.yaml" | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: "Deployment environment" | |
| required: true | |
| default: "dev" | |
| type: choice | |
| options: | |
| - dev | |
| - staging | |
| - production | |
| concurrency: | |
| group: deploy-cloud-${{ github.ref }} | |
| cancel-in-progress: false | |
| env: | |
| REGISTRY: ghcr.io | |
| DEPLOY_DIR: cube-cloud | |
| jobs: | |
| deploy-cloud: | |
| runs-on: ubuntu-latest | |
| environment: ${{ inputs.environment || 'dev' }} | |
| permissions: | |
| contents: read | |
| packages: read | |
| steps: | |
| - name: Deploy Cube Cloud Services | |
| uses: appleboy/ssh-action@v1.0.3 | |
| with: | |
| host: ${{ secrets.CUBE_SERVER_IP }} | |
| port: 49200 | |
| username: ${{ secrets.CUBE_SERVER_USERNAME }} | |
| key: ${{ secrets.CUBE_SERVER_KEY }} | |
| script_stop: true | |
| command_timeout: 200m | |
| script: | | |
| set -euo pipefail | |
| echo "=== Cube Cloud Deployment Started ===" | |
| echo "Logging into GitHub Container Registry" | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
| echo "Changing directory to project" | |
| cd ${{ env.DEPLOY_DIR }} | |
| echo "Pulling latest code from repository" | |
| git stash | |
| git pull | |
| echo "Creating required directories and setting up SSL" | |
| mkdir -p docker/traefik/ssl/certs | |
| # Initialize acme.json if it doesn't exist | |
| if test -f docker/traefik/ssl/certs/acme.json; then | |
| chmod 600 docker/traefik/ssl/certs/acme.json | |
| echo " ✓ acme.json already exists" | |
| else | |
| printf '{}' > docker/traefik/ssl/certs/acme.json | |
| chmod 600 docker/traefik/ssl/certs/acme.json | |
| echo " ✓ Created acme.json" | |
| fi | |
| echo "Updating environment variables and configuration with secrets" | |
| # Replace placeholder with actual public URL from secrets | |
| sed -i "s|__SMQ_EMAIL_HOST__|${{ secrets.SMQ_EMAIL_HOST }}|g" docker/.env | |
| sed -i "s|__SMQ_EMAIL_PORT__|${{ secrets.SMQ_EMAIL_PORT }}|g" docker/.env | |
| sed -i "s|__SMQ_EMAIL_USERNAME__|${{ secrets.SMQ_EMAIL_USERNAME }}|g" docker/.env | |
| sed -i "s|__SMQ_EMAIL_PASSWORD__|${{ secrets.SMQ_EMAIL_PASSWORD }}|g" docker/.env | |
| sed -i "s|__SMQ_EMAIL_FROM_ADDRESS__|${{ secrets.SMQ_EMAIL_FROM_ADDRESS }}|g" docker/.env | |
| sed -i "s|admin@example.com|${{ secrets.CUBE_ADMIN_EMAIL }}|g" docker/.env | |
| sed -i "s|"m2N2Lfno"|"${{ secrets.CUBE_ADMIN_PASSWORD }}"|g" docker/.env | |
| sed -i "s|__CUBE_PUBLIC_URL__|${{ secrets.CUBE_PUBLIC_URL }}|g" docker/.env | |
| sed -i "s|__CUBE_INTERNAL_AGENT_URL__|${{ secrets.CUBE_INTERNAL_AGENT_URL }}|g" docker/.env | |
| # Replace Google OAuth placeholders | |
| sed -i "s|__SMQ_GOOGLE_CLIENT_ID__|${{ secrets.SMQ_GOOGLE_CLIENT_ID }}|g" docker/.env | |
| sed -i "s|__SMQ_GOOGLE_CLIENT_SECRET__|${{ secrets.SMQ_GOOGLE_CLIENT_SECRET }}|g" docker/.env | |
| sed -i "s|__SMQ_GOOGLE_STATE__|${{ secrets.SMQ_GOOGLE_STATE }}|g" docker/.env | |
| # Replace Traefik configuration placeholders | |
| sed -i "s|__TRAEFIK_HTTP_PORT__|${{ secrets.TRAEFIK_HTTP_PORT }}|g" docker/.env | |
| sed -i "s|__TRAEFIK_HTTPS_PORT__|${{ secrets.TRAEFIK_HTTPS_PORT }}|g" docker/.env | |
| sed -i "s|__TRAEFIK_DASHBOARD_PORT__|${{ secrets.TRAEFIK_DASHBOARD_PORT }}|g" docker/.env | |
| sed -i "s|__TUNNEL_TOKEN__|${{ secrets.TUNNEL_TOKEN }}|g" docker/.env | |
| sed -i "s|__CUBE_AGENT_CERTS_TOKEN__|${{ secrets.CUBE_AGENT_CERTS_TOKEN }}|g" docker/.env | |
| sed -i "s|__CUBE_INTERNAL_AGENT_URL__|${{ secrets.CUBE_INTERNAL_AGENT_URL }}|g" docker/config.json | |
| # Replace placeholder with actual domain from secrets | |
| sed -i "s|__CUBE_DOMAIN__|${{ secrets.CUBE_DOMAIN }}|g" docker/traefik/dynamic.toml | |
| echo "Pulling latest Docker images" | |
| docker compose -f docker/compose.yaml --profile cloud pull 2>&1 | |
| echo "Stopping existing services" | |
| docker compose -f docker/compose.yaml --profile cloud down 2>&1 | |
| echo "Starting cloud services" | |
| docker compose -f docker/compose.yaml --profile cloud up -d 2>&1 | |
| echo "Waiting for services to start (30 seconds)..." | |
| sleep 30 | |
| echo "Checking service status..." | |
| docker compose -f docker/compose.yaml --profile cloud ps 2>&1 | |
| echo "=== Verifying Critical Services ===" | |
| SERVICES="traefik opensearch nats spicedb auth users domains ui cube-proxy guardrails fluent-bit" | |
| ALL_RUNNING=true | |
| for SERVICE in $SERVICES; do | |
| if docker ps --format '{{.Names}}' | grep -q "$SERVICE"; then | |
| echo "✓ Service $SERVICE is running" | |
| else | |
| echo "✗ Service $SERVICE is not running" | |
| ALL_RUNNING=false | |
| fi | |
| done | |
| if [ "$ALL_RUNNING" = false ]; then | |
| echo "Deployment verification failed!" | |
| make logs-cloud 2>&1 | tail -100 | |
| exit 1 | |
| fi | |
| echo "✓ All cloud services deployed successfully!" | |
| echo "" | |
| echo "=== Service URLs (All through Traefik Gateway) ===" | |
| echo " - Cube UI: ${{ secrets.CUBE_PUBLIC_URL }}/" | |
| echo " - Cube Proxy API: ${{ secrets.CUBE_PUBLIC_URL }}/proxy" | |
| echo " - Traefik Dashboard: http://${{ secrets.CUBE_SERVER_IP }}:49212" | |
| echo "" | |
| echo "Note: HTTP automatically redirects to HTTPS" | |
| - name: System Cleanup | |
| if: always() | |
| uses: appleboy/ssh-action@v1.0.3 | |
| with: | |
| host: ${{ secrets.CUBE_SERVER_IP }} | |
| port: 49200 | |
| username: ${{ secrets.CUBE_SERVER_USERNAME }} | |
| key: ${{ secrets.CUBE_SERVER_KEY }} | |
| script_stop: false | |
| command_timeout: 10m | |
| script: | | |
| echo "Running system cleanup..." | |
| docker system prune -a -f | |
| echo "✓ Cleanup completed" |