Files
codex f0a0667b84
All checks were successful
Deploy to Production / deploy (push) Successful in 57s
deploy: support configurable backend host for frontend API URL
2026-03-11 17:55:07 +08:00

88 lines
3.4 KiB
YAML

name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
run: |
git clone "http://172.17.0.1:3000/${{ github.repository }}.git" .
git checkout "${{ github.sha }}"
- name: Create .env.production from secrets
run: |
cat > .env.production << 'ENVEOF'
DOMAIN=${{ secrets.DOMAIN }}
BACKEND_HOST=${{ secrets.BACKEND_HOST }}
FRONTEND_HOST=${{ secrets.FRONTEND_HOST }}
ENVIRONMENT=production
PROJECT_NAME=${{ secrets.PROJECT_NAME }}
STACK_NAME=${{ secrets.STACK_NAME }}
BACKEND_CORS_ORIGINS=${{ secrets.BACKEND_CORS_ORIGINS }}
SECRET_KEY=${{ secrets.SECRET_KEY }}
FIRST_SUPERUSER=${{ secrets.FIRST_SUPERUSER }}
FIRST_SUPERUSER_PASSWORD=${{ secrets.FIRST_SUPERUSER_PASSWORD }}
SMTP_HOST=${{ secrets.SMTP_HOST }}
SMTP_USER=${{ secrets.SMTP_USER }}
SMTP_PASSWORD=${{ secrets.SMTP_PASSWORD }}
EMAILS_FROM_EMAIL=${{ secrets.EMAILS_FROM_EMAIL }}
SMTP_TLS=${{ secrets.SMTP_TLS }}
SMTP_SSL=${{ secrets.SMTP_SSL }}
SMTP_PORT=${{ secrets.SMTP_PORT }}
POSTGRES_SERVER=${{ secrets.POSTGRES_SERVER }}
POSTGRES_PORT=${{ secrets.POSTGRES_PORT }}
POSTGRES_DB=${{ secrets.POSTGRES_DB }}
POSTGRES_USER=${{ secrets.POSTGRES_USER }}
POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
DOCKER_IMAGE_BACKEND=${{ secrets.DOCKER_IMAGE_BACKEND }}
DOCKER_IMAGE_FRONTEND=${{ secrets.DOCKER_IMAGE_FRONTEND }}
ENVEOF
# Fallback defaults if image name secrets are empty
sed -i 's/^DOCKER_IMAGE_BACKEND=$/DOCKER_IMAGE_BACKEND=backend/' .env.production
sed -i 's/^DOCKER_IMAGE_FRONTEND=$/DOCKER_IMAGE_FRONTEND=frontend/' .env.production
- name: Build Docker images
run: docker compose --env-file .env.production -f compose.prod.yml build
- name: Stop existing services
run: docker compose --env-file .env.production -f compose.prod.yml down --remove-orphans || true
- name: Start services
run: docker compose --env-file .env.production -f compose.prod.yml up -d
- name: Wait for backend health check
run: |
echo "Waiting for backend container health=healthy..."
for i in $(seq 1 30); do
status=$(docker inspect -f '{{.State.Health.Status}}' full-stack-fastapi-backend-1 2>/dev/null || echo "unknown")
if [ "$status" = "healthy" ]; then
echo "✅ Backend is healthy!"
exit 0
fi
echo "Attempt $i/30 - status=$status, waiting 10s..."
sleep 10
done
echo "❌ Backend health check failed after 300s"
docker compose --env-file .env.production -f compose.prod.yml logs backend
exit 1
- name: Verify frontend
run: |
if docker compose --env-file .env.production -f compose.prod.yml ps frontend --status running | grep -q frontend; then
echo "✅ Frontend is accessible!"
else
echo "❌ Frontend is not accessible"
docker compose --env-file .env.production -f compose.prod.yml logs frontend
exit 1
fi
- name: Cleanup old Docker images
run: docker image prune -f || true