HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
krallin
tini
C2015–2025
krallin / tini

tini

A tiny but valid `init` for containers

27Distinct people
27Mentions
0Explicit recommenders
11.3KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A tiny but valid `init` for containers

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 7:24:48 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year27 dated mentions

Observed mentions: 2015-03-01 17:15:47 UTC to 2025-10-14 02:14:06 UTC.

012342015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20152016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC110
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC312
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC202
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC202
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC312
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC312
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC404
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC202
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC202
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC413

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
Tini - A tiny but valid init for containers Tini is the simplest init you could think of. All Tini does is spawn a single child (Tini is meant to be run in a container), and wait for it to exit all the while reaping zombies and performing signal forwarding. Why Tini? Using Tini has several benefits: It protects you from software that accidentally creates zombie processes, which can (over time!) starve your entire system for PIDs (and make it unusable). It ensures that the default signal handlers work for the software you run in your Docker image. For example, with Tini, SIGTERM properly terminates your process even if you didn't explicitly install a signal handler for it. It does so completely transparently! Docker images that work without Tini will work with Tini without any changes. If you'd like more detail on why this is useful, review this issue discussion: What is advantage of Tini?. Using Tini NOTE: If you are using Docker 1.13 or greater, Tini is included in Docker itself. This includes all versions of Docker CE. To enable Tini, just pass the --init flag to docker run. NOTE: There are pre-built Docker images available for Tini. If you're currently using an Ubuntu or CentOS image as your base, you can use one of those as a drop-in replacement. NOTE: There are Tini packages for Alpine Linux and NixOS. See below for installation instructions. Add Tini to your container, and make it executable. Then, just invoke Tini and pass your program and its arguments as arguments to Tini. In Docker, you will want to use an entrypoint so you don't have to remember to manually invoke Tini: # Add Tini ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini ENTRYPOINT ["/tini", "--"] # Run your program under Tini CMD ["/your/program", "-and", "-its", "arguments"] # or docker run your-image /your/program ... Note that you can skip the -- under certain conditions, but you might as well always include it to be safe. If you see an error message that looks like tini: invalid option -- 'c', then you need to add the --. Arguments for Tini itself should be passed like -v in the following example: /tini -v -- /your/program. NOTE: The binary linked above is a 64-bit dynamically-linked binary. Signed binaries The tini and tini-static binaries are signed using the key 595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7. You can verify their signatures using gpg (which you may install using your package manager): ENV TINI_VERSION v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini.asc /tini.asc RUN gpg --batch --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7 \ && gpg --batch --verify /tini.asc /tini RUN chmod +x /tini Verifying binaries via checksum The tini and tini-static binaries have generated checksums (SHA1 and SHA256). You can verify their checksums using sha1sum and sha256sum (which you may install using your package manager): ENV TINI_VERSION v0.19.0 RUN wget --no-check-certificate --no-cookies --quiet https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-amd64 \ && wget --no-check-certificate --no-cookies --quiet https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-amd64.sha256sum \ && echo "$(cat tini-amd64.sha256sum)" | sha256sum -c Alpine Linux Package On Alpine Linux, you can use the following command to install Tini: RUN apk add --no-cache tini # Tini is now available at /sbin/tini ENTRYPOINT ["/sbin/tini", "--"] NixOS Using Nix, you can use the following command to install Tini: nix-env --install tini Debian On Debian (Buster or newer), you can use the following command to install Tini: apt-get install tini Note that this installs /usr/bin/tini (and /usr/bin/tini-static), not /tini. Arch Linux On Arch Linux, there is a package available on the AUR. Install using the official instructions or use an AUR helper: pacaur -S tini Other Platforms ARM and 32-bit binaries are available! You can find the complete list of available binaries under the releases tab. Options Verbosity The -v argument can be used for extra verbose output (you can pass it up to 3 times, e.g. -vvv). Subreaping By default, Tini needs to run as PID 1 so that it can reap zombies (by running as PID 1, zombies get re-parented to Tini). If for some reason, you cannot run Tini as PID 1, you should register Tini as a process subreaper instead (only in Linux >= 3.4), by either: Passing the -s argument to Tini (tini -s -- ...) Setting the environment variable TINI_SUBREAPER (e.g. export TINI_SUBREAPER=). This will ensure that zombies get re-parented to Tini despite Tini not running as PID 1. NOTE: Tini will issue a warning if it detects that it isn't running as PID 1 and isn't registered as a subreaper. If you don't see a warning, you're fine. Remapping exit codes Tini will reuse the child's exit code when exiting, but occasionally, this may not be exactly what you want (e.g. if your child exits with 143 after receiving SIGTERM). Notably, this can be an issue with Java apps. In this case, you can use the -e flag to remap an arbitrary exit code to 0. You can pass the flag multiple times if needed. For example: tini -e 143 -- ... Process group killing By default, Tini only kills its immediate child process. This can be inconvenient if sending a signal to that process does not have the desired effect. For example, if you do docker run --rm krallin/ubuntu-tini sh -c 'sleep 10' and ctrl-C it, nothing happens: SIGINT is sent to the 'sh' process, but that shell won't react to it while it is waiting for the 'sleep' to finish. You can configure Tini to kill the child process group, so that every process in the group gets the signal, by either: Passing the -g argument to Tini (tini -g -- ...) Setting the environment variable TINI_KILL_PROCESS_GROUP (e.g. export TINI_KILL_PROC
Read the full README on GitHub

What Hacker News says

2 sources
Not OP, but I’ve been running a kubernetes cluster for a few months myself, so I’ll try to give context. > Don’t trust arbitrary base images. Kinda obvious, the equivalent of "don’t trust any random binary from the web", as it can contain malware at worst. > Use small base image. Generally, you should look at using Alpine as base image, to reduce storage size, and memory consumption of the overlay filesystem that docker uses. But be aware, Alpine uses musl and busybox instead of GNU libc and utils, so some software might not work there. Generally, this is also common sense. See more at https://alpinelinux.org/about/ and https://hub.docker.com/_/alpine/ – but be aware, often the projects you want to depend on already have an alpine image (e.g., openjdk, nodejs or postgres images are all available in an alpine version, reducing their size f
Read the rest
rom 500M+ to around 10-20M) > Use the builder pattern. With containers, many people include all build dependencies in the final container. Docker has a new syntax to avoid this, by declaring first a builder container, with its dependencies, then building, and then declaring the final container, and COPY'ing the build artifacts from the build container. This, too, keeps container size a lot smaller. You can find more here: https://docs.docker.com/engine/userguide/eng-image/multistag... > Use non-root user inside container. This is basically common sense with regards to docker as runtime, and is bad security practice (especially when combined with problematic filesystem mounts). Also is recommended by the Docker team: https://docs.docker.com/develop/dev-best-practices/ > Make the file system read only. I’m not sure what OP is referring to here, but if it refers to the container filesystem, that is because writing to AuFS or OverlayFS is significantly slower (and more memory intensive) than writing to a PersistentVolumeClaim or EmptyDir volume in Kubernetes, so you should always mount an EmptyDir volume for all log folders, temporary data, etc, and a PersistentVolumeClaim for all persistent data. Also is recommended by the Docker team: https://docs.docker.com/develop/dev-best-practices/ > One process per container, Don’t restart on failure, crash cleanly instead, Log to stdout & stdderr This is related to the logging system (which mostly looks at stdout and stderr), which is a result of the fact that Kubernetes itself was mostly designed to work with a single process per container. Yes, you can spawn multiple processes, from a single shell, and print their combined stdout, but then you also need to ensure that if one crashes, everything restarts properly. If you use a single process per container, logging to stdout/stderr, then scaling is a lot simpler, and restarts are handled automatically (and this is required for staged rollout). > Add dumb-init to prevent zombie processes. If you need multiple processes, and one that isn’t PID1 crashes, you’ll end up with zombie processes. A single process per container obviously avoids this, but if you have to use multiple, at least add an init system to reap dead child processes, potentially restart crashed dependent processes, etc. Normally, docker supports the --init parameter to do this, but the version recommended for use with Kubernetes does not support this yet (EDIT: apparently, since 1.7.0, Kubernetes actually does automatically do this for you), so you could add e.g. https://github.com/Yelp/dumb-init or https://github.com/krallin/tini (both officially recommended by the Docker team)
In Kubernetes Best Practices

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.