Devsy
Tutorials

Podman Provider Setup

Podman is a built-in Devsy provider. It runs containers without a background daemon and is OCI-compatible, so most devcontainer.json files work unchanged. See known differences for the exceptions.

This page covers installing Podman, adding it as a provider, and starting a workspace.

Install Podman

Linux

Use your package manager:

sudo apt-get install -y podman   # Debian / Ubuntu
sudo dnf install -y podman       # Fedora / RHEL / CentOS
sudo pacman -S podman            # Arch

macOS

brew install podman
podman machine init
podman machine start

Podman Desktop also works.

Windows

Podman runs inside WSL2.

  1. In PowerShell as Administrator, run wsl --install and restart when asked.

  2. In your WSL terminal, run sudo apt-get update && sudo apt-get install -y podman.

  3. Start the rootless API socket. If your distro has systemd:

    systemctl --user enable --now podman.socket
    ls -la $XDG_RUNTIME_DIR/podman/podman.sock

    Without systemd, start the service so it survives closing the terminal:

    setsid nohup podman system service --time=0 unix://$XDG_RUNTIME_DIR/podman/podman.sock >/tmp/podman-service.log 2>&1 &
  4. Note the socket path. You need it for PODMAN_HOST below.

Add the provider

devsy provider add podman

Options

OptionDefaultDescription
PODMAN_PATHpodmanPath to the podman binary, if it is not on PATH.
PODMAN_HOSTunsetPodman socket or TCP address. Required on Windows, for example unix:///run/user/<UID>/podman/podman.sock, where <UID> is the output of id -u.
PODMAN_ELEVATIONnoneRun podman through pkexec, sudo or doas to reach a rootful socket the current user cannot access. Leave it as none for rootless Podman. pkexec needs a desktop session with a polkit agent, so use sudo or doas on headless hosts.
INACTIVITY_TIMEOUTunsetStop the container after this idle time, for example 10m or 1h.

Set options when adding the provider, or later:

devsy provider add podman -o PODMAN_PATH=/usr/local/bin/podman
devsy provider set podman --option PODMAN_PATH=/usr/local/bin/podman
devsy provider get podman

Rootless and rootful

Rootless is the default and the recommended setup. Containers run as your user. Use rootful only when a container must bind-mount root-owned paths or needs network setups such as macvlan.

On macOS and Windows, switch the Podman machine mode:

podman machine init --rootful my-rootful-machine   # a new machine
podman machine set --rootful                       # change the existing machine
podman machine stop && podman machine start

Switching mode does not delete images, containers or volumes. They are hidden while the other mode is active and return when you switch back.

On Linux, to reach a rootful socket without running everything as root, set PODMAN_ELEVATION to sudo or doas.

After switching a macOS or Windows machine to rootful, set PODMAN_HOST to the rootful socket. Run podman machine inspect and read .ConnectionInfo.PodmanSocket.Path. Keep PODMAN_ELEVATION as none, because the machine connection is already authenticated.

Start a workspace

devsy workspace up --provider podman --id my-workspace https://github.com/my-org/my-repo
devsy workspace ssh my-workspace

Troubleshooting

Socket not found or permission denied

Devsy cannot reach the Podman socket. On macOS and Windows, check that the machine is running with podman machine list, and start it with podman machine start. On Linux, check the user socket:

systemctl --user status podman.socket

If the socket path is not the default, set it:

devsy provider set podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/podman.sock

Known differences

Dockerfile builds

Podman builds with Buildah, not BuildKit. BuildKit-only syntax, such as RUN --mount=type=cache under the buildkit frontend, can fail. Remove the # syntax=docker/dockerfile:1 line or rewrite those steps.

Compose

podman compose hands off to an external provider: the podman-compose package or a standalone docker-compose binary. Install one:

sudo apt-get install -y podman-compose

The docker-compose-plugin package does not work here. It adds the docker compose subcommand to the Docker CLI and pulls in Docker. Check what is available:

podman compose version

Use podman compose instead of docker-compose in your scripts.

On this page