71

I hope that this question will not be marked as primarily opinion-based, but that there is an objective answer to it.

I have read Introducing dumb-init, an init system for Docker containers, which extensively describes why and how to use dumb-init. To be honest, for someone not too experienced with how the Linux process structure works, this sounds pretty dramatic - and it feels as if you are doing things entirely wrong if you don't use dumb-init.

This is why I'm thinking about using it within my very own Docker images… what keeps me from doing this is the fact that I have not yet found an official Docker image that uses it.

  • Take mongo as an example: They call mongod directly.
  • Take postgres as an example: They call postgres directly.
  • Take node as an example: They call node directly.

If dumb-init is so important - why is apparently nobody using it? What am I missing here?

Golo Roden
  • 140,679
  • 96
  • 298
  • 425
  • 9
    (Disclaimer: I'm the maintainer of Tini — Tini and dumb-init are both lightweight init systems for containers). Note that some official Docker images do use such an init system: Redmine, Kibana, Mongo-express, Sentry, Jenkins are good examples. As you observed, this is more often useful for full-fledged apps rather than language runtimes. – Thomas Orozco Jun 06 '16 at 07:44
  • @ThomasOrozco: Can you comment on the technical side what the difference is between tini and dumb-init? Just learning about the two and wondering with the history of tini what the itch was scratched with dumb-init. From the descriptions they seem to do the same (have not compared source-code yet). – hakre May 19 '17 at 21:27
  • 4
    @hakre I believe the dumb-init folks were not aware of Tini when they wrote it, so it's not like they found something fundamentally wrong with Tini that they wanted to fix with dumb-init :). There are a few feature differences between the two. For example they support signal rewriting and Tini doesn't, but Tini supports subreapers and they don't. Overall, though, if you're looking for zombie reaping and that's it, either will do. – Thomas Orozco May 20 '17 at 09:09
  • @ThomasOrozco: Thanks for the explanation. This is all new to me and I still need to figure out if at all there is a problem with Zombie reaping as I have not yet found out how I can provoke it to put it to a test. – hakre May 20 '17 at 09:28
  • 13
    Docker run now has an `--init` flag: `Run an init inside the container that forwards signals and reaps processes`. It looks like the implementation comes directly from tini – lightswitch05 May 22 '18 at 16:28
  • My experience is that `tini` causes my container to crash if I try to resize the window it is running in. I tried it first, since `docker run --init` defaults to `tini`. Then I tried `dumb-init` to see if it would handle the window resizing. It does--no crashes. FYI: My container is based on CentOS7 but installs other tools to set up a build environment. I needed an init process to reap the zombies and both `tini` and `dumb-init` worked well for that purpose. – tanager Aug 31 '21 at 17:31

1 Answers1

44

Something like dumb-init or tini can be used if you have a process that spawns new processes and you don't have good signal handlers implemented to catch child signals and stop your child if your process should be stopped etc.

If your process doesn't spawn new processes (e.g. Node.js), then this may not be necessary.

I guess that MongoDB, PostgreSQL, ... which may run child processes have good signal handlers implemented. Otherwise there would have been zombie processes and someone would have filed an issue to fix this.

Only problem may be the official language images, like node, ruby, golang. They don't have dumb-init/tini in it as you normally don't need them. But it's up to the developer which may implement bad child execution code to either fix the signal handlers or use helper as PID 1.

cngzz1
  • 143
  • 2
  • 9
Stefan Scherer
  • 1,104
  • 9
  • 6
  • 5
    This is not entirely true. Bash scripts for example do NOT handle and emit signals properly. Also Mongo/Postgres RELY on OS's init system to handle the zombies and handle reaping of children processes. This is just the way it works. Also, docker will soon have its own init handler (now merged in master) but until you have version which supports this, you should always have PID1 process that can reap processes. See: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/ – Lu.nemec Oct 27 '16 at 08:10
  • 1
    Many of the official images have introduced [gosu](https://github.com/tianon/gosu), eg. [mongo's entrypoint.sh](https://github.com/docker-library/mongo/blob/5f4bcf4bec163ef05b4fc67d5c92762989dbde06/3.4/docker-entrypoint.sh) as PID1 process. – Stefan Scherer Dec 04 '16 at 10:02
  • 2
    `gosu` README says it `exec`s the process, which means the process will become PID1, so that's orthogonal. _All_ gosu does is switch UID, by design (which btw is [dangerous](https://github.com/tianon/gosu/issues/37) outside container use case). However having an entrypoint.sh script means the shell running that script is PID1, and could use `trap` to pass signals and theorethically `wait --any` to reap zombies — unless the script ends in `exec`, which it does in mongo's example. – Beni Cherniavsky-Paskin Apr 20 '20 at 07:47