Skip to content

#deploy-to-prod

#deploy-to-prod #71

Workflow file for this run

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