{"id":118028,"date":"2022-06-28T01:53:11","date_gmt":"2022-06-27T22:53:11","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=118028"},"modified":"2024-07-08T19:44:12","modified_gmt":"2024-07-08T16:44:12","slug":"use-tini-init-system-in-docker-containers","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/use-tini-init-system-in-docker-containers\/","title":{"rendered":"How To Use Tini Init system in Docker Containers"},"content":{"rendered":"\n<p>An <strong>init<\/strong> process can be defined as the top-most process started by the kernel at the system boot. They are responsible for starting the rest of the services on the system. These services include the SSH daemon, Nginx\/Apache e.t.c. Each of the started processes may further give rise to <strong><em>child<\/em><\/strong> <strong><em>processes<\/em><\/strong>. A <strong>Zombie<\/strong> is a child process that terminates but has not waited for. The kernel maintains information about the Zombie. This information can be, PID, resource usage information, or termination status. These Zombies are harmful and should be removed via a wait. They consume slots in the kernel process table which fills and prevents the creation of further processes.<\/p>\n\n\n\n<p><strong>Tini<\/strong> is a tiny and simplest <strong><em>init<\/em><\/strong> available for containers. It works by spawning a single child and waiting for it to exit while reaping the zombie processes as well as performing signal forwarding.<\/p>\n\n\n\n<p>It is mainly preferred due to the following benefits.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Protects the kernel from software that accidentally creates zombie processes that starve the system PIDs<\/li>\n\n\n\n<li>Transparent and can be used on any container that works without Tini with no changes required.<\/li>\n\n\n\n<li>It ensures that the<em> default signal handlers<\/em> work for the software you run in your Docker image. For example, using <em>SIGTERM<\/em> terminates the process even if it did not install a signal handler for it.<\/li>\n<\/ul>\n\n\n\n<p>This guide provides the required knowledge on how to use<em> <\/em>the<em> Tini Init<\/em> system in Docker Containers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Add Tini to your Container<\/h2>\n\n\n\n<p>Tini exists in Docker 1.13 and greater versions. It can easily be enabled using the<code> --init<\/code> flag while running the docker container.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using Prebuilt Tini Images<\/h3>\n\n\n\n<p>There are also prebuilt images for Tini for Ubuntu and CentOS base which can as well be used as a drop-in replacement of your base. All you do is modify your Dockerfile to use the Tini images instead.<\/p>\n\n\n\n<p>For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em># Change this:\n<\/em>FROM ubuntu:trusty\n\n<em># To this:\n<\/em>FROM krallin\/ubuntu-tini:trusty<\/code><\/pre>\n\n\n\n<p>With this image, the <em>ENTRYPOINT<\/em> shipped should point to Tini. If you already have an <em>ENTRYPOINT<\/em> configured, modify it as below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em># Change this:\n<\/em>ENTRYPOINT &#91;\"\/docker-entrypoint.sh\"]\n\n<em># To this:\n<\/em>ENTRYPOINT &#91;\"\/usr\/local\/bin\/tini\", \"--\", \"\/docker-entrypoint.sh\"]<\/code><\/pre>\n\n\n\n<p>Remember if you aren&#8217;t using an <em>ENTRYPOINT<\/em>, don&#8217;t make the above changes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using Tini Packages<\/h3>\n\n\n\n<p>There are Tini packages available for Alpine Linux and NixOS and can be added to your Docker file as below.<\/p>\n\n\n\n<p><strong>Alpine Linux Package<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RUN apk add --no-cache tini\n# Tini is now available at \/sbin\/tini\nENTRYPOINT &#91;\"\/sbin\/tini\", \"--\"]<\/code><\/pre>\n\n\n\n<p><strong>NixOS Package<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nix-env --install tini<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Manually add Tini<\/h3>\n\n\n\n<p>You can also add Tini to your container and make it executable. Proceed and invoke Tini and pass the program and arguments.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"># Add Tini\n<\/mark><\/em>ENV TINI_VERSION v0.19.0\nADD https:\/\/github.com\/krallin\/tini\/releases\/download\/${TINI_VERSION}\/tini \/tini\nRUN chmod +x \/tini\nENTRYPOINT &#91;\"\/tini\", \"--\"]\n\n<em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"># Run your program under Tini\n<\/mark><\/em>CMD &#91;\"\/your\/program\", \"-and\", \"-its\", \"arguments\"]\n# or docker run your-image \/your\/program ...<\/code><\/pre>\n\n\n\n<p>Alternatively, you can use signed binaries when adding Tini to your container above.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"># Add Tini\n<\/mark><\/em>ENV TINI_VERSION v0.19.0\nADD https:\/\/github.com\/krallin\/tini\/releases\/download\/${TINI_VERSION}\/tini \/tini\nADD https:\/\/github.com\/krallin\/tini\/releases\/download\/${TINI_VERSION}\/tini.asc \/tini.asc\nRUN gpg --batch --keyserver hkp:\/\/keyserver.ubuntu.com:80 --recv-keys 595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7 \\\n &amp;&amp; gpg --batch --verify \/tini.asc \/tini\nRUN chmod +x \/tini\nENTRYPOINT &#91;\"\/tini\", \"--\"]\n\n<em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"># Run your program under Tini\n<\/mark><\/em>CMD &#91;\"\/your\/program\", \"-and\", \"-its\", \"arguments\"]\n# or docker run your-image \/your\/program ...<\/code><\/pre>\n\n\n\n<p>To use the above command, ensure <strong><code>gpg<\/code><\/strong> is installed from your package manager.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use Tini Init system in Docker Containers<\/h2>\n\n\n\n<p>Here I will demonstrate how to use Tini from Docker itself by using the <code>--init<\/code> flag.<\/p>\n\n\n\n<p>A container run without passing the init flag sets the CMD as<strong> PID 1<\/strong>. In this case, the CMD is <em><strong>\/bin\/bash<\/strong><\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-pink-color\">docker run -ti --rm ubuntu:20.04 \/bin\/bash<\/mark>\nUnable to find image 'ubuntu:20.04' locally\n20.04: Pulling from library\/ubuntu\nd5fd17ec1767: Pull complete \nDigest: sha256:47f14534bda344d9fe6ffd6effb95eefe579f4be0d508b7445cf77f61a0e5724\nStatus: Downloaded newer image for ubuntu:20.04\nroot@bcb9f64af7fc:\/#<\/code><\/pre>\n\n\n\n<p>Check the PIDs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@bcb9f64af7fc:\/# <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-pink-color\">ps -fA<\/mark>\nUID          PID    PPID  C STIME TTY          TIME CMD\n<strong>root           1       0  0 09:19 pts\/0    00:00:00 \/bin\/bash\n<\/strong>root           8       1  0 09:20 pts\/0    00:00:00 ps -fA<\/code><\/pre>\n\n\n\n<p>The output above shows the CMD as PID 1. Now let&#8217;s see what happens when the &#8211;init flag is invoked.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-pink-color\">docker run -ti --init --rm ubuntu:20.04 \/bin\/bash<\/mark><\/em>\nroot@625db045f048:\/# <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">ps -fA<\/mark>\nUID          PID    PPID  C STIME TTY          TIME CMD\n<strong>root           1       0  0 09:22 pts\/0    00:00:00 \/sbin\/docker-init -- \/bin\/ba\n<\/strong>root           6       1  0 09:22 pts\/0    00:00:00 \/bin\/bash\nroot           9       6  0 09:22 pts\/0    00:00:00 ps -fA<\/code><\/pre>\n\n\n\n<p>When <strong>Tini<\/strong> init is used, it becomes<strong> PID 1<\/strong> as shown above. Now from here, Tini with PID 1 will reap forked child processes correctly.<\/p>\n\n\n\n<p>Another example using the prebuilt Tini images:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-pink-color\">docker run -ti krallin\/ubuntu-tini:trusty \/bin\/bash<\/mark>\nroot@928f92c6a1b1:\/# <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">ps -fA<\/mark>\nUID          PID    PPID  C STIME TTY          TIME CMD\n<strong>root           1       0  0 09:39 pts\/0    00:00:00 \/usr\/bin\/tini -- \/bin\/bash\n<\/strong>root           6       1  0 09:39 pts\/0    00:00:00 \/bin\/bash\nroot          16       6  0 09:39 pts\/0    00:00:00 ps -fA<\/code><\/pre>\n\n\n\n<p>You can as well execute these commands to a running container with Tini as below.<\/p>\n\n\n\n<p>To check the PIDs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker exec -it <em><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\">&lt;container_name&gt;<\/mark><\/em> ps -fA<\/code><\/pre>\n\n\n\n<p>For example.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"198\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers-1024x198.png\" alt=\"\" class=\"wp-image-118034\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers-1024x198.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers-300x58.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers-768x148.png 768w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers-696x134.png 696w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers-1068x206.png 1068w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2022\/05\/How-To-Use-Tini-Init-system-in-Docker-Containers.png 1263w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Check the Tini version.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-pink-color\">docker exec -it semaphore tini --version<\/mark>\ntini version 0.19.0<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Subreaping<\/h3>\n\n\n\n<p>For Tini to reap zombies, it should run as PID 1. This ensures that zombies are re-parented to Tini. If Tini cannot run as PID 1, you need to register Tini as a process <em><strong>subreaper<\/strong><\/em>. This can be done in two ways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Passing the <code>-s<\/code> argument to Tini (<code>tini -s -- \u2026<\/code>)<\/li>\n\n\n\n<li>invoke the variable <code>TINI_SUBREAPER<\/code>for example <code>export TINI_SUBREAPER=<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Remapping exit codes<\/h3>\n\n\n\n<p>Tini reuses the child&#8217;s exit code when exiting. This may not be exactly what you prefer. For example, if a child process exits with 143 after receiving SIGTERM, This issue is notable in Java apps. You can use the<code> -e<\/code> flag to remap the code to 0.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tini -e 143 -- ...<\/code><\/pre>\n\n\n\n<p>There are several options when using Tini, get help as below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@928f92c6a1b1:\/# <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-pale-pink-color\">tini -h<\/mark>\ntini (tini version 0.19.0 - git.fec3683)\nUsage: tini &#91;OPTIONS] PROGRAM -- &#91;ARGS] | --version\n\nExecute a program under the supervision of a valid init process (tini)\n\nCommand line options:\n\n  --version: Show version and exit.\n  -h: Show this help message and exit.\n  -s: Register as a process subreaper (requires Linux &gt;= 3.4).\n  -p SIGNAL: Trigger SIGNAL when parent dies, e.g. \"-p SIGKILL\".\n  -v: Generate more verbose output. Repeat up to 3 times.\n  -w: Print a warning when processes are getting reaped.\n  -g: Send signals to the child's process group.\n  -e EXIT_CODE: Remap EXIT_CODE (from 0 to 255) to 0.\n  -l: Show license and exit.\n\nEnvironment variables:\n\n  TINI_SUBREAPER: Register as a process subreaper (requires Linux &gt;= 3.4).\n  TINI_VERBOSITY: Set the verbosity level (default: 1).\n  TINI_KILL_PROCESS_GROUP: Send signals to the child's process group.<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Closing Thoughts.<\/h2>\n\n\n\n<p>That marks the end of this guide on how to use the Tini Init system in Docker Containers. You can now use Tini to reap the zombie processes as well as perform signal forwarding. I hope this was significant and helpful to you.<\/p>\n\n\n\n<p>Related posts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/computingforgeeks.com\/install-mirantis-cri-dockerd-as-docker-engine-shim-for-kubernetes\/\" target=\"_blank\" rel=\"noreferrer noopener\">Install Mirantis cri-dockerd as Docker Engine shim for Kubernetes<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/computingforgeeks.com\/solve-error-package-docker-ce-stable-requires-container-selinux\/\" target=\"_blank\" rel=\"noreferrer noopener\">How To Install Docker CE on Linux Systems<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/computingforgeeks.com\/how-to-run-plex-media-server-in-docker-containers\/\" target=\"_blank\" rel=\"noreferrer noopener\">How To Run Plex Media Server in Docker Containers<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>An init process can be defined as the top-most process started by the kernel at the system boot. They are responsible for starting the rest of the services on the system. These services include the SSH daemon, Nginx\/Apache e.t.c. Each of the started processes may further give rise to child processes. A Zombie is a &#8230; <a title=\"How To Use Tini Init system in Docker Containers\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/use-tini-init-system-in-docker-containers\/\" aria-label=\"Read more about How To Use Tini Init system in Docker Containers\">Read more<\/a><\/p>\n","protected":false},"author":21,"featured_media":120380,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[316,27,299,50],"tags":[37556,37555,37557,37554],"class_list":["post-118028","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-containers","category-docker","category-how-to","category-linux-tutorials","tag-tini-docker","tag-tini-in-docker","tag-tini-init","tag-tini-init-system-in-docker"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/118028","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=118028"}],"version-history":[{"count":0,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/118028\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/120380"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=118028"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=118028"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=118028"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}