Skip to content

Guide · Open source

How to use Tini: init for Docker containers

Updated · written with AI from the project's own documentation and checked against our catalogue data

Tini is a very small program that runs as the first process inside a container. It starts one child program, waits for it to exit, reaps zombie processes and forwards signals such as SIGTERM to that child. This guide shows you how to add Tini to a container, install it on Alpine or Debian, and use its main options.

Tinikrallin/tini · ★ 11.3k · MIT

Quick start

  1. 1Pick a Tini source. Use Docker's built-in --init flag if you run Docker 1.13 or later. Otherwise install the tini package for your distribution.
  2. 2Add Tini to the image. In a Dockerfile, install the package or download the binary, then make sure it is executable.
  3. 3Set Tini as the entrypoint. Use ENTRYPOINT with the Tini path and -- so your program's arguments pass through correctly.
  4. 4Build and run the container. Start the container and confirm your program receives signals such as SIGTERM when you stop it.
  5. 5Adjust options if needed. Use -g, -s, -e or -p only if your program needs process group signalling, subreaping, exit code remapping or a parent death signal.

What Tini does and why use it

Tini is the simplest init you could think of. It spawns a single child, waits for it to exit, reaps zombies and performs signal forwarding. It is meant to be run in a container.

Tini helps in two main ways. Software that accidentally creates zombie processes can, over time, starve the system for PIDs. Tini also makes sure default signal handlers work, so SIGTERM ends your process even if the program never installed its own handler.

  • Reaps zombie processes that your software leaves behind
  • Forwards signals such as SIGTERM to the child process
  • Works transparently: Docker images that work without Tini should work with it unchanged

Use Tini with docker run --init

If you use Docker 1.13 or greater, Tini is included in Docker itself, and this covers all versions of Docker CE. To enable it, pass the --init flag to docker run. You do not need to download or install anything separately.

docker run --init your-image /your/program

Add Tini to a Dockerfile with an entrypoint

If you want Tini in the image itself, add the binary, make it executable and set it as the entrypoint. The entrypoint means you do not have to remember to invoke Tini manually. The -- separates Tini's own arguments from your program's arguments.

You can skip the -- in some cases, but the README advises always including it. If you see an error like tini: invalid option -- 'c', you need the --.

ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini ENTRYPOINT ["/tini", "--"] CMD ["/your/program", "-and", "-its", "arguments"]

Install Tini on Alpine Linux or Debian

On Alpine Linux, install Tini with the package manager. The binary then lives at /sbin/tini. On Debian (Buster or newer) and Ubuntu, the apt package installs /usr/bin/tini and /usr/bin/tini-static, not /tini, so adjust your entrypoint path to match.

The README also lists packages for NixOS (nix-env --install tini) and the AUR for Arch Linux.

RUN apk add --no-cache tini ENTRYPOINT ["/sbin/tini", "--"]

Verify the download before you trust it

The tini and tini-static binaries are signed with a published GPG key, and they also come with SHA1 and SHA256 checksums. The README shows how to check the signature with gpg and the checksum with sha256sum. Use these steps if you download the binary directly from the releases page.

Common options: verbosity, subreaping, exit codes and process groups

The -v flag increases verbosity, and you can pass it up to 3 times. If Tini is not running as PID 1, use -s or the TINI_SUBREAPER variable so zombies are still re-parented to Tini on Linux 3.4 or later. Tini warns you when it is not PID 1 and not a subreaper.

Use -e to remap a child's exit code to 0, which helps with cases like a Java app exiting with 143 after SIGTERM. Use -g to signal the whole child process group, for example so Ctrl-C reaches a sleep that a shell is waiting on. Use -p to set a parent death signal.

  • -v (up to 3 times): extra verbose output
  • -s or TINI_SUBREAPER: register as a child subreaper
  • -e <code>: remap an exit code to 0 (repeatable)
  • -g or TINI_KILL_PROCESS_GROUP: signal the child process group
  • -p <SIGNAL>: set the parent death signal
tini -e 143 -- ... tini -g -- sh -c 'sleep 10' tini -p SIGTERM -- ...

Use Tini with an existing entrypoint

If your container already has an entrypoint script, put Tini in front of it. Tini then starts the script as its child. This lets you add Tini without rewriting the script.

ENTRYPOINT ["/tini", "--", "/docker-entrypoint.sh"]

What people use it for

  • Stop a containerized app cleanly on SIGTERM when the app has no signal handler of its own
  • Reap zombie processes in a long-running container so they do not accumulate
  • Run an existing Docker entrypoint script under Tini without editing the script
  • Map a Java app's 143 exit code to 0 with -e 143

Frequently asked questions

Is Tini free to use?

Tini is released under the MIT licence and is open source. The README does not mention any paid tier.

What do I need to run Tini?

Tini is meant to run inside a container. Docker is optional and is only needed for container use. The binary depends on libc, and a statically linked version is available if your container fails to start.

How do I install Tini on Ubuntu or Debian?

Run apt-get install tini on Debian (Buster or newer). The README notes that this installs /usr/bin/tini and /usr/bin/tini-static, not /tini.

Do I need Tini if Docker has --init?

Docker 1.13 and later include Tini, so docker run --init enables it without extra files. Adding Tini to your Dockerfile is useful when you want the image itself to start with Tini as its entrypoint.

Why does my container ignore Ctrl-C or SIGTERM?

The README says Tini makes default signal handlers work, so SIGTERM ends a program without its own handler. If Ctrl-C still does nothing, for example when a shell waits on a sleep, try the -g flag so the whole process group receives the signal.

What are alternatives to Tini?

The comparable projects listed for this item are dumb-init, s6-overlay and tini-static. Tini only spawns a single child, so if you need several supervised services, a full service manager such as s6-overlay is a better fit.

New agent skills, repos and AI tools — every week

The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.

Our verdict

Tini suits developers and operators who package apps into Docker images and want a small, drop-in init that reaps zombies and forwards signals without changing the application. It is not a fit for virtual machines, non-containerized systems, or anyone who needs to supervise multiple services, where a full service manager is the better choice.

Install options & downloads