Django#
Configuration#
We share the same configuration structure for almost every possible environment.
We use:
django-split-settingsto organizedjangosettings into multiple files and directories.envfiles to store secret configurationpython-decoupleto load.envfiles intodjango
Components#
If you have some specific components like celery or mailgun installed,
they could be configured in separate files.
Just create a new file in server/settings/components/.
Then add it into server/settings/__init__.py.
Environments#
To run django on different environments just
specify DJANGO_ENV environment variable.
It must have the same name as one of the files
from server/settings/environments/.
Then, values from this file will override other settings.
Local settings#
If you need some specific local configuration tweaks,
you can create file server/settings/environments/local.py.template
to server/settings/environments/local.py.
It will be loaded into your settings automatically if exists.
cp server/settings/environments/local.py.template server/settings/environments/local.py
See local.py.template version for the reference.
Secret settings#
We share the same mechanism for secret settings for all our tools.
We use .env files for django, postgres, docker, etc.
Initially, you will need to copy file
config/.env.template to config/.env:
cp config/.env.template config/.env
When adding any new secret django settings you will need to:
Add new key and value to
config/.envAdd new key without value to
config/.env.template, add a comment on how to get this value for other usersAdd new variable inside
djangosettingsUse
python-decoupleto load thisenvvariable like so:MY_SECRET = config('MY_SECRET')
Secret settings in production#
We do not store our secret settings inside our source code.
All sensible settings are stored in config/.env file,
which is not tracked by the version control.
So, how do we store secrets? We store them as secret environment variables
in Gitlab CI.
Then we use dump-env
to dump variables from both environment and .env file template.
Then, this file is copied inside docker image and when
this image is built - everything is ready for production.
Here’s an example:
We add a
SECRET_DJANGO_SECRET_KEYvariable to Gitlab CI secret variablesThen
dump-envdumpsSECRET_DJANGO_SECRET_KEYasDJANGO_SECRET_KEYand writes it toconfig/.envfileThen it is loaded by
djangoinside the settings:SECRET_KEY = config('DJANGO_SECRET_KEY')
However, there are different options to store secret settings:
Depending on a project we use different tools.
With dump-env being the default and the simplest one.
Extensions#
We use different django extensions that make your life easier.
Here’s a full list of the extensions for both development and production:
django-modern-rest - build modern type-safe APIs
django-split-settings - organize
djangosettings into multiple files and directories. Easily override and modify settings. Use wildcards in settings file paths and mark settings files as optionaldjango-axes - keep track of failed login attempts in
djangopowered sitesdjango-csp - Content Security Policy for
djangodjango-referrer-policy - middleware implementing the Referrer-Policy
django-health-check - checks for various conditions and provides reports when anomalous behavior is detected
django-add-default-value - this django Migration Operation can be used to transfer a Fields default value to the database schema
django-deprecate-fields - this package allows deprecating model fields and allows removing them in a backwards compatible manner
django-migration-linter - detect backward incompatible migrations for your django project
django-safe-migrations - detect unsafe Django migrations and warns about operations that could cause downtime, lock tables, or cause data loss in production environments.
zero-downtime-migrations - apply
djangomigrations on PostgreSql without long locks on tables
Development only extensions:
django-debug-toolbar - a configurable set of panels that display various debug information about the current request/response
django-querycount - middleware that prints the number of DB queries to the runserver console
django-zeal - auto-detecting the n+1 queries problem in
djangodjango-drifter - provide custom
djangomanagement commands to manage database migrations