Podman: Difference between revisions

H7x4 (talk | contribs)
Add a few links
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.
 
(12 intermediate revisions by 8 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]]


== Install and configure podman with NixOS service configuration ==
== 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 ==


<syntaxhighlight lang="nix">
=== '''podman compose''' ===
{ pkgs, ... }:
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.
{
  # Enable common container config files in /etc/containers
  virtualisation.containers.enable = true;
  virtualisation = {
    podman = {
      enable = true;


      # Create a `docker` alias for podman, to use it as a drop-in replacement
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.
      dockerCompat = true;


      # Required for containers under podman-compose to be able to talk to each other.
To change the default behavior or have a custom installation path for your provider of choice: <syntaxhighlight lang="nix">{
      defaultNetwork.settings.dns_enabled = true;
  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.sessionVariables = {
    PODMAN_COMPOSE_PROVIDER = "/path/to/provider";
    PODMAN_COMPOSE_WARNING_LOGS = false;
   };
   };
  # Useful other development tools
  environment.systemPackages = with pkgs; [
    dive            # look into docker image layers
    podman-tui      # status of containers in the terminal
    #docker-compose # start group of containers for dev
    podman-compose  # start group of containers for dev
  ];
}
}
</syntaxhighlight>
</syntaxhighlight>


=== podman-compose ===
=== With ZFS ===
<code>podman-compose</code> is a drop-in replacement for <code>docker-compose</code>
 
=== Using podman 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>
Rootless can't use [[ZFS]] directly but the overlay needs POSIX ACL enabled for the underlying ZFS filesystem, ie., <code>acltype=posixacl</code>
Line 39: Line 54:
Best to mount a dataset under <code>/var/lib/containers/storage</code> with property <code>acltype=posixacl</code>.
Best to mount a dataset under <code>/var/lib/containers/storage</code> with property <code>acltype=posixacl</code>.


== Use Podman within nix-shell ==
=== 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 = ['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 {


https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947
  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
  ];


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].
  shellHook = ''
    # Install required configuration
    ${podmanSetupScript}
  '';


== Run Podman containers as systemd services ==
}|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">
<syntaxHighlight lang="nix">
{
{
Line 60: Line 126:
</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:Software]]
[[Category:Server]]
[[Category:Server]]
[[Category:Container]]
[[Category:Container]]