{"id":13437663,"url":"https://github.com/Yelp/dumb-init","last_synced_at":"2025-03-19T17:33:17.995Z","repository":{"id":39877632,"uuid":"40563188","full_name":"Yelp/dumb-init","owner":"Yelp","description":"A minimal init system for Linux containers","archived":false,"fork":false,"pushed_at":"2025-02-17T20:10:13.000Z","size":275,"stargazers_count":7021,"open_issues_count":31,"forks_count":350,"subscribers_count":100,"default_branch":"master","last_synced_at":"2025-03-12T22:35:44.100Z","etag":null,"topics":["c","docker","docker-container","dumb","init","pid1","unix"],"latest_commit_sha":null,"homepage":"https://engineeringblog.yelp.com/2016/01/dumb-init-an-init-for-docker.html","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Yelp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-11T20:18:37.000Z","updated_at":"2025-03-12T20:15:26.000Z","dependencies_parsed_at":"2024-04-08T22:30:40.369Z","dependency_job_id":"42acdb6d-2a7c-4092-86ed-b644b95553c2","html_url":"https://github.com/Yelp/dumb-init","commit_stats":{"total_commits":230,"total_committers":27,"mean_commits":8.518518518518519,"dds":0.4304347826086956,"last_synced_commit":"5ccca9cb0498d8a4cb7579a43c8d3ee8c41469c5"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdumb-init","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdumb-init/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdumb-init/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdumb-init/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Yelp","download_url":"https://codeload.github.com/Yelp/dumb-init/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244153550,"owners_count":20407002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","docker","docker-container","dumb","init","pid1","unix"],"created_at":"2024-07-31T03:00:59.122Z","updated_at":"2025-03-19T17:33:17.964Z","avatar_url":"https://github.com/Yelp.png","language":"Python","readme":"dumb-init\n========\n\n[![PyPI version](https://badge.fury.io/py/dumb-init.svg)](https://pypi.python.org/pypi/dumb-init)\n\n\n**dumb-init** is a simple process supervisor and init system designed to run as\nPID 1 inside minimal container environments (such as [Docker][docker]). It is\ndeployed as a small, statically-linked binary written in C.\n\nLightweight containers have popularized the idea of running a single process or\nservice without normal init systems like [systemd][systemd] or\n[sysvinit][sysvinit]. However, omitting an init system often leads to incorrect\nhandling of processes and signals, and can result in problems such as\ncontainers which can't be gracefully stopped, or leaking containers which\nshould have been destroyed.\n\n`dumb-init` enables you to simply prefix your command with `dumb-init`. It acts\nas PID 1 and immediately spawns your command as a child process, taking care to\nproperly handle and forward signals as they are received.\n\n\n## Why you need an init system\n\nNormally, when you launch a Docker container, the process you're executing\nbecomes PID 1, giving it the quirks and responsibilities that come with being\nthe init system for the container.\n\nThere are two common issues this presents:\n\n1. In most cases, signals won't be handled properly.\n\n   The Linux kernel applies special signal handling to processes which run as\n   PID 1.\n\n   When processes are sent a signal on a normal Linux system, the kernel will\n   first check for any custom handlers the process has registered for that\n   signal, and otherwise fall back to default behavior (for example, killing\n   the process on `SIGTERM`).\n\n   However, if the process receiving the signal is PID 1, it gets special\n   treatment by the kernel; if it hasn't registered a handler for the signal,\n   the kernel won't fall back to default behavior, and nothing happens. In\n   other words, if your process doesn't explicitly handle these signals,\n   sending it `SIGTERM` will have no effect at all.\n\n   A common example is CI jobs that do `docker run my-container script`: sending\n   `SIGTERM` to the `docker run` process will typically kill the `docker run` command,\n   but leave the container running in the background.\n\n2. Orphaned zombie processes aren't properly reaped.\n\n   A process becomes a zombie when it exits, and remains a zombie until its\n   parent calls some variation of the `wait()` system call on it. It remains in\n   the process table as a \"defunct\" process. Typically, a parent process will\n   call `wait()` immediately and avoid long-living zombies.\n\n   If a parent exits before its child, the child is \"orphaned\", and is\n   re-parented under PID 1. The init system is thus responsible for\n   `wait()`-ing on orphaned zombie processes.\n\n   Of course, most processes *won't* `wait()` on random processes that happen\n   to become attached to them, so containers often end with dozens of zombies\n   rooted at PID 1.\n\n\n## What `dumb-init` does\n\n`dumb-init` runs as PID 1, acting like a simple init system. It launches a\nsingle process and then proxies all received signals to a session rooted at\nthat child process.\n\nSince your actual process is no longer PID 1, when it receives signals from\n`dumb-init`, the default signal handlers will be applied, and your process will\nbehave as you would expect. If your process dies, `dumb-init` will also die,\ntaking care to clean up any other processes that might still remain.\n\n\n### Session behavior\n\nIn its default mode, `dumb-init` establishes a\n[session](http://man7.org/linux/man-pages/man2/setsid.2.html) rooted at the\nchild, and sends signals to the entire process group. This is useful if you\nhave a poorly-behaving child (such as a shell script) which won't normally\nsignal its children before dying.\n\nThis can actually be useful outside of Docker containers in regular process\nsupervisors like [daemontools][daemontools] or [supervisord][supervisord] for\nsupervising shell scripts. Normally, a signal like `SIGTERM` received by a\nshell isn't forwarded to subprocesses; instead, only the shell process dies.\nWith dumb-init, you can just write shell scripts with dumb-init in the shebang:\n\n    #!/usr/bin/dumb-init /bin/sh\n    my-web-server \u0026  # launch a process in the background\n    my-other-server  # launch another process in the foreground\n\nOrdinarily, a `SIGTERM` sent to the shell would kill the shell but leave those\nprocesses running (both the background and foreground!).  With dumb-init, your\nsubprocesses will receive the same signals your shell does.\n\nIf you'd like for signals to only be sent to the direct child, you can run with\nthe `--single-child` argument, or set the environment variable\n`DUMB_INIT_SETSID=0` when running `dumb-init`. In this mode, dumb-init is\ncompletely transparent; you can even string multiple together (like `dumb-init\ndumb-init echo 'oh, hi'`).\n\n\n### Signal rewriting\n\ndumb-init allows rewriting incoming signals before proxying them. This is\nuseful in cases where you have a Docker supervisor (like Mesos or Kubernetes)\nwhich always sends a standard signal (e.g. SIGTERM). Some apps require a\ndifferent stop signal in order to do graceful cleanup.\n\nFor example, to rewrite the signal SIGTERM (number 15) to SIGQUIT (number 3),\njust add `--rewrite 15:3` on the command line.\n\nTo drop a signal entirely, you can rewrite it to the special number `0`.\n\n\n#### Signal rewriting special case\n\nWhen running in setsid mode, it is not sufficient to forward\n`SIGTSTP`/`SIGTTIN`/`SIGTTOU` in most cases, since if the process has not added\na custom signal handler for these signals, then the kernel will not apply\ndefault signal handling behavior (which would be suspending the process) since\nit is a member of an orphaned process group. For this reason, we set default\nrewrites to `SIGSTOP` from those three signals. You can opt out of this\nbehavior by rewriting the signals back to their original values, if desired.\n\nOne caveat with this feature: for job control signals (`SIGTSTP`, `SIGTTIN`,\n`SIGTTOU`), dumb-init will always suspend itself after receiving the signal,\neven if you rewrite it to something else.\n\n\n## Installing inside Docker containers\n\nYou have a few options for using `dumb-init`:\n\n\n### Option 1: Installing from your distro's package repositories (Debian, Ubuntu, etc.)\n\nMany popular Linux distributions (including Debian (since `stretch`) and Debian\nderivatives such as Ubuntu (since `bionic`)) now contain dumb-init packages in\ntheir official repositories.\n\nOn Debian-based distributions, you can run `apt install dumb-init` to install\ndumb-init, just like you'd install any other package.\n\n*Note:* Most distro-provided versions of dumb-init are not statically-linked,\nunlike the versions we provide (see the other options below). This is normally\nperfectly fine, but means that these versions of dumb-init generally won't work\nwhen copied to other Linux distros, unlike the statically-linked versions we\nprovide.\n\n\n### Option 2: Installing via an internal apt server (Debian/Ubuntu)\n\nIf you have an internal apt server, uploading the `.deb` to your server is the\nrecommended way to use `dumb-init`. In your Dockerfiles, you can simply\n`apt install dumb-init` and it will be available.\n\nDebian packages are available from the [GitHub Releases tab][gh-releases], or\nyou can run `make builddeb` yourself.\n\n\n### Option 3: Installing the `.deb` package manually (Debian/Ubuntu)\n\nIf you don't have an internal apt server, you can use `dpkg -i` to install the\n`.deb` package. You can choose how you get the `.deb` onto your container\n(mounting a directory or `wget`-ing it are some options).\n\nOne possibility is with the following commands in your Dockerfile:\n\n```Dockerfile\nRUN wget https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_amd64.deb\nRUN dpkg -i dumb-init_*.deb\n```\n\n\n### Option 4: Downloading the binary directly\n\nSince dumb-init is released as a statically-linked binary, you can usually just\nplop it into your images. Here's an example of doing that in a Dockerfile:\n\n```Dockerfile\nRUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64\nRUN chmod +x /usr/local/bin/dumb-init\n```\n\n\n### Option 5: Installing from PyPI\n\nThough `dumb-init` is written entirely in C, we also provide a Python package\nwhich compiles and installs the binary. It can be installed [from\nPyPI](https://pypi.python.org/pypi/dumb-init) using `pip`. You'll want to first\ninstall a C compiler (on Debian/Ubuntu, `apt-get install gcc` is sufficient),\nthen just `pip install dumb-init`.\n\nAs of 1.2.0, the package at PyPI is available as a pre-built wheel archive and does not\nneed to be compiled on common Linux distributions.\n\n\n## Usage\n\nOnce installed inside your Docker container, simply prefix your commands with\n`dumb-init` (and make sure that you're using [the recommended JSON\nsyntax][docker-cmd-json]).\n\nWithin a Dockerfile, it's a good practice to use dumb-init as your container's\nentrypoint. An \"entrypoint\" is a partial command that gets prepended to your\n`CMD` instruction, making it a great fit for dumb-init:\n\n```Dockerfile\n# Runs \"/usr/bin/dumb-init -- /my/script --with --args\"\nENTRYPOINT [\"/usr/bin/dumb-init\", \"--\"]\n\n# or if you use --rewrite or other cli flags\n# ENTRYPOINT [\"dumb-init\", \"--rewrite\", \"2:3\", \"--\"]\n\nCMD [\"/my/script\", \"--with\", \"--args\"]\n```\n\nIf you declare an entrypoint in a base image, any images that descend from it\ndon't need to also declare dumb-init. They can just set a `CMD` as usual.\n\nFor interactive one-off usage, you can just prepend it manually:\n\n    $ docker run my_container dumb-init python -c 'while True: pass'\n\nRunning this same command without `dumb-init` would result in being unable to\nstop the container without `SIGKILL`, but with `dumb-init`, you can send it\nmore humane signals like `SIGTERM`.\n\nIt's important that you use [the JSON syntax][docker-cmd-json] for `CMD` and\n`ENTRYPOINT`. Otherwise, Docker invokes a shell to run your command, resulting\nin the shell as PID 1 instead of dumb-init.\n\n\n### Using a shell for pre-start hooks\n\nOften containers want to do some pre-start work which can't be done during\nbuild time. For example, you might want to template out some config files based\non environment variables.\n\nThe best way to integrate that with dumb-init is like this:\n\n```Dockerfile\nENTRYPOINT [\"/usr/bin/dumb-init\", \"--\"]\nCMD [\"bash\", \"-c\", \"do-some-pre-start-thing \u0026\u0026 exec my-server\"]\n```\n\nBy still using dumb-init as the entrypoint, you always have a proper init\nsystem in place.\n\nThe `exec` portion of the bash command is important because it [replaces the\nbash process][exec] with your server, so that the shell only exists momentarily\nat start.\n\n\n## Building dumb-init\n\nBuilding the dumb-init binary requires a working compiler and libc headers and\ndefaults to glibc.\n\n    $ make\n\n\n### Building with musl\n\nStatically compiled dumb-init is over 700KB due to glibc, but musl is now an\noption. On Debian/Ubuntu `apt-get install musl-tools` to install the source and\nwrappers, then just:\n\n    $ CC=musl-gcc make\n\nWhen statically compiled with musl the binary size is around 20KB.\n\n\n### Building the Debian package\n\nWe use the standard Debian conventions for specifying build dependencies (look\nin `debian/control`). An easy way to get started is to `apt-get install\nbuild-essential devscripts equivs`, and then `sudo mk-build-deps -i --remove`\nto install all of the missing build dependencies automatically. You can then\nuse `make builddeb` to build dumb-init Debian packages.\n\nIf you prefer an automated Debian package build using Docker, just run `make\nbuilddeb-docker`. This is easier, but requires you to have Docker running on\nyour machine.\n\n\n## See also\n\n* [Docker and the PID 1 zombie reaping problem (Phusion Blog)](https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/)\n* [Trapping signals in Docker containers (@gchudnov)](https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86)\n* [tini](https://github.com/krallin/tini), an alternative to dumb-init\n* [pid1](https://github.com/fpco/pid1), an alternative to dumb-init, written in Haskell\n\n\n[daemontools]: http://cr.yp.to/daemontools.html\n[docker-cmd-json]: https://docs.docker.com/engine/reference/builder/#run\n[docker]: https://www.docker.com/\n[exec]: https://en.wikipedia.org/wiki/Exec_(system_call)\n[gh-releases]: https://github.com/Yelp/dumb-init/releases\n[supervisord]: http://supervisord.org/\n[systemd]: https://wiki.freedesktop.org/www/Software/systemd/\n[sysvinit]: https://wiki.archlinux.org/index.php/SysVinit\n","funding_links":[],"categories":["HarmonyOS","Python","init","Init systems","OPS"],"sub_categories":["Windows Manager","Container Runtime Distributions"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYelp%2Fdumb-init","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FYelp%2Fdumb-init","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYelp%2Fdumb-init/lists"}