minimal_containers is a lightweight, container-like virtualisation program. It consists of the program container with the subcommands start, start-all, kill and list and is written in C.
The configs, logs and pids are saved in the directory {PATH}/configs, {PATH}/logs and {PATH}/pids, respectively (see config.h), by default PATH is /containers. A container is created by adding a config named {PATH}/configs/{CONTAINER} and starting it with container start {CONTAINER}.
You should first install dietlibc. Then call make and either copy container to a directory in PATH or add the current directory to PATH.
The config syntax is kept as easy as possible: there are key-value pairs which are written as KEY=VALUE.
Possible keys:
| Name | Required | Description |
|---|---|---|
root |
Yes | The path of the root of the container (cdebootstrap/debootstrap/mmdebstrap can be used to create an initial rootfs) |
init |
Yes | The script/program executed when the container is started (When a @ precedes the path, the path is assumed to be outside of the container) |
namespaces |
Yes | Sets what should be "virtualized"/unshared:
|
max_physical_memory |
No | The maximum physical memory the container may use |
max_memory |
No | The maximum memory (physical + swap) the container may use |
max_processes |
No | The maximum processes which the container is allowed to run simultaneously |
cpu_share |
No | The "importance" of the container, a part of 1024 |
net_classid |
No | The network packets of the container will be assigned the specified classid (can be used for example with iptables) |
id_map_start |
No | The starting uid/gid for uid/gid mappings, e.g. uid 0 (root) inside of the container is the specified value outside of the container, uid x inside of the container is the specified value + x outside of the container, by default 10000, if you set it to 0, every uid/gid will be mapped to the same uid/gid outside of the container |
mount |
No | (Can be used multiple times) (In the format SOURCE:DEST) The directory SOURCE will be available as DEST inside of the container. container start warns when mounting fails, but continues nevertheless |
mount_ro |
No | Same as mount, but read-only. When mounting fails, container start exits |
iops_limit |
No | (Can be used multiple times) (In the format MAJOR:MINOR IOPS) Limits the maximum IOPS for a device |
io_bw_limit |
No | (Can be used multiple times) (In the format MAJOR:MINOR BYTES_PER_SECOND) Limits the maximum throughput for a device |
If a line is empty or starts with a #, it is ignored. Comments CANNOT be inserted in the same line as a key-value-pair. Do NOT use Windows-style linebreaks.
You can start a container with container start {CONTAINER}. When you want to debug something, you can use container start -s {CONTAINER} to start an interactive shell inside of the container (when you don't want to use /bin/bash, you can set the environment variable SHELL (When a @ precedes the path specified in SHELL, the path is assumed to be outside of the container)). The directories {PATH}/configs, {PATH}/logs and {PATH}/pids must exist.
You can stop a container with container kill {CONTAINER}. Warning: this SIGKILL's all processes within the container - they have no chance to clean something up.
Abstract unix sockets (often displayed starting with @, for example used by Xorg) are NOT unshared (blame Linux, network namespaces would be required, but that is currently not included in minimal_containers, feel free to open a PR).
With Debian you should execute rm /sbin/telinit && ln -s /bin/true /sbin/telinit when starting a container, as there is no systemd and apt calls telinit which would try to contact systemd forever.
When you install xfce4, you have to pay attention that xfce4-session doesn't have the same pid in different containers, see abstract unix sockets.
The neccesary cgroup (v1) systems have to be mounted at /sys/fs/cgroup/{devices,memory,pids,cpu,blkio,net_cls}.
The root filesystem should be owned by the correct uid/gid (inside of the container) (see id_map_start).
In a shell session, /dev/self/fd/{0,1,2}, /dev/std{out,err,in} mostly won't work.
On my servers, container start uses around 44 KiB RSS.
minimal_containers uses cgroups to limit the resource usage, linux namespaces to isolate the containers from the system and pivot_root to change the root directory.