This guide explains how to set up a CI/CD pipeline to automatically deploy a Dockerized FastAPI app (or any containerized app) to an EC2 instance using GitHub Actions.
Prerequisites
- A running EC2 Ubuntu instance
- Your app is containerized with Docker Compose
- SSH access to EC2 (user:
ubuntuor similar) - Your app code is hosted on GitHub
- Optional: DNS domain and SSL setup via Nginx + Letβs Encrypt
Step 1: Generate an SSH Deploy Key
Create a new SSH key pair (locally or in CI):
ssh-keygen -t ed25519 -C "github-deploy-key"
Step 2: Add Public Key to EC2
- SSH into EC2:
ssh ubuntu@<your-ec2-ip>
- Open the authorized_keys file:
nano ~/.ssh/authorized_keys
- Paste in the contents of
id_ed25519.pub. - Set proper permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
You can have multiple lines in authorized_keys.
Step 3: Allow Docker Without sudo
On EC2:
sudo usermod -aG docker ubuntu
Then log out and log back in (or reboot):
exit
Reconnect and test:
docker ps
Step 4: Add GitHub Secrets
Go to your GitHub repo β Settings β Secrets and variables β Actions, and add:
| Name | Description |
|---|---|
EC2_HOST |
EC2 IP or DNS |
EC2_USER |
SSH username (e.g., ubuntu) |
EC2_SSH_KEY |
Content of your private key id_ed25519 |
Step 5: Create GitHub Actions Workflow
Create a file at .github/workflows/deploy.yml:
name: Deploy to EC2
on:
push:
branches: [main] # Update if using another branch
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: SSH & Deploy
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /home/ubuntu/translation-worker-api
git pull origin main
docker-compose down
docker-compose up -d --build
Step 6: Push to GitHub to Deploy
git add .
git commit -m "Deploying via GitHub Actions"
git push origin main
Check GitHub β Actions tab to see the workflow progress.
Example Directory Structure
translation-worker-api/
βββ .github/
β βββ workflows/
β βββ deploy.yml
βββ docker-compose.yml
βββ app/
β βββ main.py
βββ β¦
Optional Enhancements
- Add
.envfile support for Docker Compose - Configure Nginx + Certbot for subdomains and SSL
- Use GitHub environments (staging, production)
- Add deploy notifications (e.g., Slack, Discord)
- Write a
deploy.shscript with error handling