podman

Activity, over time

Daily observations from the public event archive.

Attention

Daily stars & forks

Loading attention chart

Star accumulation

Cumulative stars

Loading star accumulation chart

Pull requests

Daily opens & merges

Loading pull requests chart

Conversations

Daily issues & comments

Loading conversations chart

Community

Daily accounts & reviews

Loading community chart

Releases

Daily releases

Loading releases chart

Mentions

6posts · 30d
Nov 30 posts
  1. No Docker Desktop? WSL2 + Podman on Windows: setup and the errors I hit Two ways to run containers on Windows without Docker Desktop, plus every red error message I met on the way. Here is the situation. Your laptop is locked down, Docker Desktop is not on the approved list (or the license is a "talk to finance" thing), and you still need to run docker build before lunch. Good news: you do not need Docker Desktop. Bad news: the two replacements each have their own little traps, and one of them quietly hands you root. TL;DR - Option 1: WSL2 + Docker Engine. Install Ubuntu in WSL, apt install docker.io, done. Feels exactly like Docker. Watch out for systemd and the docker group. - Option 2: Podman. No daemon, rootless by default, same commands (alias docker=podman). Watch out for low ports and the Docker named pipe. - Security gotcha: "fixing sudo" by joining the docker group gives you root-level power. Rootless Podman and real secrets beat that. !Two ways to run containers on Windows without Docker Desktop Table of contents - [1. Pick your path](#1-pick-your-path) - [2. Option 1 WSL2 and Docker Engine](#2-option-1-wsl2-and-docker-engine) - [3. Option 2 Podman on Windows](#3-option-2-podman-on-windows) - [4. The errors I hit and how to fix them](#4-the-errors-i-hit-and-how-to-fix-them) - [5. Security gotcha](#5-security-gotcha) - [6. Checklist](#6-checklist) - [Sources](#sources) 1. Pick your path Both options use WSL2 under the hood. The difference is who runs the containers. | | WSL2 + Docker Engine | Podman | |---|---|---| | Where it runs | Docker daemon inside your Ubuntu distro | A small Podman machine (a WSL2 distro) | | Daemon | Yes, dockerd running as root | No central daemon | | Default user | root daemon, you call it via sudo or the docker group | Rootless | | Commands | docker ... | podman ... (almost the same) | | You run it from | The Ubuntu shell | PowerShell, CMD or WSL | | Best for | "I want my Docker workflow back" | Locked-down or security-minded setups | My rule of thumb: if your team's scripts are full of docker compose and Docker-only flags, go with Option 1. If you mostly build and run images and your security team frowns at root daemons, go with Podman. 2. Option 1 WSL2 and Docker Engine This keeps your workflow almost identical to Docker Desktop. You just do the plumbing yourself. Step 1. Install WSL. Open PowerShell as administrator: wsl --install Restart the machine. You need Windows 10 version 2004 (build 19041) or newer, or Windows 11. By default this installs Ubuntu and sets new installs to WSL 2. Check it: wsl -l -v You want to see VERSION 2 next to your distro. Step 2. Install (or pick) a distro. Ubuntu is the default, but you can ask for it by name, and list the others: wsl --install -d Ubuntu wsl --list --online Step 3. Start Ubuntu. wsl -d Ubuntu Step 4. Install Docker Engine inside WSL (no Desktop): sudo apt update sudo apt install -y docker.io sudo systemctl enable docker sudo systemctl start docker Step 5. Test. sudo docker run hello-world If you see "Hello from Docker!", you have a working engine. Notice the sudo though. We will come back to that, because that is where people (me included) take a shortcut with a security price tag. Pros: same commands, same Dockerfiles, and an easy path to Minikube later. Cons: you manage the engine yourself, and it is a little less smooth than Desktop. Source: Install WSL 3. Option 2 Podman on Windows Podman is daemonless: there is no big root process waiting for orders. On Windows, Podman runs inside a "Podman machine", which is a WSL2 distro it manages for you. The podman command in PowerShell talks to it. Step 1. Install Podman. The official way is the Windows installer from the Podman GitHub releases page. The quick way is winget: winget install RedHat.Podman Close and reopen the terminal so podman.exe is on your PATH. Step 2. Create and start the Podman machine. podman machine init podman machine start If WSL is not installed yet, podman machine init offers to install it for you, reboots, and carries on after you log in. Nice, but do not be surprised by the reboot. Step 3. Test. podman run hello-world If a short image name like hello-world makes Podman ask which registry you mean, give it the full name: docker.io/library/hello-world. Step 4. Use your Docker muscle memory. podman build -t myapp . podman run myapp alias docker=podman # in a bash shell In PowerShell the equivalent is Set-Alias docker podman (add it to your profile to keep it). Pros: no daemon, rootless by default, Docker-compatible CLI, and security teams like it. Cons: some edge cases with networking and volumes, and Kubernetes integration is a bit more work. Source: Podman installation, Podman for Windows guide 4. The errors I hit and how to fix them The fun part. Here is what broke, why, and the fix. Error 1. wsl --install just prints the help text. Why: WSL is already installed, so the "install everything" path does not run. Fix: list what is available and install a distro by name: wsl --list --online wsl --install -d Ubuntu If the download hangs at 0.0%, add --web-download: wsl --install --web-download -d Ubuntu. Error 2. System has not been booted with systemd as init system (PID 1). Can't operate. Why: systemctl needs systemd, and some distros or older WSL builds still use the old WSL init. The current Ubuntu from wsl --install has systemd on by default, so you mostly hit this with other distros. Fix: check your WSL version is 0.67.6 or newer, then add this to /etc/wsl.conf inside the distro: [boot] systemd=true Then restart WSL (see Error 4). Confirm with systemctl status. Error 3. permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock Why: the Docker socket belongs to root and the docker group. Your user is in neither, so plain docker ps gets the door slammed. Fix: add yourself to the group, then restart WSL so the new group sticks: sudo usermod -aG docker $USER wsl --shutdown wsl -d Ubuntu Then docker ps works without sudo. Here is my lab after the fix: empty table, no error, no sudo. !docker ps works without sudo after usermod and wsl --shutdown Before you celebrate, read section 5. This fix has a catch. Error 4. I changed a setting and nothing happened. Why: WSL only picks up wsl.conf changes after the distro fully stops. Microsoft calls it the "8 second rule": close every shell, then wait about 8 seconds. Fix: wsl --list --running should say there are no running distributions. Or use the big hammer: wsl --shutdown. It stops all distros, including your Podman machine, so save your work first. Error 5. Rootless Podman will not bind port 80. Why: rootless containers cannot bind ports below 1024. Fix: map to a higher host port (-p 8080:80), which is what I do on a dev laptop anyway. Only if you really need port 80, stop the machine and switch it to rootful: podman machine stop podman machine set --rootful podman machine start podman machine set --rootful=false takes you back. Error 6. Docker tools talk to the wrong engine. Why: Podman listens on the same named pipe Docker clients use by default, npipe:////./pipe/docker_engine. If something else already holds that pipe, the two fight. Fix: point your tools at Podman's own pipe by setting DOCKER_HOST to npipe:////./pipe/podman-machine-default. Error 7. podman machine init fails after the automatic WSL install. Why: the auto-install sometimes gets stuck halfway. Fix: install WSL manually with wsl --install from an admin PowerShell, reboot, and run podman machine init again. Also check that virtualization is enabled: WSL needs it, and a VM host needs nested virtualization. Source: WSL config, 8 second rule, systemd in WSL 5. Security gotcha This is the DevSecOps bit. Read it before you copy any of the fixes above to a shared machine. 1. The docker group is root with extra steps. Docker's own docs say it plainly: the docker group grants root-level privileges. Anyone in it can start a container that mounts / from the host and edit anything. On your personal lab laptop, fine. On a shared build box, think twice before running usermod -aG docker for everyone. 2. Rootless is the safer default, so keep it. Podman machines start rootless. --rootful exists, but switching to it just to get port 80 trades a small annoyance for a bigger blast radius. Map to 8080 instead. 3. Your Windows drives are inside WSL. By default WSL mounts C:\ at /mnt/c. A container started with -v /mnt/c:/host can read your whole user profile, browser data included. Mount only the project folder you need. 4. Secrets in compose files end up in Git. environment: DB_PASSWORD=SuperSecret123 in a compose file is how passwords travel to a public repo. Keep secrets out of the file: use a .env file listed in .gitignore, or Podman secrets, which are mounted as a file and never baked into an image: printf 'my-lab-password' | podman secret create db_password - podman run --secret db_password docker.io/library/alpine cat /run/secrets/db_password 5. License is a security-adjacent problem too. Docker Desktop is free for personal use and small businesses (under 250 employees and under $10M revenue). Bigger companies need a paid plan. Unlicensed tools on corporate laptops tend to get noticed by the same people who run your security reviews. Source: Docker post-install steps (docker group warning), podman secret create 6. Checklist - [ ] wsl -l -v shows my distro on VERSION 2 - [ ] systemctl status works inside Ubuntu (systemd on) - [ ] docker run hello-world or podman run hello-world prints its hello - [ ] I know the docker group equals root, and I only use it on my own lab machine - [ ] My Podman machine is still rootless, and I map ports above 1023 - [ ] I mount project folders, not the whole /mnt/c - [ ] No passwords in compose files: .env is in .gitignore or I use podman secret - [ ] I run wsl --shutdown knowing it stops every distro, Podman included Which did you pick on your Windows machine, WSL2 + Docker or Podman? And what was your first red error? Tell me below. Sources - Microsoft Learn: Install WSL - Microsoft Learn: Use systemd to manage Linux services with WSL - Microsoft Learn: Advanced settings configuration in WSL - Podman docs: Installation - Podman for Windows guide - Podman docs: podman machine set - Podman docs: podman secret create - Docker docs: Linux post-installation steps - Docker docs: Docker Desktop license agreement

  2. Hacker News · · on Docker is weird · 80fj0348i

    I've used crun without root for a lot of practical use cases, if you are only doing limited use of the network and are careful with volume mounts it works pretty well. Podman also has a fully rootless mode which can work for many uses: github.com/podman-container-tools/podman/blob/mai…

  3. X · · @ppoi

    WSL3対応版が出てきた github.com/podman-container-tools/podman/releases…

    17 views
  4. DEV · · @homelabpm

    Rootful Podman restarts a --uidmap container once on an AppArmor host, then gives up TL;DR: On a host with AppArmor enabled, a rootful Podman container that has its own ID mapping (--uidmap/--gidmap) and a restart policy is restarted once at most. When it exits the second time it stays exited. podman events shows died, restart, and then nothing, and RestartCount stops at 1. The process that should restart it, podman container cleanup, fails with profile "containers-default-0.62.2" specified but AppArmor is disabled on the host. AppArmor is enabled, and the error is logged only if the container was created with podman --syslog. Reproduced on Debian 13 with Debian's podman 5.4.2. The upstream report is on Ubuntu 26.04 with 5.7.0 and 6.1.3, so it isn't Ubuntu-specific or new. The same container without the mapping, or with --security-opt apparmor=unconfined, kept restarting. A Quadlet unit with UIDMap= and Restart=always was restarted by systemd every time. The toolkit's check-podman-restart-userns.sh lists containers that are stuck or will get stuck. Upstream report: podman-container-tools/podman#29925. The symptom A disposable Debian 13.7 VM (kernel 6.12.111, AppArmor enabled: /sys/module/apparmor/parameters/enabled is Y), apt install podman: podman 5.4.2, crun 1.21, conmon 2.1.12, containers-common 0.62.2. All as root. Three containers that exit after four seconds, each with --restart always: podman run -d --name rtest-userns --restart always \ --uidmap 0:200000:65536 --gidmap 0:200000:65536 alpine:3.22 sleep 4 podman run -d --name rtest-unconfined --restart always \ --uidmap 0:200000:65536 --gidmap 0:200000:65536 \ --security-opt apparmor=unconfined alpine:3.22 sleep 4 podman run -d --name rtest-plain --restart always alpine:3.22 sleep 4 Twenty-five seconds later: rtest-userns: exited restarts=1 apparmor=containers-default-0.62.2 rtest-unconfined: running restarts=5 apparmor=unconfined rtest-plain: running restarts=5 apparmor=containers-default-0.62.2 The events for the mapped container: create init start died restart and nothing after that. podman start rtest-userns from a shell started it without complaint. --restart on-failure:3 on a mapped container whose command exits 1 stopped the same way, at restarts=1. Created with podman --syslog run ... instead, the same container left this in the journal when it stopped: /usr/bin/podman[5105]: level=error msg="Cleaning up container: failed to clean up container 75c416f9...: profile \"containers-default-0.62.2\" specified but AppArmor is disabled on the host" from the process podman ... --syslog container cleanup --stopped-only <id>, which conmon runs when the container exits. Why it's easy to miss Everything you'd look at says the restart policy is working. The event stream has a restart event. podman inspect shows the policy as always. The first crash is handled, so a quick test that kills the container once and watches it come back passes. The error itself goes nowhere by default. Without --syslog on the command that created the container, the cleanup process has no place to report it, so it isn't in the journal, in podman logs, or in the events. When you do find it, it says AppArmor is disabled on a host where it plainly isn't, which points at the host configuration rather than at Podman. And the combination is narrow enough that most setups don't have it. Rootless Podman doesn't use AppArmor profiles. Fedora and RHEL use SELinux. Containers without their own mapping restart fine. It takes rootful Podman, an AppArmor distribution, and --uidmap/--gidmap, which is exactly what people reach for when they want rootful containers to run as unprivileged host IDs. Other ways of giving a container its own mapping, such as --userns=auto, weren't tested here. What's really going on The message comes from containers/common's AppArmor package. IsEnabled() there returns whether IsSupported() succeeds, and IsSupported() (v0.62.2, the version in Debian) checks three things in order: that the process isn't rootless, that the kernel reports AppArmor as enabled, and that the apparmor_parser binary can be found. The upstream report doesn't explain the failure. The obvious guess is that the cleanup process thinks it is rootless. Here it isn't. Traced with strace -f on conmon as the container exited, the cleanup process ran as root, in the host's user namespace, with no Podman user-namespace variable in its environment, and it didn't re-execute itself or call unshare. conmon's capabilities were the same for the mapped and the plain container (CapEff: 000001ffffffffff, host user namespace). So whichever check fails, it fails for a process that looks the same as the one that successfully restarts the plain container. Which of the other two checks fails in that path wasn't pinned down here. What is clear is the shape: the restart decision happens in the cleanup process, the cleanup process fails before it restarts the container, and the failure is reported only to syslog when asked for. The fix Until Podman fixes it: - Let systemd do the restarting. A Quadlet unit with the same mapping: [Container] Image=docker.io/library/alpine:3.22 Exec=sleep 4 UIDMap=0:200000:65536 GIDMap=0:200000:65536 [Service] Restart=always RestartSec=1 restarted 4 times in 25 seconds, with no AppArmor error in its journal. Quadlet runs the container with --rm and no --restart, so each restart is a new podman run from systemd, and Podman's own restart path isn't used. - --security-opt apparmor=unconfined also avoids it, as the table shows. That removes the container's AppArmor confinement, so it is a trade, not a fix. - Create containers with podman --syslog if you depend on Podman's restart policy. It doesn't fix anything, but the failure is then in the journal instead of nowhere. To find containers already in this state, check-podman-restart-userns.sh lists every container with a restart policy that is exited without having been stopped by the user (STUCK), and every running one that is rootful, mapped, confined and set to restart on an AppArmor host (AT RISK, because it will stop the same way next time). On the test VM it reported the stuck and the at-risk containers, and passed one stopped by the user, one that exited 0 under on-failure, and the unconfined one. The generalisable habit A restart policy is only tested when the thing has stopped more than once. The common test, kill it and see it come back, exercises the first restart, which here worked. The question to ask is "what does the second exit look like", and the place to look is the restart count after a few cycles, not whether the container is up right now. The same goes for a supervisor's error reporting. When the component that does the restarting is a short-lived helper process, find out where its errors go before you need them. Here they went to syslog only on request. Podman's compat API resetting the restart policy to no was the same kind of failure: the container looks configured to come back, and after the next crash it doesn't. Toolkit This post's fix is available as a tested, ready-to-run script in the toolkit. See the toolkit →

    1 comment
  5. X · · @dpuiger

    Checkpoints ignore user-specified security configuration and are very difficult to run safely. github.com/podman-container-tools/podman/releases… t.co

  6. ちょうど今このバグを踏んでいる。 podman#29749

    130 views

Latest stargazers

The last 10 distinct accounts we observed this year.

Most active participants

PR, issue, comment & review events in the past year.

Packages

Scan pending.

README badges

Embed a badge in your README or website.

Live mentions · last 30 days
containers/podman mentions in the last 30 days