#deploy-to-prod #71
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 Docker to EC2 | |
| on: | |
| push: | |
| branches: | |
| - main # This will trigger on any push to the main branch | |
| jobs: | |
| build_and_push: | |
| if: github.event.head_commit.message == '#deploy-to-prod' # Check for commit message | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v2 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v2 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: us-east-1 | |
| - name: Build and Push Docker image | |
| run: | | |
| docker compose -f production.yml build django | |
| docker tag failures_production_django:latest ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest | |
| aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_REPOSITORY_URL }} | |
| docker push ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest | |
| deploy_to_ec2: | |
| if: github.event.head_commit.message == '#deploy-to-prod' # Check for commit message | |
| needs: build_and_push | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Start SSH agent and add EC2 private key | |
| run: | | |
| echo "${{ secrets.EC2_PRIVATE_KEY }}" > ec2-key.pem | |
| chmod 600 ec2-key.pem | |
| eval "$(ssh-agent -s)" | |
| ssh-add ec2-key.pem | |
| - name: SSH into EC2 and restart Docker | |
| run: | | |
| ssh -o StrictHostKeyChecking=no -i ec2-key.pem ec2-user@ec2-${{ secrets.AWS_EC2_PUBLIC_IP_WITH_DASHES }}.compute-1.amazonaws.com <<'REMOTE' | |
| set -euo pipefail | |
| docker ps -aq | xargs -r docker stop | |
| docker ps -aq | xargs -r docker rm | |
| docker network rm failures-prod || true | |
| export DJANGO_ALLOWED_HOSTS="softwarefailures.com,ec2-${{ secrets.AWS_EC2_PUBLIC_IP_WITH_DASHES }}.compute-1.amazonaws.com,localhost,127.0.0.1" | |
| export REDIS_URL="redis://redis:6379/0" | |
| export CELERY_BROKER_URL="${REDIS_URL}" | |
| export DJANGO_SECRET_KEY='${{ secrets.DJANGO_SECRET_KEY }}' | |
| export DJANGO_ADMIN_URL='${{ secrets.DJANGO_ADMIN_URL }}' | |
| export OPENAI_API_KEY='${{ secrets.OPENAI_API_KEY }}' | |
| export CHAINLIT_AUTH_SECRET='${{ secrets.CHAINLIT_AUTH_SECRET }}' | |
| export $(aws secretsmanager get-secret-value --secret-id prod/failure/postgres --region us-east-1 --query SecretString --output text | jq -r '. as $s | "POSTGRES_HOST=\($s.host)\nPOSTGRES_PORT=5432\nPOSTGRES_DB=\($s.dbname)\nPOSTGRES_USER=\($s.username)\nPOSTGRES_PASSWORD=\($s.password)\nDATABASE_URL=postgres://\($s.username):\($s.password)@\($s.host):5432/\($s.dbname)"') | |
| export CHAINLIT_DATABASE_URL="${DATABASE_URL/postgres:\/\//postgresql://}" | |
| aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_REPOSITORY_URL }} | |
| docker pull ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest | |
| printf '%s\n' \ | |
| 'server {' \ | |
| ' listen 80;' \ | |
| ' server_name _;' \ | |
| '' \ | |
| ' location = /failbot { return 301 /failbot/; }' \ | |
| ' location /failbot/ {' \ | |
| ' proxy_pass http://chainlit-prod:8501;' \ | |
| ' proxy_http_version 1.1;' \ | |
| ' proxy_set_header Host $host;' \ | |
| ' proxy_set_header X-Real-IP $remote_addr;' \ | |
| ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' \ | |
| ' proxy_set_header X-Forwarded-Proto $scheme;' \ | |
| ' proxy_set_header Upgrade $http_upgrade;' \ | |
| ' proxy_set_header Connection "upgrade";' \ | |
| ' proxy_read_timeout 600s;' \ | |
| ' }' \ | |
| '' \ | |
| ' location / {' \ | |
| ' proxy_pass http://django-prod:80;' \ | |
| ' proxy_http_version 1.1;' \ | |
| ' proxy_set_header Host $host;' \ | |
| ' proxy_set_header X-Real-IP $remote_addr;' \ | |
| ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' \ | |
| ' proxy_set_header X-Forwarded-Proto $scheme;' \ | |
| ' }' \ | |
| '}' > /tmp/failures-nginx.conf | |
| docker network create failures-prod | |
| docker volume create failures_chroma_data | |
| docker run -d --name redis --restart unless-stopped --network failures-prod redis:alpine | |
| docker run -d --name chroma --restart unless-stopped --network failures-prod -v failures_chroma_data:/var/lib/chroma/data ghcr.io/chroma-core/chroma:1.0.9 run --host 0.0.0.0 --port 8001 --path /var/lib/chroma/data | |
| docker run -d --name django-prod --restart unless-stopped --network failures-prod \ | |
| -e POSTGRES_HOST -e POSTGRES_PORT -e POSTGRES_DB -e POSTGRES_USER -e POSTGRES_PASSWORD -e DATABASE_URL \ | |
| -e REDIS_URL -e CELERY_BROKER_URL -e DJANGO_ALLOWED_HOSTS -e DJANGO_SECRET_KEY -e DJANGO_ADMIN_URL -e OPENAI_API_KEY \ | |
| -e DJANGO_SETTINGS_MODULE=config.settings.production \ | |
| ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest /start | |
| sleep 10 | |
| CHROMA_COUNT=$(docker exec django-prod /bin/sh -lc 'python -c "import sys,pysqlite3; sys.modules[\"sqlite3\"]=sys.modules.pop(\"pysqlite3\"); import chromadb; c=chromadb.HttpClient(host=\"chroma\", port=8001); print(c.get_or_create_collection(\"articlesVDB\").count())"') | |
| if [ "${CHROMA_COUNT}" = "0" ]; then | |
| docker exec django-prod python -m failures backfillchroma | |
| fi | |
| docker run -d --name chainlit-prod --restart unless-stopped --network failures-prod --cpus 1.0 --memory 2g --memory-swap 2g \ | |
| -w /app/failbot \ | |
| -e POSTGRES_HOST -e POSTGRES_PORT -e POSTGRES_DB -e POSTGRES_USER -e POSTGRES_PASSWORD \ | |
| -e DATABASE_URL="${CHAINLIT_DATABASE_URL}" -e REDIS_URL -e CELERY_BROKER_URL \ | |
| -e DJANGO_SECRET_KEY -e DJANGO_ADMIN_URL -e CHAINLIT_AUTH_SECRET -e OPENAI_API_KEY \ | |
| -e DJANGO_SETTINGS_MODULE=config.settings.production -e PYTHONPATH=/app \ | |
| ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest chainlit run failbotUI.py --port 8501 --host 0.0.0.0 --root-path /failbot | |
| docker run -d --name nginx-proxy --restart unless-stopped --network failures-prod -p 80:80 -v /tmp/failures-nginx.conf:/etc/nginx/conf.d/default.conf:ro nginx:alpine | |
| docker image prune -f | |
| REMOTE |