13

We are looking to move our current Nginx/Gunicorn/Django stack into Docker, and deploy it for high availability using Docker Swarm. One of the decisions we have been struggling with is whether or not to place Nginx in the same container as Gunicorn/Django. Here are the scenarios and how we view them:

Scenario 1: Place Nginx in the app's container. This goes against the "each service has its own container" methodology, but it allows Nginx to communicate with Gunicorn directly through a unix socket instead of a port. This obviously isn't huge but it's worth mentioning. The main advantages are listed below. A potential disadvantage here is having extra overhead from too many Nginx instances (please weigh in on this).

Scenario 2: Place Nginx in its own container. Though this follows the aforementioned methodology, it seems more flawed. In a Docker Swarm scenario, the distribution of Nginx and App containers will likely not be uniform. Some nodes may end up with more Nginx containers, while others have more app containers (and possibly even 0 Nginx containers). This means that Nginx would end up reverse-proxying an app container on a different host entirely.

Now I'm sure Docker Swarm supports special configurations that say at least one Nginx container must be running on each node, but this strikes me as an anti-pattern. Even in that instance, is it worth the effort over Scenario 1?

Leah Sapan
  • 3,621
  • 7
  • 33
  • 57
  • Is the purpose of your nginx instance only to proxy pass to gunicorn ? If so, in contrary to the opinion of @vanadium23, it clearly seems to me that having n nginx instances is an antipattern where only one instance (or 3, for HA purpose) would be enough. Note: I'm not familiar with a Gunicorn/Django stack, but I've been managing/running a full microservices stack in production relying on docker – MagicMicky Nov 30 '16 at 09:18
  • @MagicMicky you bring up an interesting point. Do you configure swarm to run exactly 1 instance of Nginx on each worker? – Leah Sapan Feb 14 '17 at 11:06
  • We actually have 2 dedicated front servers that run Nginx and proxypass to our swarm manager (which then forwards to the application needed). It might be a little bit of an overhead, but it is really easier to manage our nginx on their own servers. If you want to stick with docker swarms, I would start Nginx in 3 instances, and use the [Docker Swarm load balancer](https://docs.docker.com/engine/swarm/key-concepts/#/load-balancing) to load balance between the difference instances. – MagicMicky Feb 15 '17 at 11:40

1 Answers1

9

Based on production experience, it's better to counterpart rule from docker docs one container for one process. You're shipping a (micro-)service with docker image, and if it's required to have nginx in it, you include it.

So basically for django app there are:

  1. nginx (e.g.: for static files)
  2. gunicorn or uwsgi
  3. django code itself

Don't see any perfomance issue on adding nginx to container, but little note on docker image size. On ubuntu:16.04/debian:jessie by adding nginx-full you increase your image size for around ~100mb. (some overhead on first pulling image).

So it's not controversal to second scenario, because you can also add nginx behind your docker image for balancing purpose (or proxy_pass managing).

vanadium23
  • 3,516
  • 15
  • 27
  • would you still give the same advice today (01-2022)? and, how would nginx and django run in the same container? there is only one `CMD` to be run, right? one way could be uwsgi emporer mode? – benzkji Jan 20 '22 at 14:26
  • aahhh. nginx runs via systemd/whatever, gunicorn launched via Dockerfiles's `CMD` - correct me if wrong ;-) – benzkji Jan 20 '22 at 14:29