In many blog posts, and general opinion, there is a saying that goes "one process per container".

Why does this rule exist? Why not run ntp, nginx, uwsgi and more processes in a single container that needs to have all processes to work?

blog posts mentioning this rule:

  • Possible to link to one/more such blog posts? It'll help readers understand the context, and the point-of-view better :) – Dawny33 Mar 9 '17 at 6:39
  • But - would it be okay to have a very "fat" container with dozens of processes in order to stage a rollout and operation of an enterprise server which still can't have Docker? – Peter Muryshkin Sep 1 '17 at 3:10
  • @J.Doe it will probably not be okay. containers are different than VMs, there are multiple small problems even for a small application - for an enterprise rollout it will be a two year project get it all to run in a container in the first place. – Evgeny Sep 1 '17 at 9:51
up vote 37 down vote accepted

Lets forget the high-level architectural and philosophical arguments for a moment. While there may be some edge cases where multiple functions in a single container may make sense, there are very practical reasons why you may want to consider following "one function per container" as a rule of thumb:

  • Scaling containers horizontally is much easier if the container is isolated to a single function. Need another apache container? Spin one up somewhere else. However if my apache container also has my DB, cron and other pieces shoehorned in, this complicates things.
  • Having a single function per container allows the container to be easily re-used for other projects or purposes.
  • It also makes it more portable and predictable for devs to pull down a component from production to troubleshoot locally rather than an entire application environment.
  • Patching/upgrades (both the OS and the application) can be done in a more isolated and controlled manner. Juggling multiple bits-and-bobs in your container not only makes for larger images, but also ties these components together. Why have to shut down application X and Y just to upgrade Z?
    • Above also holds true for code deployments and rollbacks.
  • Splitting functions out to multiple containers allows more flexibility from a security and isolation perspective. You may want (or require) services to be isolated on the network level -- either physically or within overlay networks -- to maintain a strong security posture or comply with things like PCI.
  • Other more minor factors such as dealing with stdout/stderr and sending logs to the container log, keeping containers as ephemeral as possible etc.

Note that I'm saying function, not process. That language is outdated. The official docker documentation has moved away from saying "one process" to instead recommending "one concern" per container.

Having slain a "two processes" container a few days ago, there some pain points for me which caused me to use two container instead of a python script which started two processes:

  1. Docker is good at recognizing crashed containers. It can't do that when the main process looks fine, but some other process died a gruesome death. Sure, you can monitor your process manually, but why reimplement that?
  2. docker logs gets a lot less useful when multiple processes are spewing their logs to the console. Again, you can write the process name to the logs, but docker can do that, too.
  3. Testing and reasoning about a container get's a lot harder.
  • This should be the accepted answer. – ClintM Jan 15 at 19:07
  • Agreed. While there are some other answers with some great points, the key point is about docker's handling of PID 1. – Brett Wagner Mar 6 at 17:09

The recommendation comes from the goal and design of the Operating-system-level virtualization

Containers have been designed to isolate a process for others by giving it its own userspace and filesystem.
This is the logical evolution of chroot which was providing an isolated filesystem, the next step was isolating processes from the others to avoid memory overwrites and allowing to use the same resource (I.e TCP port 8080 for example) from multiple processes without conflicts.

The main interest in a container it to package the needed library for the process without worrying about version conflicts. If you run multiples processes needing two versions of the same library in the same userspace and filesystem, you'd had to tweak at least LDPATH for each process so the proper library is found first, and some libraries can't be tweaked this way, because their path is hard coded in the executable at compilation time, see this SO question for more details.
At the network level you'll have to configure each process to avoid using the same ports.

Running multiple processes in the same container require some heavy tweaking and at the end of the day defeat the purpose of isolation, if you are ok to run multiples processes within the same userspace, sharing the same filesytem and network resources, then why not running them on the host itself ?

Here is the non exhaustive list of the heavy tweaking/pitfalls I can think of:

  • Handling the logs

    Either being with a mounted volume or interleaved on stdout this bring some management. If using a mounted volume your container should have it's own "place" on host or two same containers will fight for the same resource. When interleaving on stdout to take advantage of docker logs it can become a nightmare for analysis if the sources can't be identified easily.

  • Beware of zombie processes

    If one of your process in a container crash, supervisord may not be able to clean up the childs in a zombie state, and the host init will never inherit them. Once you exhausted the number of available pids (2^22 so roughly 4 millions) a bunch of things will fail.

  • Separation of concerns

    If you run two separated things, like an apache server and logstash within the same container, that may ease the log handling, but you have to shutdown apache to update logstash. (In reality, you should use the logging driver of Docker) Will it be a graceful stop waiting the current sessions to end or not ? If it's a graceful stop, it may take sometime and become long to roll the new version. If you do a kill, you'll impact users for a log shipper and that should be avoided IMHO.

Finally when you have multiple processes you're reproducing an OS, and in this case using a hardware virtualization sounds more in line with this need.

  • 3
    I find these arguments unconvincing. There is a huge difference between a process with multiple containers and running on host. While explaining the original intention of containers is somewhat relevant, it's not really a compelling reason to avoid multi-process containers. IOW, you're answering "why not" with "why yes", which isn't as helpful as it could be. It can be very convenient to run multiple processes in the same container - that's the why yes. The why not remains to be explained. – Assaf Lavie Mar 9 '17 at 13:51
  • 1
    You haven't elaborated on the kind of tweaking you had in mind. And you haven't made the case that this tweaking is more work than setting up multiple containers. Let's take a concrete example: you often see packaged docker images that have supervisord running some main process and some auxiliary process. This is very easy to set up; arguably just as easy as separating the containers. e.g. app & log shipper. So, the onus is on your part, I believe, to argue why this isn't the case. – Assaf Lavie Mar 9 '17 at 15:58
  • 1
    BTW, I do believe there are valid arguments against multi-process containers, but you did not mention any of them. But in any case, it's far from being a clear cut case. In some instances it's perfectly acceptable to allow more than one process. Heck, some very popular images spawn several sub-process - is that evil as well? What I'm saying is there are trade-offs, and your answer paints a one-sided picture that lacks nuance and detail. – Assaf Lavie Mar 9 '17 at 16:00
  • 1
    interesting ... It sounds like we have similar (identical) opinion on this. Maybe you should just ignore it in this case, because it was from somebody who wanted to earn the Critic badge ... and decided to abuse your answer to get that badge ... – Pierre.Vriens Mar 13 '17 at 15:55
  • 1
    I don't "rush" to conclusion ... I just recommend you to ignore it. But "you" cannot change my mind on what I have seen with my own eyes about who the anonymous downvoter of your answer is. Anyway, time to move on ... – Pierre.Vriens Mar 13 '17 at 20:49

As in most cases, it's not all-or-nothing. The guidance of "one process per container" stems from the idea that containers should serve a distinct purpose. For example, a container should not be both a web application and a Redis server.

There are cases where it makes sense to run multiple processes in a single container, as long as both processes support a single, modular function.

The process I'll called as service here, 1 container ~ 1 service, if any of my service is failed then I'll only spin up that respective container and with-in seconds everything is up again. So, there won't be any dependencies between services. It is best practice to keep your container size less than 200 MB and max 500 MB (exception to windows native containers are more than 2 GB's) otherwise, its going to be the similar as virtual machine, not exactly but, performance suffice. Also, take into consideration few parameters as scaling, how could I make my services resilience, auto-deploy, etc.

And, its purely your call how you need to make your architectural patterns like micro-service in polygot environment using the containers technology that best suite your environment and will automate the things for you.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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