Skip to content

#deploy-to-prod

#deploy-to-prod #66

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 << 'EOF'
# Stop and remove everything
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
# Setup environment variables
export DJANGO_ALLOWED_HOSTS="softwarefailures.com,$(ifconfig enX0 | grep 'inet ' | awk '{print $2}'),$(curl -s http://checkip.amazonaws.com)"
export REDIS_URL=redis://redis:6379/0
export CELERY_BROKER_URL="${REDIS_URL}"
export $(aws secretsmanager get-secret-value --secret-id prod/failure/postgres --region us-east-1 --query SecretString --output text | jq -r '. as $secret | "POSTGRES_HOST=\($secret | .host)\nPOSTGRES_PORT=5432\nPOSTGRES_DB=\($secret | .dbname)\nPOSTGRES_USER=\($secret | .username)\nPOSTGRES_PASSWORD=\($secret | .password)\nDATABASE_URL=postgres://\($secret | .username):\($secret | .password)@\($secret | .host):5432/\($secret | .dbname)"')
export OPENAI_API_KEY='${{ secrets.OPENAI_API_KEY }}'
export CHAINLIT_DB_URI="${DATABASE_URL}"
export CHAINLIT_DATABASE_URL="${DATABASE_URL/postgres:\/\//postgresql://}"
export DJANGO_SECRET_KEY='test'
export DJANGO_ADMIN_URL='admin/'
export CHAINLIT_AUTH_SECRET="0,uZEoYlN7auIrSf1F%7mm/6@n9:ubHDb36Z31L9vhY^2uzr4eiZGzQpMpK:%K,I"
export FAILBOT_REDIRECT_URL='${{ secrets.FAILBOT_REDIRECT_URL }}'
# Pull the latest image
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
# Start the container with the new image
docker network create failures-prod || true
docker volume create failures_chroma_data || true
docker run -d --name redis --network failures-prod -p 6379:6379 redis:alpine
docker run -d --name chroma --network failures-prod -p 8001:8001 -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 --network failures-prod -p 80:80 -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 FAILBOT_REDIRECT_URL -e OPENAI_API_KEY -e DJANGO_SETTINGS_MODULE=config.settings.production ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest /start
# Initial backfill only when collection is empty
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); col=c.get_or_create_collection(\"articlesVDB\"); print(col.count())"')
if [ "$CHROMA_COUNT" = "0" ]; then
docker exec django-prod python -m failures backfillchroma
fi
# Start Chainlit after backfill to avoid stale collection handles
docker run -d --name chainlit-prod --network failures-prod --cpus 1.0 --memory 2g --memory-swap 2g -w /app/failbot -p 8501:8501 -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_DB_URI="${CHAINLIT_DATABASE_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
# Clean up
docker image prune -f --all
docker network prune -f
EOF