Podman: Difference between revisions
imported>JohnAZoidberg No edit summary |
Giantdwarf (talk | contribs) Updated podman compose documentation. I essentially copied the official documentation from https://docs.podman.io/en/stable/markdown/podman-compose.1.html and modified the instructions to use nixos options instead of manual file edits. |
||
| (38 intermediate revisions by 29 users not shown) | |||
| Line 1: | Line 1: | ||
Podman can run rootless containers and be a drop-in replacement for Docker | [https://podman.io/ Podman] can run rootless containers and be a drop-in replacement for [[Docker]] | ||
== | == Setup == | ||
{{File|3=virtualisation = { | |||
containers.enable = true; | |||
podman = { | |||
enable = true; | |||
dockerCompat = true; | |||
defaultNetwork.settings.dns_enabled = true; # Required for containers under podman-compose to be able to talk to each other. | |||
}; | |||
}; | |||
users.users.<USERNAME> = { # replace `<USERNAME>` with the actual username | |||
extraGroups = [ | |||
"podman" | |||
]; | |||
};|name=/etc/nixos/configuration.nix|lang=nix}} | |||
< | {{Security Warning|Beware that the podman group membership is effectively equivalent to being root, just like with Docker! <br> Consider using rootless podman.}} | ||
A reboot or re-login might be required for the permissions to take effect after applying changes | |||
== Tips and tricks == | |||
=== '''podman compose''' === | |||
podman compose is a thin wrapper around an external compose provider such as [https://github.com/docker/compose docker-compose] or [https://github.com/containers/podman-compose podman-compose]. This means that <code>podman compose</code> is executing another tool that implements the compose functionality but sets up the environment in a way to let the compose provider communicate transparently with the local Podman socket. The specified options as well as the command and argument are passed directly to the compose provider. | |||
The default compose providers are <code>docker-compose</code> and <code>podman-compose</code>. If installed, <code>docker-compose</code> takes precedence since it is the original implementation of the Compose specification. | |||
< | To change the default behavior or have a custom installation path for your provider of choice: <syntaxhighlight lang="nix">{ | ||
{ | services.podman.settings.containers = { compose_providers = ["/path/to/provider"] }; | ||
}</syntaxhighlight>You may also set the <code>PODMAN_COMPOSE_PROVIDER</code> environment variable:<syntaxhighlight lang="bash">PODMAN_COMPOSE_PROVIDER="/path/to/provider" podman compose up -d</syntaxhighlight>or:<syntaxhighlight lang="nix">{ | |||
environment.sessionVariables = { | |||
PODMAN_COMPOSE_PROVIDER = "/path/to/provider"; | |||
}; | |||
}</syntaxhighlight>By default, <code>podman compose</code> will emit a warning saying that it executes an external command. This warning can be disabled by setting <code>compose_warning_logs</code> to false in <code>services.podman.settings.containers</code> or setting the <code>PODMAN_COMPOSE_WARNING_LOGS</code> environment variable to false.<syntaxhighlight lang="nix">{ | |||
services.podman.settings.containers = { | |||
compose_providers = ["/path/to/provider"]; | |||
compose_warning_logs = false; | |||
}; | |||
}</syntaxhighlight><syntaxhighlight lang="nix"> | |||
{ | { | ||
environment. | environment.sessionVariables = { | ||
PODMAN_COMPOSE_PROVIDER = "/path/to/provider"; | |||
PODMAN_COMPOSE_WARNING_LOGS = false; | |||
}; | |||
} | } | ||
</ | </syntaxhighlight> | ||
=== With ZFS === | |||
= | Rootless can't use [[ZFS]] directly but the overlay needs POSIX ACL enabled for the underlying ZFS filesystem, ie., <code>acltype=posixacl</code> | ||
< | Best to mount a dataset under <code>/var/lib/containers/storage</code> with property <code>acltype=posixacl</code>. | ||
< | === Within nix-shell === | ||
From https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947 :<blockquote>{{File|3={ pkgs ? import <nixpkgs> {} }: | |||
let | |||
# To use this shell.nix on NixOS your user needs to be configured as such: | |||
# users.extraUsers.adisbladis = { | |||
# subUidRanges = [{ startUid = 100000; count = 65536; }]; | |||
# subGidRanges = [{ startGid = 100000; count = 65536; }]; | |||
# }; | |||
}; | |||
# Provides a script that copies required files to ~/ | |||
podmanSetupScript = let | |||
registriesConf = pkgs.writeText "registries.conf" '' | |||
[registries.search] | [registries.search] | ||
registries = ['docker.io' | registries = ['docker.io'] | ||
[registries.block] | |||
registries = [] | |||
''; | ''; | ||
in pkgs.writeScript "podman-setup" '' | |||
#!${pkgs.runtimeShell} | |||
# Dont overwrite customised configuration | |||
if ! test -f ~/.config/containers/policy.json; then | |||
install -Dm555 ${pkgs.skopeo.src}/default-policy.json ~/.config/containers/policy.json | |||
fi | |||
if ! test -f ~/.config/containers/registries.conf; then | |||
install -Dm555 ${registriesConf} ~/.config/containers/registries.conf | |||
fi | |||
''; | |||
# Provides a fake "docker" binary mapping to podman | |||
dockerCompat = pkgs.runCommandNoCC "docker-podman-compat" {} '' | |||
mkdir -p $out/bin | |||
ln -s ${pkgs.podman}/bin/podman $out/bin/docker | |||
''; | |||
in pkgs.mkShell { | |||
buildInputs = [ | |||
dockerCompat | |||
pkgs.podman # Docker compat | |||
pkgs.runc # Container runtime | |||
pkgs.conmon # Container runtime monitor | |||
pkgs.skopeo # Interact with container registry | |||
pkgs.slirp4netns # User-mode networking for unprivileged namespaces | |||
pkgs.fuse-overlayfs # CoW for images, much faster than default vfs | |||
]; | |||
shellHook = '' | |||
# Install required configuration | |||
${podmanSetupScript} | |||
''; | |||
}|name=podman-shell.nix|lang=nix}}</blockquote>Note that rootless podman requires newuidmap (from shadow). If you're not on NixOS, this cannot be supplied by the Nix package 'shadow' since [https://nixos.org/manual/nix/unstable/expressions/derivations.html setuid/setgid programs are not currently supported by Nix]. | |||
=== Containers as systemd services === | |||
<syntaxHighlight lang="nix"> | |||
{ | |||
virtualisation.oci-containers.backend = "podman"; | |||
virtualisation.oci-containers.containers = { | |||
container-name = { | |||
image = "container-image"; | |||
autoStart = true; | |||
ports = [ "127.0.0.1:1234:1234" ]; | |||
}; | |||
}; | }; | ||
} | } | ||
</syntaxHighlight> | </syntaxHighlight> | ||
=== Cross-architecture containers using binfmt/qemu === | |||
<syntaxHighlight lang="nix"> | |||
boot.binfmt = { | |||
emulatedSystems = [ "aarch64-linux" ]; | |||
preferStaticEmulators = true; # required to work with podman | |||
}; | |||
</syntaxHighlight> | |||
<syntaxhighlight lang="console"> | |||
$ podman run --arch arm64 'docker.io/alpine:latest' arch | |||
aarch64 | |||
</syntaxhighlight> | |||
=== DevContainers === | |||
Using Podman, it is possible that the process of creation of DevContainers' containers to become stuck at the "Please select an image URL" step. | |||
To avoid this issue, you might restrict its registries configuration. | |||
You can change the global registries with:<syntaxhighlight lang="nix"> | |||
virtualisation.containers.registries.search = [ "docker.io" ]; | |||
</syntaxhighlight> | |||
For user-scoped registries you can do using [[Home Manager]] manually: | |||
{{File|3=# User-scoped `~/.config/containers/registries` | |||
xdg.configFile."containers/registries.conf".text = '' | |||
[registries.search] | |||
registries = ['docker.io'] | |||
'';|name=~/.config/home-manager/home.nix|lang=nix}} | |||
[[Category:Software]] | |||
[[Category:Server]] | |||
[[Category:Container]] | |||