Back to .md Directory

Production deployment guide (Docker + Postgres + GitHub CD)

Guides a developer through deploying a Django app with Docker, Postgres, and a GitHub CD pipeline on a low-cost VM.

May 2, 2026
0 downloads
0 views
ai rag workflow
View source

What this file does

Guides a developer through deploying a Django app with Docker, Postgres, and a GitHub CD pipeline on a low-cost VM.

When to use it

  • You need a step-by-step production deployment for a small-traffic Django project
  • You want to set up automated deploys from GitHub Actions on push to main
  • You are provisioning an always-free cloud VM and need a repeatable setup
  • You need a simple database backup cron job and rollback procedure

Assumes this stack

DockerPostgreSQLDjangoGitHub ActionsNginx or CaddyLet's Encrypt

Production deployment guide (Docker + Postgres + GitHub CD)

This guide gets this project live with a containerized app and database, optimized for very small traffic.

1) One-time prep in this repo

  1. Copy environment template:
    cp .env.example .env
    
  2. Edit .env with real values:
    • Strong SECRET_KEY
    • Real domain(s) in ALLOWED_HOSTS
    • HTTPS URLs in CSRF_TRUSTED_ORIGINS
    • Strong POSTGRES_PASSWORD

2) Provision a low-cost server

For lowest cost, use an always-free VM (for example, Oracle Cloud Always Free ARM).

Install on the VM:

sudo apt update
sudo apt install -y git docker.io docker-compose-v2
sudo usermod -aG docker $USER

Log out/in so docker group is applied.

3) Deploy app manually (first deploy)

sudo mkdir -p /opt/cantina
sudo chown -R $USER:$USER /opt/cantina
cd /opt/cantina
git clone <your-github-repo-url> .
cp .env.example .env
nano .env

docker compose build --pull
docker compose up -d

Check status:

docker compose ps
docker compose logs -f web

Create admin user:

docker compose exec web python manage.py createsuperuser

4) Put HTTPS in front (production)

Recommended simple setup:

  • Put Nginx/Caddy on the VM as reverse proxy from 443 -> localhost:8000.
  • Use Let's Encrypt certificates.

At minimum, keep port 8000 closed publicly and expose only 80/443.

5) Set up GitHub CD pipeline

This repo includes .github/workflows/deploy.yml, which deploys on each push to main.

In GitHub repo settings, add these Actions secrets:

  • SSH_HOST (VM public IP or hostname)
  • SSH_USER (VM user)
  • SSH_PRIVATE_KEY (private key matching VM authorized key)
  • SSH_PORT (usually 22)

On the VM, ensure repo is in /opt/cantina and branch is main.

6) Database backup (must-have)

Use cron on VM:

crontab -e

Example daily backup at 02:30:

30 2 * * * docker exec cantina-db pg_dump -U cantina cantina | gzip > /opt/cantina/backups/cantina_$(date +\%F).sql.gz

Also add a retention cleanup job and sync backups to external storage when possible.

7) Health checks and operations

  • App logs: docker compose logs -f web
  • DB logs: docker compose logs -f db
  • Restart after config change: docker compose up -d --build
  • Migrations run automatically on container startup via entrypoint.

8) Rollback approach

If a deploy breaks:

  1. SSH into VM
  2. cd /opt/cantina
  3. git checkout <last-good-commit>
  4. docker compose up -d --build

For safer rollbacks, deploy from Git tags/releases.

What's inside

8 numbered sections covering VM setup, manual deploy, HTTPS, CD pipeline, backups, health checks, and rollback.

Change this for your project

  • Replace cantina in paths like /opt/cantina and container name cantina-db with your project name
  • Replace <your-github-repo-url> with your actual repository URL
  • Replace joaovitortc/cantina in the deploy workflow reference with your repo
  • Replace cantina in pg_dump -U cantina cantina with your database name and user

Where it goes

Keep it in your repository where the agent or team that needs it will read it.

Worth borrowing

  • Using a cron job to dump the database and gzip it to a backup directory
  • Rolling back by checking out a previous Git commit and rebuilding containers

Related Documents