Deploying Django + Postgres to Oracle Cloud
Project #125 of 10 in "Production-grade apps" progression
Updated: Oct 09, 2026
Learning plan
-
- Gunicorn
- Production settings / environment separation
- .env contracts: .exampe, .dev.example, .prod.example
- SECRET_KEY
- DEBUG
- ALLOWED_HOSTS
- CSRF_TRUSTED_ORIGINS
- DATABASE_URL / PostgreSQL settings
- Storage settings
- OAuth credentials
- Dev-only auto-reload
- Static files with collectstatic (make command)
- Media storage abstraction
- Local filesystem storage in dev / prod
- OCI Object Storage and Docker bind mount in production
-
- What's Docker?
- Docker images & containers
- .dockerignore file
- Dockerfile
- Compose.yml file: base, dev, prod
- Django service: web
- PostgreSQL service: db
- Persistent PostgreSQL volume
- .env
- Docker commands: ps, images, run, start, stop, restart, pull, rm
- Make commands: migrate, collectstatic
- Shell commands inside containers
-
- GitHub Actions workflow: CI.yml file
- Django tests: seeding, healthcheck, unit tests
- Act for local workflow tests
- Local db, lint and type checks on Railway deploys
-
- OCI setup: creating instance and subnet
- Security lists / network security rules (ingress, reserved IP)
- SSH into VM: public and private keys, git aliases
- Installing Docker: etc folder, GPG keys, group permission
- Secure copy files over SSH: scp, .env. compose.yml
- Prepare host directories: staticfiles, media
-
- DNS type A record
- Fighting firewall: iptables, netfilter-persistent
- Configuring Nginx: .conf file
- Installing TLS certificates uisng certbot
- Google sign in: update OAuth callback URLs
- Django settings: secure cookies, ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, HSTS
- Verify HTTPS
-
- Build Docker image
- Tag Docker image
- Push image to container registry
- Configure GitHub secrets
- Configure SSH authentication
- Create server-side deploy.sh
- SSH into OCI VM
- Pull new image
- docker compose up -d
- Run migrations
- Run collectstatic
- Run health check
- Fail deployment if health check fails
-
- Create Object Storage bucket
- Configure bucket/access policy
- Configure boto3
- Configure production bucket credentials
- Upload media
- Verify Django can read/write media
- Verify media is not stored inside the Docker container
-
- Create production .env
- Pull/build application image
- Start Docker Compose
- Run migrations
- Run collectstatic
- Check Django logs
- Check PostgreSQL
- Check media storage
- Restart containers and verify persistence
-
- Tag images with versions
- Keep previous image available
- Know how to deploy previous image
- Test rollback manually