tini README

The project's README from github.com/krallin/tini. As one markdown file: README.md.

Tini - A tiny but valid init for containers

Build Status

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:

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:

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:

This corresponds more closely to what happens when you do ctrl-C etc. in a terminal: The signal is sent to the foreground process group.

docker run --rm --entrypoint tini krallin/ubuntu-tini -g -- sh -c 'sleep 10'

Parent Death Signal

Tini can set its parent death signal, which is the signal Tini should receive when its parent exits. To set the parent death signal, use the -p flag with the name of the signal Tini should receive when its parent exits:

tini -p SIGTERM -- ...

NOTE: See this PR discussion to learn more about the parent death signal and use cases.

More

Existing Entrypoint

Tini can also be used with an existing entrypoint in your container!

Assuming your entrypoint was /docker-entrypoint.sh, then you would use:

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

Statically-Linked Version

Tini has very few dependencies (it only depends on libc), but if your container fails to start, you might want to consider using the statically-built version instead:

ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini

Size Considerations

Tini is a very small file (in the 10KB range), so it doesn't add much weight to your container.

The statically-linked version is bigger, but still < 1M.

Building Tini

If you'd rather not download the binary, you can build Tini by running cmake . && make.

Before building, you probably also want to run:

export CFLAGS="-DPR_SET_CHILD_SUBREAPER=36 -DPR_GET_CHILD_SUBREAPER=37"

This ensure that even if you're building on a system that has old Linux Kernel headers (< 3.4), Tini will be built with child subreaper support. This is usually what you want if you're going to use Tini with Docker (if your host Kernel supports Docker, it should also support child subreapers).

Understanding Tini

After spawning your process, Tini will wait for signals and forward those to the child process, and periodically reap zombie processes that may be created within your container.

When the "first" child process exits (/your/program in the examples above), Tini exits as well, with the exit code of the child process (so you can check your container's exit code to know whether the child exited successfully).

Debugging

If something isn't working just like you expect, consider increasing the verbosity level (up to 3):

tini -v    -- bash -c 'exit 1'
tini -vv   -- true
tini -vvv  -- pwd

Authors

Maintainer:

Contributors:

Special thanks to:

tini (krallin/tini)

Searching Database…

11.3K ·GitHub
这是什么?Tini 是一个极小的初始化进程(init),专为在容器内以 PID 1 的身份运行而设计。它把你的程序作为子进程启动,回收僵尸进程,并把信号转发给子进程,这样 SIGTERM 之类的信号才能正确生效。
它是像 systemd 那样的完整初始化系统,还是更简单的东西?它是可能的最简单的初始化程序:不做服务管理,只负责启动子进程、回收僵尸进程和转发信号。
我该如何把 Tini 加到 Docker 镜像里?把 Tini 二进制文件加入镜像,用 chmod 赋予可执行权限,然后将它设为 ENTRYPOINT,并在你程序的 CMD 之前加上 --。
我需要单独下载这个二进制文件,还是 Docker 已经内置了?如果你使用的是 Docker 1.13 及以上版本(包括所有 Docker CE 版本),Tini 已经内置,你只需在 docker run 时传入 --init 即可。否则,你需要自己添加二进制文件,或者通过 Alpine、NixOS、Debian(Buster 及以上)或 Arch AUR 安装。
运行时有哪些需要注意的地方,比如进程组或退出码?默认情况下,Tini 只向它的直接子进程发送信号,而不是整个进程组,因此除非你传入 -g,Ctrl-C 可能无法传递到 shell 管道中。另外,它需要以 PID 1 身份运行才能回收僵尸进程;或者你可以在 Linux 3.4 及以上版本上使用 -s 把它注册为 subreaper。
谁需要它?它会带来多少额外开销?任何希望正确处理信号并回收僵尸进程的容器开发者都需要它。Tini 极其轻量,动态构建版本约 10KB,静态构建版本不到 1MB。
我能把 Tini 和现有的入口脚本一起使用吗?可以,只需把 Tini 放在最前面,并把你现有的入口脚本作为它的参数传入,例如 ENTRYPOINT ["/tini", "--", "/docker-entrypoint.sh"]。
Tini 能在非 x86 或 32 位系统上运行吗?可以,它提供 ARM 和 32 位的二进制文件,完整的可用二进制文件列表在 GitHub 的 releases 页面上。
子进程退出时,容器的退出码会怎样?Tini 的退出码与第一个子进程的退出码相同,因此检查容器的退出码就能判断子进程是否成功。它还支持通过 -e 参数把特定退出码重新映射为 0,适用于比如 Java 应用在收到 SIGTERM 后以 143 退出的情况。
如何验证下载的 Tini 二进制文件没有被篡改?Tini 的发布版本使用 GPG 密钥签名,同时也公布了 SHA1/SHA256 校验和,因此你可以用 gpg --verify 或 sha256sum -c 来验证其完整性。
Creator
krallin
Size
0.2 MB
Stars
11.3K
Age
11y
Commits · 90 Days