What if you find yourself managing more than one Django-based web site at the same time in production? Do you have to deploy each one of them on a separate server? Or can you manage with just one, saving on hosting expenses? How will you go about the setup in this case, ensuring smooth running of these sites side by side.
For "real" production web site, with medium to heavy traffic, it is probably the best to have a separate server. Even more so, for busier sites you might very well have multiple servers in order to handle the workload. As they say, it is a good problem to have.
On the other hand, you might have a few Django-based sites, which experience very little load. In that case, running more than one of those on the same host makes economical sense. In this post I list some gotchas for such a setup.
Gunicorn + Nginx
If you use the common setup of nginx web server in front of gunicorn container, you need to remember a couple of things:
- Each gunicorn instance must have a unique binding address. If you use TCP/IP, then remember to choose a separate address for each instance (don't forget the port number). If you prefer Unix sockets, same logic applies - make sure the path is still unique. NB: looks like gunicorn won't tolerate more than one socket file in "/run/gunicorn" directory. To avoid trouble, locate your socket files outside "/run/" hierarchy.
- Ensure your nginx "upstream" sections have unique names as well, and are referred in other parts by these segregated names. Otherwise nothing will work
- Double check your nginx for any other name clashes
Caching makes Django web sites faster, when used correctly. If you use caching, you have two options in multi-site setup on the same box:
- Have different caches set up for different Django instances. This might defeat the purpose of having as light setup as possible, however
- Use the same cache (memcached, Redis etc) for all instances. This makes more sense in the scenario we are discussing. However, it is very important to segregate cache entries from different sites inside the single instance. The easiest way to do it is by using the "KEY_PREFIX" Django cache option, setting it to a unique (and short) value per Django installation
In general, I always advocate for as much automation in deployment as possible. Ideally you should have a deployment script, which sets up everything via a single command. It can use an existing automation solution, such as ansible, or you might want to roll your own, if you feel like it. But don't do things by hand, this is a sure way to disaster and maintenance headache!