In this article you will get to know:

  1. Why you shouldn’t host your application with the same settings used for development?
  2. What is the difference between development and production environments and settings?
  3. How to keep your production settings safely and conveniently?

A bit proficiency in git version control system will let you understand why some methods of config management are more easy to maintain.

Introduction

When you start your fresh new Django project with django-admin startproject mysite, you will see it comes with settings file (named settings.py). If you haven’t deployed an application to the production stage, you may presume that this is to be the only configuration file for your project. This way, hopefully, you could use it after successful development when you finally manage to run your work on a dedicated server.

It’s not a good idea, though. The reason is, when you push your application to the external server, you make it available for everyone. Not only your visitors, but also potential black hats. Who the hell are black hats? Well, they are commonly said hackers, although a hacker does not necessarily mean a computer-literate guy who does nasty things. Anyway, evil people and their scripts may try to breach your application in order to steal data like passwords, credit card numbers or e-mail addresses. They can also redirect people from your website to their own, for example, some advertisements or phishing of your own app.

One of possible ways to harm your website is abusement of development configuration run in a production environment.

Difference between development and production configuration rules

The first thing to mention is that, the starting Django configuration is only for development purposes. This makes a lot of things easier in order to help you build your site. The examples, to name a few, are:

  • very descriptive and detailed error information (DEBUG = True setting),
  • SECRET_KEY stored directly in the configuration file,
  • SSL not turned on.

There are many many more settings not safe for the production environment. You can read about them all in the Django documentation. If you are interested, you may take a look at the deployment checklist. This time, let me tell you why you shouldn’t deploy your project with mentioned above settings:

  1. DEBUG flag set to True will provide full traceback of any error. If somebody starts making them by purpose (e.g. by providing incorrect requests or wrong data to the forms), uncaught exceptions will reveal your code fragments to the attacker. First of all, everybody will know you used Django to set your site. It’s a heavy follow up to look for further weak sides.
  2. If you use a version control system like git and store your project somewhere externally (like on Github), everybody with access to the repository can get your SECRET_KEY. It’s a bit like sharing your passwords, because it’s used to encrypt sensitive data. For example, Django uses SECRET_KEY to hash sessions. If somebody gets it, they may use it to sign their own session data and authorize without password.
  3. Without SSL, your Django project uses old HTTP protocol for data transfer. That means, all the information between you and the server is transferred unencrypted, as a plain text. If somebody intercepts this data, they can read it without any problem. This includes information like login and passwords.

You may have noticed, that although it all looks like seriously important when you host your project, it’s not necessary for development at all. On one hand, you don’t need to protect your dummy data when you grow your app. On the other hand, it’s of the highest priority to protect data of your users. That’s why we consider two configuration settings for both development and deployment case. Let’s see how to maintain them.

How to set different configurations for development and production?

Before we start, let’s remind commonly used shortcuts – dev for development and prod for production. Suppose we start with existing configuration – config.py. What we’re going to do is to duplicate this file. So you should have your original file and copy. Let’s change their names to settings_dev.py and settings_prod.py. Now we can change some of configuration settings in settings_prod.py to turn off development conveniences in order to make your application more secure. To keep things simple, but still make noticeable change, set DEBUG flag to False.

You may try how your app works now. When you run your development server with python manage.py runserver, probably you will get an error:
ModuleNotFoundError: No module named 'mysite.settings'
That’s because we have no longer file called settings.py. We have duplicated it and set another names for both. We have two dedicated configuration files – now let’s see how to switch between them and hopefully restore your application to work.

Configuration switch

Find manage.py file you use to manage your Django app. Inside the file, you can find the line which is responsible for loading settings:

os.environ.setdefault('DJANGO_SETTINGS_MODULE','mysite.settings')

As you see, you can’t run your app now, because you have dedicated settings files (with _dev and _prod suffixes), but your app looks for just settings.py. There are few options for what you can do:

  1. Duplicate one of your dedicated settings files and change it’s name to settings.py. This way let’s you better manage config files with your version control system (VCS). If you add settings.py file to .gitignore, it will not track mentioned file. Consequently, no matter if you keep this file copied from settings_dev.py locally or copied from settings_prod.py on the hosting, your VCS won’t notify you that you changed something in your project files. Consequently, you will have your git repository clean in both prod and dev environment although your settings may be totally different and that’s the point.
  2. Change mysite.settings into either mysite.settings_dev or mysite.settings_prod, that is mysite. (mind the dot) plus the name of config file. This solution is more easy to implement. You need to be careful though, because now git will notice that you modified project file. Watch out to not commit this change, because if you do this and synchronize, you may one day run your application with settings you didn’t mean to use.
  3. Use environment variables. It’s very commonly used solution especially when dockerizing your application. However, to efficiently use those this method, you need to know how to set these variables in the systems you use. Although very interesting, this topic is beyond the scope of the article. If you want to dive in yourself, let me give you a hint. What you may do is just set the environment variable DJANGO_SETTINGS_MODULE to either mysite.settings_dev or mysite.settings_prod and then you won’t need to manipulate your files.

Try to enable production config. If you run server and put random things in your app url you won’t get any descriptive information any more, just 404 Not Found, or 500 Internal Server Error. It’s better to show that instead of your app’s guts to the users, right?

What to do next?

Although you now have working configuration split, there are many more improvements you can do to raise security of your app on production environment. First thing you would do is to take your secret key away from settings_prod.py. There are many ways how to do it. You can Google easily. The best thing is no matter how you implement that, it’s not going to affect your development environment, because both settings files follow their own path. I hope you see now, coding with conveniences is possible with deploying your app safely as well.

1 Comment
  1. Very useful, thank you!

Leave a Reply

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.