Deploy Prompteus to AWS #133
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
| # This workflow deploys the Prompteus multi-service application to AWS EC2 | |
| # | |
| # IMPORTANT: This workflow depends on the CI/CD workflows for each service to build | |
| # and publish Docker images to GitHub Container Registry (GHCR) before deployment. | |
| # The workflow will automatically wait for all builder workflows to complete successfully. | |
| # | |
| # Prerequisites: | |
| # 1. EC2 instance with Docker and Docker Compose installed | |
| # 2. A .env file exists in the repository root with base configuration for all services | |
| # 3. Configure the following repository variables (Settings > Secrets and variables > Actions > Variables): | |
| # - EC2_PUBLIC_IP: Your EC2 instance public IP address | |
| # - AWS_EC2_USER: SSH username (usually 'ubuntu' or 'ec2-user') | |
| # | |
| # 4. Configure the following repository secrets (Settings > Secrets and variables > Actions > Secrets): | |
| # - AWS_EC2_PRIVATE_KEY: Your EC2 private key for SSH access | |
| # - POSTGRES_PASSWORD: Strong password for PostgreSQL database (overrides .env) | |
| # - MEILI_MASTER_KEY: Strong master key for MeiliSearch (overrides .env) | |
| # - OPENAI_API_KEY: (Optional) If using OpenAI instead of Ollama for LLM services | |
| # | |
| # 5. The workflow uses nip.io for easy SSL-enabled domain names: | |
| # - Client will be available at: https://client.{EC2_PUBLIC_IP}.nip.io | |
| # - API will be available at: https://api.{EC2_PUBLIC_IP}.nip.io | |
| # | |
| # 6. Make sure your EC2 security group allows inbound traffic on: | |
| # - Port 22 (SSH) | |
| # - Port 80 (HTTP) | |
| # - Port 443 (HTTPS) | |
| # - Port 8081 (Client service) | |
| # - Port 8080 (API services) | |
| name: Deploy Prompteus to AWS | |
| on: | |
| workflow_dispatch: | |
| workflow_run: | |
| workflows: | |
| - "Client CI/CD" | |
| - "Genai CI/CD" | |
| - "Search CI/CD" | |
| - "Server CI/CD" | |
| - "Summary CI/CD" | |
| - "Contribution CI/CD" | |
| types: | |
| - completed | |
| branches: [main, finalize-aws] | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-latest | |
| # Only deploy if all builder workflows completed successfully | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Copy Docker Compose and Config Files | |
| uses: appleboy/scp-action@v0.1.7 | |
| with: | |
| host: ${{ secrets.EC2_PUBLIC_IP }} | |
| username: ${{ secrets.AWS_EC2_USER }} | |
| key: ${{ secrets.AWS_EC2_PRIVATE_KEY }} | |
| source: "./docker-compose.yml" | |
| target: /home/${{ secrets.AWS_EC2_USER }}/prompteus | |
| - name: Prepare Production Environment File | |
| uses: appleboy/ssh-action@v1.0.3 | |
| with: | |
| host: ${{ secrets.EC2_PUBLIC_IP }} | |
| username: ${{ secrets.AWS_EC2_USER }} | |
| key: ${{ secrets.AWS_EC2_PRIVATE_KEY }} | |
| script: | | |
| cd prompteus | |
| # Override security-sensitive values from GitHub secrets (only if available) | |
| if [ ! -z "${{ secrets.POSTGRES_PASSWORD }}" ]; then | |
| echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> .env | |
| fi | |
| if [ ! -z "${{ secrets.MEILI_MASTER_KEY }}" ]; then | |
| echo "MEILI_MASTER_KEY=${{ secrets.MEILI_MASTER_KEY }}" >> .env | |
| fi | |
| # Override URLs for production deployment using nip.io | |
| echo "CLIENT_HOST=client.${{ secrets.EC2_PUBLIC_IP }}.nip.io" >> .env | |
| echo "SERVER_HOST=api.${{ secrets.EC2_PUBLIC_IP }}.nip.io" >> .env | |
| echo "PUBLIC_API_URL=https://api.${{ secrets.EC2_PUBLIC_IP }}.nip.io" >> .env | |
| if [ ! -z "${{ secrets.OPENAI_API_KEY }}" ]; then | |
| echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> .env | |
| fi | |
| echo "Production environment file prepared successfully" | |
| - name: Deploy Prompteus Services | |
| uses: appleboy/ssh-action@v1.0.3 | |
| with: | |
| host: ${{ secrets.EC2_PUBLIC_IP }} | |
| username: ${{ secrets.AWS_EC2_USER }} | |
| key: ${{ secrets.AWS_EC2_PRIVATE_KEY }} | |
| script: | | |
| cd prompteus | |
| # Login to GitHub Container Registry | |
| echo "${{ secrets.GITHUB_TOKEN }}" | \ | |
| docker login ghcr.io -u "${{ github.actor }}" --password-stdin | |
| # Set image tags for main branch deployment | |
| export DOCKER_TAG=main | |
| # Show which images will be deployed | |
| echo "=== Images to be deployed ===" | |
| docker compose \ | |
| --env-file .env \ | |
| config --images | |
| # Pull latest images from the builder workflows | |
| docker compose \ | |
| --env-file .env \ | |
| pull | |
| # Deploy with the built images | |
| docker compose \ | |
| --env-file .env \ | |
| up -d \ | |
| --remove-orphans | |
| # Show running services | |
| docker compose ps | |
| # Show service logs (last 50 lines) | |
| echo "=== Recent service logs ===" | |
| docker compose logs --tail=50 | |
| - name: Wait for Services Health Check | |
| uses: appleboy/ssh-action@v1.0.3 | |
| with: | |
| host: ${{ secrets.EC2_PUBLIC_IP }} | |
| username: ${{ secrets.AWS_EC2_USER }} | |
| key: ${{ secrets.AWS_EC2_PRIVATE_KEY }} | |
| script: | | |
| cd prompteus | |
| echo "Waiting for services to become healthy..." | |
| # Wait up to 5 minutes for all services to be healthy | |
| timeout 300 bash -c ' | |
| while true; do | |
| if docker compose ps --format json | jq -r ".[] | select(.Health != \"\" and .Health != \"healthy\") | .Name" | grep -q .; then | |
| echo "Waiting for services to become healthy..." | |
| sleep 10 | |
| else | |
| echo "All services are healthy!" | |
| break | |
| fi | |
| done | |
| ' || { | |
| echo "Timeout waiting for services to become healthy" | |
| echo "Current service status:" | |
| docker compose ps | |
| docker compose logs --tail=100 | |
| exit 1 | |
| } | |
| echo "=== Final deployment status ===" | |
| docker compose ps | |
| echo "" | |
| echo "🚀 Deployment complete!" | |
| echo "Client URL: https://client.${{ secrets.EC2_PUBLIC_IP }}.nip.io" | |
| echo "API URL: https://api.${{ secrets.EC2_PUBLIC_IP }}.nip.io" |