# ============================================================================= # Deploy to Production Server # ============================================================================= # Triggers after successful build on main/master branch # SSHs to production server and updates containers # ============================================================================= name: Deploy to Production on: workflow_run: workflows: ["Build and Push"] types: [completed] branches: [main, master] env: REGISTRY: qbit.realms.pub IMAGE_PREFIX: realms jobs: deploy: # Only deploy if the build succeeded if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: docker steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup SSH key run: | mkdir -p ~/.ssh echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key # Add host key (skip strict checking for first connection) ssh-keyscan -p ${{ secrets.DEPLOY_PORT }} ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true - name: Copy docker-compose to server run: | scp -i ~/.ssh/deploy_key -P ${{ secrets.DEPLOY_PORT }} \ -o StrictHostKeyChecking=no \ docker-compose.prod.yml \ root@${{ secrets.DEPLOY_HOST }}:/opt/realms/docker-compose.yml - name: Deploy to Production run: | ssh -i ~/.ssh/deploy_key -p ${{ secrets.DEPLOY_PORT }} \ -o StrictHostKeyChecking=no \ root@${{ secrets.DEPLOY_HOST }} ' set -e cd /opt/realms # Login to registry echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin # Pull latest images docker compose pull # Bring up services with zero-downtime restart docker compose up -d --remove-orphans # Prune old images docker image prune -f # Show running containers docker compose ps ' - name: Cleanup SSH key if: always() run: rm -f ~/.ssh/deploy_key - name: Health Check run: | sleep 10 ssh -i ~/.ssh/deploy_key -p ${{ secrets.DEPLOY_PORT }} \ -o StrictHostKeyChecking=no \ root@${{ secrets.DEPLOY_HOST }} ' # Check if services are running docker compose ps --format "table {{.Name}}\t{{.Status}}" # Basic health check for frontend curl -sf http://localhost:80/health || echo "Frontend health check pending" ' || true