Jump to content

Podman: Difference between revisions

From NixOS Wiki
imported>Eoli3n
No edit summary
Malix (talk | contribs)
enhance: headers
 
(36 intermediate revisions by 27 users not shown)
Line 1: Line 1:
Podman can run rootless docker containers
[https://podman.io/ Podman] can run rootless containers and be a drop-in replacement for [[Docker]]


== Install podman ==
== 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.
  };
};


<syntaxHighlight lang="nix">
users.users.<USERNAME> = { # replace `<USERNAME>` with the actual username
{ pkgs, ... }:
  extraGroups = [
{
    "podman"
  environment.systemPackages = with pkgs; [ podman runc conmon slirp4netns fuse-overlayfs ];
  ];
}
}|name=/etc/nixos/configuration.nix|lang=nix}}
</syntaxHighlight>
A reboot or re-login might be required for the permissions to take effect after applying changes
 
== Tips and tricks ==
 
=== podman-compose ===
<code>podman-compose</code> is a drop-in replacement for <code>docker-compose</code>
 
See [https://docs.podman.io/en/stable/markdown/podman-compose.1.html the official documentation]
 
=== With ZFS ===


== Configure subuid/subgid for your user ==
Rootless can't use [[ZFS]] directly but the overlay needs POSIX ACL enabled for the underlying ZFS filesystem, ie., <code>acltype=posixacl</code>


<syntaxHighlight lang="nix">
Best to mount a dataset under <code>/var/lib/containers/storage</code> with property <code>acltype=posixacl</code>.
{
  users.users.username.subUidRanges = [{ startUid = 100000; count = 65536; }];
  users.users.username.subGidRanges = [{ startGid = 100000; count = 65536; }];
}


</syntaxHighlight>
=== Within nix-shell ===
From https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947 :<blockquote>{{File|3={ pkgs ? import <nixpkgs> {} }:


== Create configuration files ==
let


<syntaxHighlight lang="nix">
  # To use this shell.nix on NixOS your user needs to be configured as such:
{
   # users.extraUsers.adisbladis = {
   environment.etc."containers/policy.json" = {
  #  subUidRanges = [{ startUid = 100000; count = 65536; }];
    mode="0644";
  #  subGidRanges = [{ startGid = 100000; count = 65536; }];
    text=''
   # };
      {
        "default": [
          {
            "type": "insecureAcceptAnything"
          }
        ],
        "transports":
          {
            "docker-daemon":
              {
                "": [{"type":"insecureAcceptAnything"}]
              }
          }
      }
    '';
   };


   environment.etc."containers/registries.conf" = {
   # Provides a script that copies required files to ~/
     mode="0644";
  podmanSetupScript = let
    text=''
     registriesConf = pkgs.writeText "registries.conf" ''
       [registries.search]
       [registries.search]
       registries = ['docker.io', 'quay.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 do such using [[Home Manager]] manually:
{{File|3=# Global `/etc/containers/registries.conf`
environment.etc."containers/registries.conf".text = ''
  [registries.search]
  registries = ['docker.io']
'';
# 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]]

Latest revision as of 15:39, 1 October 2025

Podman can run rootless containers and be a drop-in replacement for Docker

Setup

❄︎ /etc/nixos/configuration.nix
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"
  ];
}

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 drop-in replacement for docker-compose

See the official documentation

With ZFS

Rootless can't use ZFS directly but the overlay needs POSIX ACL enabled for the underlying ZFS filesystem, ie., acltype=posixacl

Best to mount a dataset under /var/lib/containers/storage with property acltype=posixacl.

Within nix-shell

From https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947 :

❄︎ podman-shell.nix
{ 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 {

  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}
  '';

}

Note that rootless podman requires newuidmap (from shadow). If you're not on NixOS, this cannot be supplied by the Nix package 'shadow' since setuid/setgid programs are not currently supported by Nix.

Containers as systemd services

{
  virtualisation.oci-containers.backend = "podman";
  virtualisation.oci-containers.containers = {
    container-name = {
      image = "container-image";
      autoStart = true;
      ports = [ "127.0.0.1:1234:1234" ];
    };
  };
}

Cross-architecture containers using binfmt/qemu

boot.binfmt = {
  emulatedSystems = [ "aarch64-linux" ];
  preferStaticEmulators = true; # required to work with podman
};
$ podman run --arch arm64 'docker.io/alpine:latest' arch
aarch64

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 do such using Home Manager manually:

❄︎ ~/.config/home-manager/home.nix
# Global `/etc/containers/registries.conf`
environment.etc."containers/registries.conf".text = ''
  [registries.search]
  registries = ['docker.io']
'';

# User-scoped `~/.config/containers/registries`
xdg.configFile."containers/registries.conf".text = ''
  [registries.search]
  registries = ['docker.io']
'';