18

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?

19

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.

  • 3
    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/… – user2640621 Sep 20 '17 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 Sep 20 '17 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. – Jiri Klouda Sep 20 '17 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 Sep 20 '17 at 18:27
  • 1
    @JiriKlouda answer amended, I hope it's detailed enough to convey all the points raised in comments. – Tensibai Sep 22 '17 at 8:34
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 exact the same content to reach consistency. This leaves you the least puzzle part (and most fun part) to work on.

EDITED: Now it's almost half 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 could not do that along.

3

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.

  • Do you mean different images on the same container? – CarlosAS Sep 20 '17 at 13:06
  • How will you start nginx and php-fpm in the same container? Please add an example. – 030 Sep 20 '17 at 14:49
  • 1
    @030 here an example – CarlosAS Sep 20 '17 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 Sep 20 '17 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 Sep 20 '17 at 18:30
-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, privacy policy and cookie policy

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