containers.conf(5)

πŸ’… containers.conf β€” the config file, aka containers.conf(5)

ok so bestie, picture this: you're on containers.conf(5) and you're about to learn the container engine config file that sets the default configuration options and command-line flags for container engines. She's the blueprint. She's the vibe. Let's go 🫢


✨ NAME ✨

containers.conf β€” the container engine configuration file. It specifies default configuration options and command-line flags for container engines. That's it, that's the whole job, and she does it flawlessly πŸ’…


🌸 DESCRIPTION 🌸

Container engines like Podman & Buildah read the containers.conf file, if it exists, and use it to modify the defaults for running containers on the host. It's written in TOML format, which is literally the easiest thing to tweak and version, no cap πŸ”₯

By default, the config is read from $XDG_CONFIG_HOME/containers/containers.conf (or from $HOME/.config/containers/containers.conf if $XDG_CONFIG_HOME is unset), if it exists; otherwise from /etc/containers/containers.conf; otherwise from /usr/share/containers/containers.conf.

πŸŽ€ Drop-in files, because one file is never enough

In addition to containers.conf, drop-in files using the same format from the following directories are also read:

  • $XDG_CONFIG_HOME/containers/containers.conf.d (or from $HOME/.config/containers/containers.conf.d if $XDG_CONFIG_HOME is unset)
  • /etc/containers/containers.rootful.conf.d (only when running as uid 0)
  • /etc/containers/containers.rootless.conf.d/$UID (only when running as uid > 0)
  • /etc/containers/containers.rootless.conf.d (only when running as uid > 0)
  • /etc/containers/containers.conf.d
  • /usr/share/containers/containers.rootful.conf.d (only when running as uid 0)
  • /usr/share/containers/containers.rootless.conf.d/$UID (only when running as uid > 0)
  • /usr/share/containers/containers.rootless.conf.d (only when running as uid > 0)
  • /usr/share/containers/containers.conf.d

🌈 The rules of the drop-in game

The files must be using the .conf suffix β€” directories or files with other suffixes will be ignored, periodt πŸ™ˆ

All files from these paths will be first collected and then sorted in alpha-numerical order. If the same filename is used twice, then only the first match from the directory list above is used. Then the files will be parsed in the sorted order. It's giving very organized, very cunty, honestly πŸ‘‘

Fields specified in containers conf override the default options, as well as options in previously read containers.conf files.

See containers-config(5) for a more detailed description on how the files are loaded. iykyk.

Not all options are supported in all container engines. (Yes, that's real, don't come for me πŸ’€)

Note: container engines also use other configuration files for configuring the environment. Bestie, she's not the only one in the group chat:
  • storage.conf for configuration of container and images storage.
  • registries.conf for definition of container registries to search while pulling container images.
  • policy.conf for controlling which images can be pulled to the system.
Note: if Podman is running in a virtual machine using podman machine (this includes Mac and Windows hosts), ensure that the configuration files are edited in the virtual machine by using podman machine ssh. Don't edit them on the host and wonder why nothing's happening. We've all been there 😭

πŸ¦‹ ENVIRONMENT VARIABLES πŸ¦‹

  • CONTAINERS_CONF β€” if this is set, all system and user config files are ignored and only the specified config file will be loaded. Iconic. Exclusive. Main character energy.
  • CONTAINERS_CONF_OVERRIDE β€” if this path environment variable is set, the config file will be loaded last even when CONTAINERS_CONF is set. She gets the final say, always πŸ’…

The values of both environment variables may be absolute or relative paths, for instance, CONTAINERS_CONF=/tmp/my_containers.conf.


🧚 MODULES 🧚

A module is a containers.conf file located directly in or a sub-directory of the following three directories:

  • $XDG_CONFIG_HOME/containers/containers.conf.modules or $HOME/.config/containers/containers.conf.modules if $XDG_CONFIG_HOME is not set.
  • /etc/containers/containers.conf.modules
  • /usr/share/containers/containers.conf.modules

Files in those locations are not loaded by default β€” only on-demand. Like, they're on read receipts until you actually ask for them 🌸

They are loaded after all system and user configuration files but before CONTAINERS_CONF_OVERRIDE, hence allowing for overriding system and user configs.

Modules are currently supported by podman(1). The podman --module flag allows for loading a module and can be specified multiple times. If the specified value is an absolute path, the config file will be loaded directly. Relative paths are resolved relative to the three module directories mentioned above and in the specified order such that modules in $XDG_CONFIG_HOME/$HOME allow for overriding those in /etc and /usr/share. Hierarchy! Ordering! She ate ✨


πŸ’– APPENDING TO STRING ARRAYS πŸ’–

So the default behavior during the loading sequence of multiple containers.conf files is to override previous data. Rude, but okay. To change the behavior from overriding to appending, you can set the append attribute as follows:

array=["item-1", "item=2", ..., {append=true}]

Setting the append attribute instructs to append to this specific string array for the current and also subsequent loading steps. To change back to overriding, set {append=false}.

Consider the following example:

modules1.conf: env=["1=true"]
modules2.conf: env=["2=true"]
modules3.conf: env=["3=true", {append=true}]
modules4.conf: env=["4=true"]

After loading the files in the given order, the final contents are env=["2=true", "3=true", "4=true"]. If modules4.conf would set {append=false}, the final contents would be env=["4=true"]. See how that works? Lowkey genius, highkey useful, no notes πŸ’œ


⭐ FORMAT ⭐

The TOML format https://github.com/toml-lang/toml is used as the encoding of the configuration file. Every option is nested under its table. No bare options are used. The format of TOML can be simplified to:

[table1]
option = value

[table2]
option = value

[table3]
option = value

[table3.subtable1]
option = value

Nested like a Russian doll, except she's cute and versionable πŸŽ€


πŸ‘‘ CONTAINERS TABLE πŸ‘‘

The containers table contains settings to configure and manage the OCI runtime. This is where the real content lives, bestie, buckle up πŸš€

  • annotations = [] β€” list of annotations. Specified as "key=value" pairs to be added to all containers. Example: "run.oci.keep_original_groups=1"
  • apparmor_profile = "container-default" β€” used to change the name of the default AppArmor profile of container engines. The default profile name is "container-default".
  • base_hosts_file = "" β€” base file to create the /etc/hosts file inside the container. This must either be an absolute path to a file on the host system, or one of the following special flags:
    • "" β€” use the host's /etc/hosts file (the default)
    • none β€” do not use a base file (i.e. start with an empty file)
    • image β€” use the container image's /etc/hosts file as base file
  • cgroup_conf = [] β€” list of cgroup_conf entries specifying a list of cgroup files to write to and their values. For example memory.high=1073741824 sets the memory.high limit to 1GB.
  • cgroups = "enabled" β€” determines whether the container will create CGroups. Options are:
    • enabled β€” enable cgroup support within container
    • disabled β€” disable cgroup support, will inherit cgroups from parent
    • no-conmon β€” do not create a cgroup dedicated to conmon.
  • cgroupns = "private" β€” default way to create a cgroup namespace for the container. Options are: private β€” create private Cgroup Namespace for the container. host β€” share host Cgroup Namespace with the container.
  • container_name_as_hostname = true|false β€” when no hostname is set for a container, use the container's name, with characters not valid for a hostname removed, as the hostname instead of the first 12 characters of the container's ID. Containers not running in a private UTS namespace will have their hostname set to the host's hostname regardless of this setting.

Default is false.

  • default_capabilities = [] β€” list of default capabilities for containers.

The default list is:

default_capabilities = [
      "CHOWN",
      "DAC_OVERRIDE",
      "FOWNER",
      "FSETID",
      "KILL",
      "NET_BIND_SERVICE",
      "SETFCAP",
      "SETGID",
      "SETPCAP",
      "SETUID",
      "SYS_CHROOT",
]
Note: by default container engines using containers.conf run with less capabilities than Docker. Docker runs additionally with "AUDIT_WRITE", "MKNOD" and "NET_RAW". If you need to add one of these capabilities for a particular container, you can use the --cap-add option or edit your system's containers.conf.
  • default_sysctls = [] β€” a list of sysctls to be set in containers by default, specified as "name=value".

Example: "net.ipv4.ping_group_range=0 1000".

  • default_ulimits = [] β€” a list of ulimits to be set in containers by default, specified as "name=soft-limit:hard-limit".

Example: "nofile=1024:2048".

  • devices = [] β€” list of devices. Specified as 'device-on-host:device-on-container:permissions'.

Example: "/dev/sdc:/dev/xvdc:rwm".

  • dns_options = [] β€” list of default DNS options to be added to /etc/resolv.conf inside of the container.
  • dns_searches = [] β€” list of default DNS search domains to be added to /etc/resolv.conf inside of the container.
  • dns_servers = [] β€” a list of dns servers to override the DNS configuration passed to the container. The special value β€œnone” can be specified to disable creation of /etc/resolv.conf in the container.
  • env = ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"] β€” environment variable list for the container process, used for passing environment variables to the container. If a variable is listed without a value, the value is copied from the host environment.
Note: this is only used when a container is created, not with subsequent commands like podman exec. This prevents variables in the config file from overwriting values specified on the command line when the container was created. Sneaky-proof, love that for us πŸ™ˆ
  • env_host = false β€” pass all host environment variables into the container.
  • host_containers_internal_ip = "" β€” set the IP address the container should expect to connect to the host. The IP address is used by Podman to automatically add the host.containers.internal and host.docker.internal hostnames to the container's /etc/hosts file. It is also used for the host-gateway flag of Podman's --add-host CLI option. If no IP address is configured (the default), Podman will try to determine it automatically, but might fail to do so depending on the container's network setup. Adding these internal hostnames to /etc/hosts is silently skipped then. Set this config to none to never add the internal hostnames to /etc/hosts.
Note: if Podman is running in a virtual machine using podman machine (this includes Mac and Windows hosts), Podman resolves the host.containers.internal hostname via the podman machine (gvproxy) DNS resolver instead when it is empty. Also because the name will be resolved by the DNS name in gvproxy, setting this to none has no effect. This option does not change the gvproxy behavior. πŸ’€
Note: this config doesn't affect the actual network setup, it just tells Podman the IP address it should expect. Configuring an IP address here doesn't ensure that the container can actually reach the host using this IP address. It's a hint, not a promise, bestie 🫢

http_proxy=true

okay so this one is about proxy vibes ✨ When it's on, the default proxy environment variables get passed straight into the container. The ones that get passed in are: http_proxy, https_proxy, ftp_proxy, no_proxy, plus the upper case versions of all of those. The no_proxy option is the one you need when the host system is using a proxy but the container should not use a proxy. And heads up β€” if proxy environment variables get specified for the container in any other way, those override the values passed from the host. πŸ’…

init=false

Run an init inside the container that forwards signals and reaps processes. simple as that, bestie 🫢

init_path="/usr/libexec/podman/catatonit"

If this option isn't set, catatonit gets searched for in the directories listed under the helper_binaries_dir option. And honestly? It's recommended to just install catatonit there instead of configuring this option here. ✨

This is the path to the container-init binary, which forwards signals and reaps processes within containers. Note that the container-init binary will only be used when the --init for podman-create and podman-run is set.

interface_name=""

The default way to set interface names inside containers. When left undefined it defaults to the legacy pattern of ethX, where X is an integer. The options are:

  • device β€” uses the network_interface name from the network config as the interface name. Falls back to the ethX pattern if the network_interface is not set.

ipcns="shareable"

The default way to create a IPC namespace for the container. Options are:

  • host β€” share host IPC Namespace with the container.
  • none β€” create shareable IPC Namespace for the container without a private /dev/shm.
  • private β€” create private IPC Namespace for the container, other containers are not allowed to share it.
  • shareable β€” create shareable IPC Namespace for the container.

keyring=true

Indicates whether the container engines create a kernel keyring for use within the container. πŸ”‘

label=true

Indicates whether the container engine uses MAC(SELinux) container separation via labeling. This option is ignored on disabled systems, so don't stress if it's not doing anything for you. πŸŽ€

label_users=false

label_users indicates whether to enforce confined users in containers on SELinux systems. This option causes containers to maintain the current user and role field of the calling process. By default SELinux containers run with the user system_u, and the role system_r.

log_driver=""

Logging driver for the container. Currently available options are k8s-file, journald, none and passthrough, with json-file aliased to k8s-file for scripting compatibility. The journald driver is used by default if the systemd journal is readable and writable. Otherwise, the k8s-file driver is used. iykyk 🌸

log_path=""

Default path for container logs to be stored in. When empty, logs will be stored in the container's default storage and removed when the container is removed. A subdirectory named with the container ID will be created under the specified path, and the log file will have the default name ctr.log within that directory. This option can be overridden by the --log-opt flag.

log_size_max=-1

Maximum size allowed for the container's log file. Negative numbers indicate that no size limit is imposed. If it's positive, it must be >= 8192 to match/exceed conmon's read buffer. The file is truncated and re-opened so the limit is never exceeded. no cap, it just keeps getting trimmed πŸ”₯

log_tag=""

Default format tag for container log messages. This is useful for creating a specific tag for container log messages. Container log messages default to using the truncated container ID as a tag.

mounts=[]

List of mounts. Specified as "type=TYPE,source=,destination=,"

Example:

[
"type=bind,source=/var/lib/foobar,destination=/var/lib/foobar,ro",
]

netns=""

Default way to create a NET namespace for the container. The option is mapped to the --network argument for the podman commands, and it accepts the same values as that option. For example it can be set to bridge, host, none, pasta and more β€” see the podman-create(1) manual for all available options (https://docs.podman.io/en/latest/markdown/podman-create.1.html#network-mode-net). πŸ¦‹

no_hosts=false

Do not modify the /etc/hosts file in the container. Podman assumes control over the container's /etc/hosts file by default; refer to the --add-host CLI option for details. To disable this, either set this config to true, or use the functionally identical --no-hosts CLI option.

oom_score_adj=0

Tune the host's OOM preferences for containers (accepts values from -1000 to 1000). 😭 please tune responsibly

pidns="private"

Default way to create a PID namespace for the container. Options are:

  • private β€” create private PID Namespace for the container.
  • host β€” share host PID Namespace with the container.

pids_limit=1024

Maximum number of processes allowed in a container. 0 indicates that no limit is imposed. literally the bouncer at the club of process counts πŸ’…

prepare_volume_on_create=false

Copy the content from the underlying image into the newly created volume when the container is created instead of when it is started. If false, the container engine will not copy the content until the container is started. Setting it to true may have negative performance implications β€” so like, know what you're signing up for, bestie ⚠️

privileged=false

Give extended privileges to all containers. A privileged container turns off the security features that isolate the container from the host. Dropped Capabilities, limited devices, read-only mount points, Apparmor/SELinux separation, and Seccomp filters are all disabled. Due to the disabled security features, the privileged field should almost never be set as containers can easily break out of confinement. πŸ’€

Containers running in a user namespace (e.g., rootless containers) cannot have more privileges than the user that launched them. so no, this doesn't magically make you root-root. periodt.

read_only=true|false

Run all containers with root file system mounted read-only. Set to false by default.

seccomp_profile="/usr/share/containers/seccomp.json"

Path to the seccomp.json profile which is used as the default seccomp profile for the runtime. πŸŽ€

shm_size="65536k"

Size of /dev/shm. The format is <number><unit>. number must be greater than 0. Unit is optional and can be: b (bytes), k (kilobytes), m (megabytes), or g (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses 65536k.

tz=""

Set timezone in container. Takes IANA timezones as well as local, which sets the timezone in the container to match the host machine. If not set, then containers will run with the time zone specified in the image. 🌍

Examples:

tz="local"
tz="America/New_York"

umask="0022"

Sets umask inside the container.

userns="host"

Default way to create a USER namespace for the container. Options are:

  • private β€” create private USER Namespace for the container, without adding any UID mappings.
  • host β€” share host USER Namespace with the container. Root in the container is mapped to the host user UID.
  • auto β€” automatically create a USER namespace with a unique mapping.
  • keep-id β€” like private, but container UIDs are mapped to the host user's subordinate UIDs listed in /etc/subuid, and the current user's UID:GID are mapped to the same values in the container.
  • no-map β€” like keep-id, but the current user's UID:GID does not map to any UID:GID inside the container.

utsns="private"

Default way to create a UTS namespace for the container. Options are:

  • private β€” create private UTS Namespace for the container.
  • host β€” share host UTS Namespace with the container.

volumes=[]

List of volumes. Specified as "directory-on-host:directory-in-container:options".

Example: "/db:/var/lib/db:ro". πŸ“

🌐 NETWORK TABLE 🌐

Okay so the network table is where all the container-network management settings live. Buckle up bestie, there's a bunch πŸ’…

  • network_backend="" β€” this picks what network driver gets used to set up and tear down container networks. The only supported value is "netavark", and an empty string defaults to "netavark". So yeah, it's netavark, it's always netavark 🫢
  • netavark_plugin_dirs=[] β€” a list of directories that will be searched for netavark plugins. The default list is:
netavark_plugin_dirs = [
  "/usr/local/libexec/netavark",
  "/usr/libexec/netavark",
  "/usr/local/lib/netavark",
  "/usr/lib/netavark",
]
  • default_network="podman" β€” the name of the default network as seen in podman network ls. Heads up: this option only affects the network assignment when the bridge network mode is selected, i.e. --network bridge. It's the default for rootful containers but not rootless. If you wanna change the default network mode, use the netns option under the [containers] table instead. πŸ“
⚠️ Note: this should not be changed while you have any containers using this network. Like, seriously, don't.
  • default_subnet="10.88.0.0/16" β€” the subnet to use for the default network (the one named above in default_network).
⚠️ Note: this should not be changed if any containers are currently running on the default network.
  • default_subnet_pools=[] β€” DefaultSubnetPools is a list of subnets and size, used to allocate subnets automatically for podman network create. It iterates through the list and picks the first free subnet with the given size. This is only used for ipv4 subnets β€” ipv6 subnets are always assigned randomly, no cap. ✨

The default list is (10.89.0.0-10.255.255.0/24):

default_subnet_pools = [
  {"base" = "10.89.0.0/16", "size" = 24},
  {"base" = "10.90.0.0/15", "size" = 24},
  {"base" = "10.92.0.0/14", "size" = 24},
  {"base" = "10.96.0.0/11", "size" = 24},
  {"base" = "10.128.0.0/9", "size" = 24},
]
  • default_rootless_network_cmd="pasta" β€” configures which rootless network program to use by default. The only valid option is pasta (which is, of course, the default) 🍝
  • rootless_port_forwarder="rootlessport" β€” selects the port forwarding mechanism for rootless bridge networks. Valid options are rootlessport (the default) and pasta. rootlessport uses a userspace TCP/UDP proxy. pasta uses pasta's control socket to add port forwarding rules via kernel splice, which preserves the original source IP address inside the container. The pasta option is experimental and subject to change β€” so like, use it knowing it might shift under you πŸ™ˆ
🚨 Important: this option must only be changed when no containers are running. Switching while containers are active leads to port-forwarding rules being leaked or cleanup failures, because the running netns was created with the previous setting. Not a vibe.
  • network_config_dir="/etc/containers/networks" β€” path to the directory where network configuration files live. The default is "/etc/containers/networks" as root, and "$graphroot/networks" as rootless.
  • firewall_driver="" β€” the firewall driver to be used by netavark. The default is empty, which means netavark will pick one accordingly. Currently supported drivers are "nftables", "none" (no firewall rules will be created) and "firewalld" β€” and btw firewalld is experimental at the moment and not recommended outside of testing πŸ’€
  • dns_bind_port=53 β€” port to use for the dns forwarding daemon with netavark in rootful bridge mode and dns enabled. Using an alternate port might be useful if other dns services should run on the machine.
  • pasta_options = [] β€” a list of default pasta options that should be used running pasta. It accepts the pasta cli options β€” see pasta(1) for the full list of options πŸ‘‘
  • default_host_ips=[] β€” the default host IPs to bind published container ports to when no host IP is explicitly specified in the -p flag (e.g., -p 8000:8000). If empty, the default behavior is to bind to all network interfaces (0.0.0.0 for IPv4 and :: for IPv6). If multiple IPs are specified, separate port mapping for each of the specified IP would be created. For instance, setting this to ["127.0.0.1", "::1"] and port specified as -p 8080:80 will result in two port mappings in podman: 127.0.0.1:8080:80 and [::1]:8080:80. Note that explicitly specifying a host IP in the -p flag (e.g., -p 192.168.1.10:8000:8000) will always override this default πŸŽ€

βš™οΈ ENGINE TABLE βš™οΈ

The engine table is where the config options used to set up container engines like Podman and Buildah hang out. Main character energy, honestly πŸ‘‘

  • active_service="" β€” name of destination for accessing the Podman service. See the SERVICE DESTINATION TABLE below (iykyk, it's coming).
  • add_compression=[] β€” list of compression algorithms. If set, it makes sure that the requested compression variant for each platform is added to the manifest list, keeping the original instance intact in the same manifest list, on every manifest push. Supported values are gzip, zstd and zstd:chunked. Heads up: zstd:chunked is incompatible with encrypting images, and will be treated as zstd with a warning in that case.
πŸ“Œ Note: this is different from compression_format, which allows users to select a default compression format for push and manifest push, while add_compression is limited to manifest push and allows users to append new instances to the manifest list with the specified compression algorithms in add_compression for each platform.
  • cgroup_manager="systemd" β€” the cgroup management implementation used for the runtime. Supports cgroupfs and systemd.
  • compat_api_enforce_docker_hub=true β€” enforce using docker.io for completing short names in Podman's compatibility REST API. Note that this will ignore unqualified-search-registries and short-name aliases defined in containers-registries.conf(5).
  • compose_providers=[] β€” specify one or more external providers for the compose command. The first found provider is used for execution. Can be an absolute and relative path or a (file) name.
  • compose_warning_logs=true β€” emit logs on each invocation of the compose command indicating that an external compose provider is being executed.
  • conmon_env_vars=[] β€” environment variables to pass into Conmon.
  • conmon_path=[] β€” paths to search for the conmon container manager binary. If the paths are empty or no valid path was found, then the $PATH environment variable will be used as the fallback. The default list is:
conmon_path=[
    "/usr/libexec/podman/conmon",
    "/usr/local/libexec/podman/conmon",
    "/usr/local/lib/podman/conmon",
    "/usr/bin/conmon",
    "/usr/sbin/conmon",
    "/usr/local/bin/conmon",
    "/usr/local/sbin/conmon",
    "/run/current-system/sw/bin/conmon",
]
  • detach_keys="ctrl-p,ctrl-q" β€” keys sequence used for detaching a container. Specify the keys sequence used to detach a container. Format is a single character [a-Z] or a comma separated sequence of ctrl-<value>, where <value> is one of: a-z, @, ^, [, \, ], ^ or _. Specifying "" disables this feature. 🫢
  • enable_port_reservation=true β€” determines whether the engine will reserve ports on the host when they are forwarded to containers. When enabled, when ports are forwarded to containers, they are held open by conmon as long as the container is running, ensuring that they cannot be reused by other programs on the host. However β€” and this is the tradeoff β€” this can cause significant memory usage if a container has many ports forwarded to it. Disabling this can save memory 🌸
  • env=[] β€” environment variables to be used when running the container engine (e.g., Podman, Buildah). For example "MYVAR=value". These environment variables will not be used within the container. Set the env section under the [containers] table if you want to set environment variables for the container, bestie.
πŸ“Œ Note: when using this to set http proxy variables, they might get leaked into the container depending on if http_proxy (under the [containers] table) is set to true (default) or false.
  • events_logfile_path="" β€” define where event logs will be stored, when events_logger is "file".
  • events_logfile_max_size="1m" β€” sets the maximum size for events_logfile_path. The unit can be b (bytes), k (kilobytes), m (megabytes) or g (gigabytes). The format for the size is <number><unit>, e.g., 1b or 3g. If no unit is included then the size will be in bytes. When the limit is exceeded, the logfile will be rotated and the old one will be deleted. If the maximum size is set to 0, then no limit will be applied, and the logfile will not be rotated. πŸ—‚οΈ
  • events_logger="journald" β€” the default method to use when logging events. The default method is different based on the platform that Podman is being run upon. To determine the current value, use this command:
podman info --format {{.Host.EventLogger}}

Valid values are: file, journald, and none.

  • events_container_create_inspect_data=true|false β€” creates a more verbose container-create event which includes a JSON payload with detailed information about the container. Set to false by default.
  • healthcheck_events=true|false β€” whether Podman should log healthcheck events. With many running healthchecks on a short interval, Podman will spam the event log a lot, as it generates an event for each single healthcheck run. Because this event is optional and only useful to external consumers that may want to know when a healthcheck is run or failed, users can turn it off by setting it to false. Default is true πŸ’–
  • helper_binaries_dir=["/usr/libexec/podman", ...] β€” a list of directories which are used to search for helper binaries. The following binaries are searched in these directories:
    • aardvark-dns
    • catatonit
    • netavark
    • pasta

Podman machine uses it for these binaries:

  • gvproxy
  • qemu
  • vfkit

The default paths on Linux are:

  • /usr/local/libexec/podman
  • /usr/local/lib/podman
  • /usr/libexec/podman
  • /usr/lib/podman

The default paths on macOS are:

  • /usr/local/opt/podman/libexec
  • /opt/homebrew/bin
  • /opt/homebrew/opt/podman/libexec
  • /usr/local/bin
  • /usr/local/libexec/podman
  • /usr/local/lib/podman
  • /usr/libexec/podman
  • /usr/lib/podman

The default path on Windows is:

  • C:\Program Files\RedHat\Podman
  • hooks_dir=["/etc/containers/oci/hooks.d", ...] β€” path to the OCI hooks directories for automatically executed hooks.
  • cdi_spec_dirs=["/etc/cdi", "/var/run/cdi", ...] β€” directories to scan for CDI Spec files πŸ¦‹
  • image_default_format="oci"|"v2s2"|"v2s1" β€” manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building container images. By default images pulled and pushed match the format of the source image. Building/committing defaults to OCI.
πŸ“Œ Note: image_build_format is deprecated. Like, it's giving legacy, don't use it.
  • image_default_transport="docker://" β€” the transport method that gets used by default when you pull or push images. That's it, that's the vibe. πŸ’…
  • image_parallel_copies=0 β€” max number of image layers getting copied (pulled/pushed) at the same time. If you don't set this field at all, it just falls back to the containers/image defaults. (6)
  • image_volume_mode="bind" β€” tells container engines how to deal with the built-in image volumes. options are:
    • bind: an anonymous named volume gets created and mounted into the container.
    • tmpfs: the volume is mounted onto the container as a tmpfs, which lets users create content that vanishes when the container is stopped. literally ghost content πŸ‘»
    • ignore: all volumes are just ignored and nothing happens.
  • infra_command="/pause" β€” the infra (pause) container image command for pod infra containers. when a pod runs, a /pause process gets started inside a container to hold open the namespaces tied to that pod. this container does nothing except sleep, reserving the pod's resources for the pod's whole lifetime. icon behavior honestly 😴
  • infra_image="" β€” the infra (pause) container image for pod infra containers. same deal: when a pod runs, a pause process gets started in a container to hold open the namespaces associated with the pod, and this container does nothing but sleep, reserving the pod's resources for the lifetime of the pod. by default container engines run a built-in container using the pause executable. if you want to override it, specify an image to pull.
  • kube_generate_type="pod" β€” default Kubernetes kind/specification of the kubernetes yaml generated by the podman kube generate command. possible options are pod and deployment.
  • lock_type="shm" β€” the locking mechanism to use. valid values are "shm" and "file". change the default only if you're 100% sure what you're doing β€” generally "file" is only useful on platforms where cgo isn't available for the faster "shm" lock type. heads up: you may need to run podman system renumber after you change the lock type. 🫢
  • multi_image_archive=false β€” allows creating archives (like tarballs) with more than one image in them. some container engines, Podman included, interpret additional arguments as tags for one image and hence don't store more than one image. this option lets you alter that default behavior.
  • namespace="" β€” default engine namespace. if the engine is joined to a namespace, it only sees containers and pods created in that same namespace, and new containers and pods get created in that namespace. the default namespace is "", which corresponds to no namespace. when no namespace is set, all containers and pods are visible. πŸ‘€
  • no_pivot_root=false β€” whether to use chroot instead of pivot_root in the runtime.
  • num_locks=2048 β€” number of locks available for containers, pods, and volumes. each created container, pod, or volume consumes one lock. locks get recycled and can be reused after the associated container, pod, or volume is removed. default number available is 2048. if you change this, a lock renumbering must be performed using the podman system renumber command. no skipping that step bestie πŸ’€
  • pod_exit_policy="continue" β€” sets the exit policy of the pod when the last container exits. supported policies are:
    • continue β€” the pod continues running when the last container exits. used by default.
    • stop β€” the pod is stopped when the last container exits. used in play kube.
  • pull_policy="always"|"missing"|"never" β€” pull the image before running or creating a container. the default is missing.
    • missing: attempt to pull the latest image from the registries listed in registries.conf if a local image doesn't exist. raises an error if the image isn't in any listed registry and isn't present locally.
    • always: pull the image from the first registry it's found in, as listed in registries.conf. raises an error if it's not found in the registries, even if the image is present locally. harsh but fair ✨
    • never: don't pull the image from the registry, use only the local version. raises an error if the image isn't present locally.
  • remote = false β€” indicates whether the application should be running in remote mode. this flag modifies the --remote option on container engines. setting the flag to true will default podman --remote=true for access to the remote Podman service. remote queen behavior πŸ¦‹
  • retry = 3 β€” number of times to retry pulling/pushing images in case of failure.
  • retry_delay = "" β€” delay between retries in case pulling/pushing an image fails. if set, container engines retry at the set interval; otherwise they delay 2 seconds and then exponentially back off.
  • runtime="" β€” the default OCI specific runtime in runtimes that gets used by default. must refer to a member of the runtimes table. the default runtime gets searched for on the system using this priority: "crun", "runc", "runj", "kata", "runsc", "ocijail".
  • runtime_supports_json=["crun", "crun-vm", "runc", "kata", "runsc", "youki", "krun"] β€” the list of OCI runtimes that support --format=json.
  • runtime_supports_kvm=["kata", "krun"] β€” the list of OCI runtimes that support running containers with KVM separation.
  • runtime_supports_nocgroups=["crun", "crun-vm", "krun"] β€” the list of OCI runtimes that support running containers without CGroups.
  • image_copy_tmp_dir="/var/tmp" β€” default location for storing temporary container image content. can be overridden with the TMPDIR environment variable. if you specify "storage", then the location of the container/storage tmp directory gets used. if set, it's the user's responsibility to clean up storage β€” configure tmpfiles.d(5) to do the cleanup. πŸ”₯
  • service_timeout=5 β€” number of seconds to wait without a connection before the podman system service times out and exits.
  • static_dir="/var/lib/containers/storage/libpod" β€” directory for persistent libpod files (database, etc). by default this gets configured relative to where containers/storage stores containers.
  • stop_timeout=10 β€” number of seconds to wait for a container to exit before sending the kill signal.
  • exit_command_delay=300 β€” number of seconds to wait for the API process for the exec call before sending the exit command, mimicking the Docker behavior of 5 minutes (in seconds).
  • tmp_dir="/run/libpod" β€” the path to a temporary directory for storing per-boot container stuff. must be a tmpfs (wiped after reboot).
  • volume_path="/var/lib/containers/storage/volumes" β€” directory where named volumes get created using the default volume driver. by default this gets configured relative to where containers/storage stores containers. this convention is followed by the default volume driver, but other drivers may not follow it.
  • chown_copied_files=true β€” determines whether files copied into a container will have their ownership changed to the primary uid/gid of the container.
  • compression_format="gzip" β€” the compression format to use when pushing an image. supported values are: gzip, zstd and zstd:chunked. this field is ignored when pushing images to the docker-daemon and docker-archive formats. it's also ignored when the manifest format is set to v2s2. zstd:chunked is incompatible with encrypting images, and gets treated as zstd with a warning in that case. 😭
  • compression_level="5" β€” the compression level to use when pushing an image. valid options depend on the compression format used. for gzip, valid options are 1-9, with a default of 5. for zstd, valid options are 1-20, with a default of 3.

🌸 SERVICE DESTINATION TABLE 🌸

the engine.service_destinations table holds the config options used to set up remote connections to the podman service for the podman API. remote besties only πŸ’–

[engine.service_destinations.{name}] URI to access the Podman service:

uri="ssh://user@production.example.com/run/user/1001/podman/podman.sock"

Example URIs, so you can see the whole range, no cap:

  • rootless local β€” unix:///run/user/1000/podman/podman.sock
  • rootless remote β€” ssh://user@engineering.lab.company.com/run/user/1000/podman/podman.sock
  • rootful local β€” unix:///run/podman/podman.sock
  • rootful remote β€” ssh://root@10.10.1.136:22/run/podman/podman.sock
  • tcp/tls remote β€” tcp://10.10.1.136:9443
  • identity="~/.ssh/id_rsa β€” path to a file containing the ssh identity key.
  • tls_cert="/path/to/certs/podman/tls.crt" β€” path to a PEM file containing the TLS client certificate.
  • tls_key="/path/to/certs/podman/tls.key" β€” path to a PEM file containing the TLS client certificate private key.
  • tls_ca="/path/to/certs/podman/ca.crt" β€” path to a PEM file containing the TLS certificate authority (CA) bundle.

[engine.runtimes_flags]

lists of default runtime flags for each valid OCI runtime (crun, runc, kata, runsc, krun, etc). to list the supported flags, please consult the documentation of the selected container runtime. iykyk πŸ“–

[engine.volume_plugins]

a table of all the enabled volume plugins on the system. volume plugins can be used as the backend for Podman named volumes. individual plugins are specified below, as a map of the plugin name (what the plugin will be called) to its path (filepath of the plugin's unix socket). obsessssed with a good plugin socket 🧚

[engine.platform_to_oci_runtime]

lets end users switch the OCI runtime on the basis of the container image's platform string. the following config field contains a map of platform/string = oci_runtime.


πŸŽ€ SECRET TABLE πŸŽ€

the secret table contains settings for the configuration of the secret subsystem. keep it on the dl 🀫

  • driver=file β€” name of the secret driver to be used. currently valid values are:
    • file
    • pass

[secrets.opts]

the driver specific options object. πŸ’œ

πŸ–₯️ MACHINE TABLE ✨

okay so the machine table is where all the podman machine VM settings live β€” think of it as the little instruction card your VM gets handed at birth 🍼

  • cpus=1 β€” how many CPUs a machine gets created with. one (1) singular brain cell by default, bless.
  • disk_size=10 β€” the size of the disk in GB that gets created when you init a podman-machine VM. ten whole gigabytes, live a little πŸ’…
  • image="docker://quay.io/podman/machine-os" β€” the image used when creating a new VM with podman machine init. it can be a registry with a bootable OCI artifact, a download URL, or a local path, so pick your fighter πŸŽ€ The registry target has to be in the form docker://registry/repo/image:version. and listen β€” container engines translate the URIs $OS and $ARCH into the native OS and ARCH, so a URI like "https://example.com/$OS/$ARCH/foobar.ami" would literally become "https://example.com/linux/amd64/foobar.ami" on a Linux AMD machine. iconic behavior fr. if you don't specify anything, the default Podman machine image gets used.
  • memory=2048 β€” memory in MB that a machine is created with.
  • user="" β€” the username to use and create on the podman machine OS, so you get rootless container access 🫢 The default value is user. On Linux/Mac the default is core.
  • volumes=["$HOME:$HOME"] β€” host directories that get mounted as volumes into the VM by default. environment variables like $HOME work as well as complete paths, for both the source and the destination. and you can slap an optional third field :ro on there to tell the container engines to mount the volume readonly β€” protective queen behavior πŸ”’

and just so you know, on Mac the default volumes are:

[ "/Users:/Users", "/private:/private", "/var/folders:/var/folders" ]
  • provider="" β€” the virtualization provider used for running a podman-machine VM. an empty value is interpreted as the default provider for the current host OS.

here's the rundown, since the original is a whole table and tables don't fit in my group chat:

  • Linux β€” default "" (qemu), optional: None
  • Windows β€” default "" ("wsl": Windows Subsystem for Linux), optional: "hyperv" (Windows Server Virtualization)
  • Mac β€” default "" ("libkrun": Launch machine via libkrun platform, optimized for sharing GPU with the machine), optional: "applehv" (Apple Hypervisor)
  • rosetta=false β€” Rosetta supports running x86_64 Linux binaries on a Podman machine on Apple silicon 🍎 The default value is false. and ngl this one is picky: supported on AppleHV(arm64) machines only.
  • import_native_ca=false β€” imports the host's trusted CA certificates into the machine. when it's set to true, the certificates from the host system get imported during machine startup, which lets containers running in the machine trust the same Certificate Authorities as the host OS. The default value is false. trust chain, but make it slay πŸ”

🌾 FARMS TABLE 🌾

the farms table holds config options used to group up remote connections into farms, and those farms are what get used when you send out builds to different machines in a farm via podman buildfarm 🚜

  • default="" β€” the default farm to use when farming out builds.
  • [farms.list] β€” a map of farms created, where the key is the farm name and the value is the list of system connections. iykyk, key = name, value = connection list.

🐚 PODMANSH TABLE 🐚

the podmansh table is, bestie, exactly what it sounds like β€” the config options used by podmansh:

  • shell="/bin/sh" β€” the shell to spawn in the container. The default value is /bin/sh.
  • container="podmansh" β€” the name of the container that podmansh joins. The default value is podmansh.
  • timeout=0 β€” number of seconds to wait for podmansh logins. this value is favoured over the deprecated field engine.podmansh_timeout if it's set. The default value is 30.
heads up 🫢 β€” engine.podmansh_timeout is deprecated, so if timeout is set, it wins. periodt.

πŸ‘€ SEE ALSO πŸ‘€

go read these next, they're the friend group of this page πŸ’–


and that's a wrap on containers.conf(5), bestie!! πŸŽ€ you made it through the whole thing, i'm so proud of you 🫢 this gem comes to you from the Container package, and it's containers.conf(5) β€” go forth and configure responsibly, mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from