name: Deploy to Production on: push: branches: [master] jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Docker CLI run: | apt-get update -qq && apt-get install -y -qq docker.io >/dev/null 2>&1 mkdir -p ~/.docker/cli-plugins curl -fsSL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \ -o ~/.docker/cli-plugins/docker-compose chmod +x ~/.docker/cli-plugins/docker-compose docker compose version - name: Create .env.prod from secrets run: | cat < .env.prod DB_USER=${{ secrets.DB_USER }} DB_PASSWORD=${{ secrets.DB_PASSWORD }} DB_NAME=${{ secrets.DB_NAME }} JWT_SECRET=${{ secrets.JWT_SECRET }} KIS_APP_KEY=${{ secrets.KIS_APP_KEY }} KIS_APP_SECRET=${{ secrets.KIS_APP_SECRET }} KIS_ACCOUNT_NO=${{ secrets.KIS_ACCOUNT_NO }} DART_API_KEY=${{ secrets.DART_API_KEY }} CORS_ORIGINS=${{ secrets.CORS_ORIGINS }} ADMIN_USERNAME=${{ secrets.ADMIN_USERNAME }} ADMIN_EMAIL=${{ secrets.ADMIN_EMAIL }} ADMIN_PASSWORD=${{ secrets.ADMIN_PASSWORD }} KRX_OPENAPI_KEY=${{ secrets.KRX_OPENAPI_KEY }} KRX_ID=${{ secrets.KRX_ID }} KRX_PW=${{ secrets.KRX_PW }} EOF - name: Backup database before deploy run: | docker exec galaxis-po-db pg_dump -U ${{ secrets.DB_USER }} ${{ secrets.DB_NAME }} \ > /tmp/galaxis-po-backup-$(date +%Y%m%d_%H%M%S).sql 2>/dev/null || true - name: Deploy with Docker Compose run: | docker compose --project-name galaxis-po --env-file .env.prod -f docker-compose.prod.yml down || true docker compose --project-name galaxis-po --env-file .env.prod -f docker-compose.prod.yml build docker compose --project-name galaxis-po --env-file .env.prod -f docker-compose.prod.yml up -d - name: Health check run: | echo "Waiting for all containers to become healthy..." for i in $(seq 1 30); do STATUS=$(docker inspect --format='{{.State.Health.Status}}' galaxis-po-frontend 2>/dev/null || echo "missing") if [ "$STATUS" = "healthy" ]; then break fi echo " frontend: $STATUS (attempt $i/30)" sleep 5 done docker compose --project-name galaxis-po --env-file .env.prod -f docker-compose.prod.yml ps docker exec galaxis-po-backend python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || { echo "Backend: FAILED"; exit 1; } echo "Backend: OK" docker exec galaxis-po-frontend wget -q --spider http://127.0.0.1:3000/ || { echo "Frontend: FAILED"; exit 1; } echo "Frontend: OK" - name: Run DB migrations run: | docker exec galaxis-po-backend alembic upgrade head - name: Re-seed portfolio data run: | docker exec galaxis-po-backend python -m scripts.seed_data - name: Generate portfolio snapshots run: | docker exec galaxis-po-backend python -m scripts.generate_snapshots