This repo is a blueprint for Django + Postgres + Gunicorn + nginx + Docker web projects to be deployed on a VPS.
The backend
directory is the output of django-admin startproject
with some additions:
- Initialized
core
app. - Basic dependencies such as
psycopg2
andgunicorn
. - Settings splitted for local and production environments and controlled by environment variables.
- Initial HTML templates and SCSS pipeline. JS/SCSS files are processed (transpiled, bundled) by
django_compressor
and served withwhitenoise
. - Common utilities.
There is also a bunch of files for local development and deployment with Docker.
All local development is done with docker compose
so it's easy to set up and doesn't require to install anything locally. The combination -f docker-compose-base.yml -f docker-compose-dev.yml
defines a postgres
service and a web
service that runs Django dev server with the source code mounted as a volume.
The combination -f docker-compose-base.yml -f docker-compose-prod.yml
defines a postgres
service, an nginx
service running nginx-le, and a web
service that runs Gunicorn.
-
Clone this repo:
git clone https://github.com/r4victor/my_django_docker_project_template new_project && cd new_project
-
Init a new git folder:
rm -rf .git && git init
-
Create an
.env
file from the template:mv backend/.env-template backend/.env
-
Rename
my_django_docker_project_template
to your project name indocker-compose-base.yml
.
That's it! You have a new project set up!
To start a Django dev server, run:
docker compose -f docker-compose-base.yml -f docker-compose-dev.yml up
Other Django commands can be run in the same way:
docker compose -f docker-compose-base.yml -f docker-compose-dev.yml run --rm web ./manage.py migrate
If you need to run a production setup with nginx and Gunicorn locally, then run
docker compose -f docker-compose-base.yml -f docker-compose-prod.yml up --build
Before that, ensure that your set DJANGO_SETTINGS_MODULE=backend.settings.prod
in .env
and generate a local https cert by running ./scripts/generate_local_cert.sh
.
To deploy, you manually ssh into your server, pull the project and run docker compose
just like locally:
docker compose -f docker-compose-base.yml -f docker-compose-prod.yml up --build
The only difference is that you need to change env variables to match your domain and set LETSENCRYPT=true
to let nginx issue a certificate for your.
- Zero downtime deployments. One option would be to make nginx buffer requests while we run migrations and restart the app.
- Set up automatic deployments on tag releases.
- We run
manage.py
in Dockerfile to bake static files into the image. To avoid passing dummy env vars there, Django prod settings allows all env vars to be optional. I don't like this since we may want to fail on app start if some env vars are not provided. Another solution would be to make a separate settings file for running in Dockerfile.