<p>I'm setting up a Flask/uswgi web server. I'm still wondering about the micro-service architecture:</p>

<p>Should I put both nginx and Flask with uwsgi in one container or shall I put them in two different containers and link them?</p>

<p>I intend to run these services in a Kubernetes cluster.</p>

<p>Thanks</p>

<p><strong>Short answer:</strong></p>

<p>I would deploy the nginx and uwsgi/flask application as separate containers. This gives you a more flexible architecture that allows you to link more microservices containers to the nginx instance, as your requirements for more services grow.</p>

<p><strong>Explanation:</strong></p>

<p>With docker the usual strategy is to split the nginx service and the uwsgi/flask service into two separate containers. You can then link both of them using links.  This is a common architecture philosophy in the docker world. Tools like docker-compose simplify the management of running multiple containers and forming links between them. The following docker-compose configuration file shows an example of this:</p>

<pre><code>version: '2'
services:

  app:
    image: flask_app:latest
    volumes:
        - /etc/app.cfg:/etc/app.cfg:ro
    expose:
        - "8090"

  http_proxy:
    image: "nginx:stable"
    expose:
        - "80"
    ports:
        - "80:8090"
    volumes:
        - /etc/app_nginx/conf.d/:/etc/nginx/conf.d/:ro
</code></pre>

<p>This means that if you want to add more application containers, you can attach them to the same ngnix proxy easily by linking them. Furthermore, if you want to upgrade one part of your infrastructure, say upgrade nginx, or shift from apache to nginx, you are only re-building the relevant container, and leaving all the rest in the place.</p>

<p>If you were to add both services to a single container (e.g. by launching supervisord process from the Dockerfile ENTRYPOINT), that would allow you to opt more easily for communication between the nginx and uwsgi process using the socks file, rather than by IP, but I don't think this in it self is a strong enough reason to put both in the same container.</p>

<p>Also, consider if eventually you end up running twenty microservices and each is running each own nginx instance, that means you now have twenty sets of nginx (access.log/error.log) logs to track across twenty containers.</p>

<p>If you are employing a "microservices" architecture, that implies that with time you will be adding more and more containers. In such an ecosystem, running nginx as a separate docker process and linking the microservices to it makes it easier to grow in line with your expanding requirements.</p>

<p>Furthermore, certain tasks only need to be done once. For example, SSL termination can be done at the nginx container, with it configured with the appropriate SSL certificates once, irrespective of how many microservices are being attached to it, if the nginx service is running on its own container.</p>

<p><strong>A note about service discovery</strong> </p>

<p>If the containers are running in the same host then linking all the containers is easy. If the containers are running over multiple hosts, using Kubernetes or Docker swarm, then things may become a bit more complicated, as you (or your cluster framework) needs to be able to link your DNS address to your nginx instance, and the docker containers need to be able to 'find' each other - this adds a bit of conceptual overhead. Kubernetes helps you achieve this by grouping containers into pods, defining services, etc.</p>
