Fix to handle existing containers. #5
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
| name: '🚀 Deploy Next.js Docker App' | |
| on: | |
| push: | |
| branches: [main] | |
| jobs: | |
| build-and-deploy: | |
| runs-on: self-hosted | |
| name: '🐳 Build & Deploy' | |
| steps: | |
| - name: '🔍 Checkout Code' | |
| uses: actions/checkout@v4 | |
| # ======================== | |
| # 🔐 Secrets & Config Setup | |
| # ======================== | |
| - name: '🔒 Verify Secrets Exist' | |
| run: | | |
| if [ -z "${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }}" ]; then | |
| echo "❌ Critical error: GOOGLE_SERVICES_JSON_BASE64 secret missing!" | |
| exit 1 | |
| fi | |
| echo "✅ All secrets present" | |
| - name: '📁 Create google-services.json' | |
| run: | | |
| echo "$GOOGLE_SERVICES_JSON_BASE64" | base64 --decode > google-services.json | |
| echo "🔄 Validating JSON..." | |
| if ! jq empty google-services.json; then | |
| echo "❌ JSON validation failed!" | |
| exit 1 | |
| fi | |
| env: | |
| GOOGLE_SERVICES_JSON_BASE64: ${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }} | |
| - name: '⚙️ Create .env File' | |
| run: | | |
| echo "${{ secrets.ENV_FILE_CONTENT }}" > .env | |
| echo "" >> .env | |
| # ======================================================= | |
| # 🐳 Docker Compose Operations (This section is updated) | |
| # ======================================================= | |
| - name: '🚀 Launch or Update Services' | |
| run: | | |
| # Step 1: Explicitly check for the network and create it only if it's missing. | |
| # This is more robust than the previous '|| true' syntax. | |
| if ! docker network ls | grep -q "codebuilder-net"; then | |
| echo "Network 'codebuilder-net' not found. Creating it..." | |
| docker network create codebuilder-net | |
| else | |
| echo "Network 'codebuilder-net' already exists. Skipping creation." | |
| fi | |
| # Step 2: Bring up all services defined in the compose file. | |
| # This command is idempotent. On the first run, it creates and starts everything. | |
| # On subsequent runs, it will connect to existing containers and ensure they | |
| # are started if they were stopped, but it will NOT try to re-create them. | |
| # This safely ensures the database is running before we proceed. | |
| echo "Ensuring all services are up..." | |
| docker compose up -d | |
| # Step 3: Force a rebuild and replacement of the webapp service ONLY. | |
| # This is the key command for zero-downtime-style updates of your app. | |
| # --no-deps: Guarantees that the 'db' container will not be touched. | |
| # --build: Rebuilds the webapp image from your latest source code. | |
| # --force-recreate: Explicitly stops the old webapp container and starts a new one | |
| # from the new image, even if the configuration is the same. | |
| echo "Rebuilding and force-recreating the webapp service..." | |
| docker compose up -d --no-deps --build --force-recreate webapp | |
| - name: '🗑 Prune Old Docker Images' | |
| if: always() # This step will run even if the deployment fails. | |
| run: | | |
| docker image prune -af |