Skip to content

fpco/pid1-rs

Repository files navigation

pid1-rs

Crates.io Crates.io Rust

A Rust library and binary for correct PID 1 signal handling and zombie process reaping in containerized environments.

Overview

In Unix-like systems, the process with Process ID (PID) 1 has special responsibilities. It is the ancestor of all other processes and is responsible for adopting orphaned processes and reaping them. When running applications in containers, your application's process often becomes PID 1.

Without proper handling, signals like SIGTERM might not be forwarded to child processes, and zombie processes can accumulate, leading to resource leaks. pid1-rs solves this by providing:

  • Signal Forwarding: Intercepts signals like SIGTERM and SIGINT and forwards them to its child process, allowing for graceful shutdown.
  • Zombie Reaping: Acts as an init process to reap orphaned child processes, preventing zombie process accumulation.

This project provides two ways to use this functionality: as a Rust library integrated into your application, or as a standalone binary executable.

Comparison with tini

tini is a popular, minimal init for containers. pid1-rs provides similar functionality with a different approach:

  • The pid1 library integrates directly into your Rust application. This is its main advantage over tini, as you don't need to add a separate binary to your container. The PID 1 handling logic is compiled into your application, simplifying your Dockerfile and potentially reducing image size.
  • The pid1-exe binary is a direct, Rust-native alternative to tini. Both serve the same purpose as a standalone init binary. If you prefer a toolchain built in Rust or need a init for non-Rust applications, pid1-exe is an excellent choice.

Packages in this Repository

This repository consists of two packages:

  • pid1: A Rust library to integrate into your application.
  • pid1-exe: A standalone pid1 binary for use in any container environment.

pid1 Library Usage

This library is used to simplify Rust deployment in a containerized environment. Instead of using binaries like Haskell's pid1 or tini in your container, you can use this crate directly.

Usage

You must ensure that the launch method is the first statement in your main function:

use std::time::Duration;
use pid1::Pid1Settings;

fn main() {
    Pid1Settings::new()
        .enable_log(true) // Optional: for debugging
        .timeout(Duration::from_secs(2)) // Optional: timeout for graceful shutdown
        .launch()
        .expect("Launch failed");
    println!("Hello world");
    // Rest of the logic...
}

This function is meant only for Unix systems and the above code is a no-op on Windows.

For more examples, see the examples directory.

pid1-exe Binary Usage

You can download the pid1 binary from the releases page and use it as the ENTRYPOINT in your container.

Docker Example

In this example, your-application and its arguments are passed using CMD.

FROM alpine:3.14.2

ADD --chmod=755 https://github.com/fpco/pid1-rs/releases/download/v0.1.0/pid1-x86_64-unknown-linux-musl /usr/bin/pid1

ENTRYPOINT [ "pid1" ]
CMD [ "your-application", "--arg1" ]

Command-line Options

The pid1 binary supports various command-line options:

pid1 --help
Usage:

Arguments:
  <COMMAND>  Process to run
  [ARGS]...  Arguments to the process

Options:
  -w, --workdir <DIR>        Specify working direcory
  -t, --timeout <TIMEOUT>    Timeout (in seconds) to wait for child proess to exit [default: 2]
  -v, --verbose              Turn on verbose output
  -e, --env <ENV>            Override environment variables. Can specify multiple times
  -u, --user-id <USER_ID>    Run command with user ID
  -g, --group-id <GROUP_ID>  Run command with group ID
  -h, --help                 Print help

Development

The testing steps are documented in Development.md.

About

pid1 handling library for proper signal and zombie reaping of the PID1 process

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors