I am using Django and deploy my stack with Ansible. Finally, I am using Fabric to deploy my Django project pulling my code from GitHub.
My question: What is the best practice to deal with private settings in Django's settings.py file, such as passwords for email or S3? Currently, I file-transfer a settings_production.py from my machine to the production machine at the end of my deployment script before restarting the application server. This file contains the settings that I am not putting into settings.py as part of the repo.
At the end of my settings.py I am adding something like
try:
from settings_production import *
except ImportError:
pass
Are there better ways to do this?
ALLOWED_HOSTS. A list of strings representing the host/domain names that this Django site can serve. This is a security measure to prevent HTTP Host header attacks, which are possible even under many seemingly-safe web server configurations.
If you're new to deploying Django and/or Python, we'd recommend you try mod_wsgi first. In most cases it'll be the easiest, fastest, and most stable deployment choice.
By default, the configuration uses SQLite. If you're new to databases, or you're just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won't need to install anything else to support your database.
The answer is: http://12factor.net/config.
You should manage code-related differences between environments via different settings modules. An example of this would be adding debug_toolbar
to INSTALLED_APPS
locally, while removing it in production. To handle this aspect, rather than using the old try: import except ImportError: ...
idiom and keeping an out-of-version-control local_settings.py
on your local machine, you should instead keep all of your settings modules in version control, including your local settings. Then, in wsgi.py
and manage.py
, use os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.conf.local')
to default your project to use local settings. In dev / production, you add an environment variable to use the respective settings module (e.g., DJANGO_SETTINGS_MODULE=myproject.conf.dev
).
When you use 12 Factor, it's no longer necessary to keep certain settings modules out of version control, because, with 12 Factor, you don't put any passwords or sensitive settings directly into a settings module. You instead keep them in the environment and access them like this:
# Inside of a settings module
FOO_PASSWORD = os.environ['FOO_PASSWORD']
In environments like Heroku, this setup is simple, because you can enter config vars for your app via the web interface.
I recommend pretty much all of 12 Factor's principles, esp things like disposability, logs, and config.
If you'd like to maintain an extra settings module, out of version control, to avoid having to use environment variables during local dev (I don't blame you), you can still follow the above principles and also add, to the bottom of the local settings module that is in version control, try: from some_other_local import * except: pass
. This will allow you to set only the necessary override settings locally, while still keeping the rest of your local settings (e.g., local database, relative static / media file paths, installed apps, etc.) in version control, which gives you the best of both worlds.
I think a good example of how to do it is jcalazan/ansible-django-stack which besides the code includes a few links, in particular this one about How to deploy encrypted copies of your SSL keys and other files with Ansible and OpenSSL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With