30

I just started working with Docker and Kubernetes and I've been watching a lot of stacks, in which some people build nginx+php in a single image and some build an image with nginx and another one with php (mounting the same path and enclosing both containers in the same deployment in Kubernetes).

What would be the advantages of building two docker images instead of installing both nginx+php in the same one?

4 Answers 4

22

PHP with nginx is usually done using php-fpm which is a separate processus.

Keeping the core idea of docker of one process (see end of answer for more details on this point) per container this makes sense to have the nginx process and php-fpm process in separate containers.

As the communication between nginx and php-fpm arise through fastcgi the php-fpm container can also be on a separated host and this allows using a cluster of php-fpm containers behind nginx.

After the wall of comment here's a little more background, docker documentation have paragraph about the idea that a container should have only one concern.

The main idea of a linux container (lxc) is to run a process in an isolated namespace at the cpu and memory level, docker add on top of this an isolation at the filesystem level.
The advantage is that the compromission of a process within this namespace won't allow to read memory of other processes and as such should prevent other compromission on the host.

While talking about nginx and php-fpm, they work in pair but each has it's own concern, nginx will do the HTTP part, routing, headers validation, etc. and php-fpm will do the code interpretation and return the html part to nginx. While it's usual to have both together serving a single application that's not mandatory.

Depending on context it may be easier to have a container including the whole stack for an application, on a developer workstation for exemple. But ideally for production use, try to keep the fewer interaction inside the container, having separated processes in the same container with supervisord brings its share of problem in term of zombie process and log handling (exemple story here for illustration purpose only).

So finally I'll quote the docker page with some emphasis:

While “one process per container” is frequently a good rule of thumb, it is not a hard and fast rule. Use your best judgment to keep containers as clean and modular as possible.

There's no "silver bullet rule" which apply to everything, it's always a balance between the complexity within the container and the complexity orchestrating the containers themselves.

10
  • 4
    The core idea is actually "Each container should have only one concern", and "it is not necessarily true that there should be only one operating system process per container". docs.docker.com/engine/userguide/eng-image/… Commented Sep 20, 2017 at 10:41
  • I admit it's a shortcut to strike the idea, nginx is not a single monolithic process nor is php-fpm, but replace process by concern in my answer and it is still OK nginx does the routing, php-fpm does the interpretation
    – Tensibai
    Commented Sep 20, 2017 at 10:54
  • 3
    The answer is usually one service one port per container, not really one process. On the other hand, if you have multiple running processes in a container, you need to consider some init process, service management, restarts, independent logging, independent package dependencies, it gets a bit more complicated. And sometimes 1:1 mapping turns into 1:n mapping when scaling. Commented Sep 20, 2017 at 16:26
  • @Jiri playing devil's advocate: so a apache in front of a rails app using a postgres DB should go within the same container? That's just one service in an external point of view after all.
    – Tensibai
    Commented Sep 20, 2017 at 18:27
  • 1
    @JiriKlouda answer amended, I hope it's detailed enough to convey all the points raised in comments.
    – Tensibai
    Commented Sep 22, 2017 at 8:34
5

There is no meaningful benefit that outweighs having to manage two containers. As long as you have a 1:1 relationship between the processes and they serve a single purpose, put them in the same container.

8
  • Do you mean different images on the same container?
    – CarlosAS
    Commented Sep 20, 2017 at 13:06
  • How will you start nginx and php-fpm in the same container? Please add an example.
    – 030
    Commented Sep 20, 2017 at 14:49
  • 1
    @030 here an example
    – CarlosAS
    Commented Sep 20, 2017 at 15:24
  • 2
    @carlos Very valid exemple for dev purposes, I'd block this kind of things for production use (running supervisord within a container can turn in a footgun quite easily)
    – Tensibai
    Commented Sep 20, 2017 at 17:41
  • I disagree with that answer, with this reasoning a apache server with mod security talking to a tomcat talking to a postgresql server hosting only one app should fit within a single container.
    – Tensibai
    Commented Sep 20, 2017 at 18:30
4

Actually, one missing point here is the horizontal scalability. There's an article from Jamie Alquiza long time ago addressed this:

http://archive.is/pDzz0

In short, you scale your php-fpm horizontally for reaching higher performance. Scaling Nginx+php-fpm together does not bring you any benefit. I encourage you do some stress testing (e.g. Tsung, Gatling, etc.; please don't do Apache ab, that is a very old toy) yourself to verify what the article stated. I personally have several real world experiences proved the article is true in general.

But there're two drawback (maybe not for Kubernetes) for bare metal machines / VMs:

  1. How to configure Nginx dynamically discover php-fpm container changes? This is the easy part.
  2. How do we share the same volume / file systems after scaling? Nginx and php-fpm containers should read exactly the same content to reach consistency. This leaves you the least complicated puzzle piece (and the most fun part) to work on.

EDITED: Now it's almost halfway into the of year 2019. Old model, php-fpm+nginx in the same pod, has different usage. If you're familiar with service mesh, then nginx (or what so call Nginmesh) serves as a sidecar to handle east-west bound traffic. East-west bound traffic mostly used to authenticate among services, or other fancy functionalities, whereas pure "php-fpm only" containers could not do that alone.

-1

The advantage is : you can run multiple php-fpm containers in back-end, we call it PHP cluster, via number of ports. Example port 9000, 9001, 9002 .. and so on

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.