name: Build & Deploy on: push: branches: [main] workflow_dispatch: permissions: contents: read packages: write concurrency: group: production-deploy cancel-in-progress: true jobs: build-and-push-images: name: Build & Push Docker Images runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set image namespace id: vars run: echo "owner_lc=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_OUTPUT" - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push backend image uses: docker/build-push-action@v6 with: context: ./backend file: ./backend/Dockerfile push: true tags: | ghcr.io/${{ steps.vars.outputs.owner_lc }}/cloudlense-backend:latest ghcr.io/${{ steps.vars.outputs.owner_lc }}/cloudlense-backend:${{ github.sha }} - name: Build and push frontend image uses: docker/build-push-action@v6 with: context: ./frontend file: ./frontend/Dockerfile push: true build-args: | NEXT_PUBLIC_SUPABASE_URL=https://placeholder.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=placeholder-key SUPABASE_SERVICE_ROLE_KEY=placeholder-service-key tags: | ghcr.io/${{ steps.vars.outputs.owner_lc }}/cloudlense-frontend:latest ghcr.io/${{ steps.vars.outputs.owner_lc }}/cloudlense-frontend:${{ github.sha }} deploy-to-server: name: Deploy on Server runs-on: ubuntu-latest needs: build-and-push-images steps: - uses: actions/checkout@v4 - name: Upload production compose file uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} port: ${{ secrets.DEPLOY_PORT || '22' }} source: "devops/docker-compose.prod.yml" target: ${{ secrets.DEPLOY_PATH }} strip_components: 1 - name: Upload deploy script uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} port: ${{ secrets.DEPLOY_PORT || '22' }} source: "devops/scripts/deploy-prod.sh" target: ${{ secrets.DEPLOY_PATH }} strip_components: 2 - name: Deploy containers uses: appleboy/ssh-action@v1.2.0 env: DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }} GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }} GHCR_READ_TOKEN: ${{ secrets.GHCR_READ_TOKEN }} IMAGE_TAG: ${{ github.sha }} GHCR_OWNER: ${{ github.repository_owner }} with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} port: ${{ secrets.DEPLOY_PORT || '22' }} envs: DEPLOY_PATH,GHCR_USERNAME,GHCR_READ_TOKEN,IMAGE_TAG,GHCR_OWNER script_stop: true script: | set -euo pipefail cd "${DEPLOY_PATH}" chmod +x deploy-prod.sh GHCR_OWNER="$(echo "${GHCR_OWNER}" | tr '[:upper:]' '[:lower:]')" ./deploy-prod.sh curl -fsS "http://localhost:5000/health" >/dev/null curl -fsS "http://localhost:3000" >/dev/null