Elouworld

Using docker-compose with Podman rootless

Podman is a daemonless Docker alternative for Linux that can run without root access. However, it is less well known that Podman can expose a UNIX-domain socket compatible with the Docker API. This makes it work with most tools in the Docker ecosystem, such as docker-compose.

Podman uses a Linux feature called user namespaces. With this, the root user inside a container is mapped to your host user. Other UIDs and GIDs are mapped to the ranges defined in /etc/subuid and /etc/subgid, respectively.

This tutorial assumes that Podman and docker-compose are already installed, for example using your Linux distribution’s package manager.

Enable and start the Podman socket

To enable and start the Podman socket, run this command (as your user, not as root):

1
systemctl --user enable --now podman.socket

This command creates a UNIX-domain socket at ${XDG_RUNTIME_DIR}/podman/podman.sock. ${XDG_RUNTIME_DIR} is a private tmpfs automatically mounted for each user.

Note: The command requires a systemd session. If you are trying to run this command as another user, be aware that using sudo is not supported, because it doesn’t create a systemd session. You can use machinectl shell --uid=your-username (part of the systemd-container package on some Linux distributions) if you are part of the wheel group. Alternatively, log in as your user on a TTY or via SSH.

Expose it as the Docker host

Tools like docker-compose read the DOCKER_HOST environment variable. Set it to point to the Podman socket like this:

1
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/podman/podman.sock"

Add this line to your shell configuration (e.g. ~/.zshrc for Zsh) to make it permanent.

Use docker-compose

You can now run docker-compose as usual:

1
2
3
4
docker-compose config
docker-compose up -d
docker-compose ps
docker-compose down --volumes

Depending on your Linux distribution, docker-compose may be available as docker compose instead of docker-compose, but it works the same way. You can add an alias in your shell:

1
alias docker-compose='docker compose'

Tips and tricks

Stop and disable rootful Docker

If you have Docker installed but are not ready to uninstall it, you can stop and disable its systemd service by running (as root):

1
2
systemctl disable --now docker.service docker.socket
rm -f /var/run/docker.sock

Note: These commands do not erase Docker data.

If you change your mind, run this to start it again (as root):

1
systemctl enable --now docker.service

Using docker

The podman command accepts the same arguments as docker, but you can also keep using the docker command if you prefer: it can read the DOCKER_HOST variable and talk to the Podman socket, just like docker-compose.

podman unshare

If you want to become root without starting a container, you can use the podman unshare command, which starts a new shell as root (in a user namespace, not real host root), much like sudo -i. You will then be able to manipulate files owned by container users (for example with chown or chmod).

podman mount

You can access the files of a running container with podman mount.

First, run podman unshare, then change directory to the path returned by podman mount container-name-or-id:

1
2
podman unshare
cd "$(podman mount container-name-or-id)"

You will then be able to run your usual TUI editor to edit files in the container.

Docker rootless

If you are not ready to switch to Podman, Docker also supports a rootless installation. See their documentation.

Once it is set up and started, you also need to set the DOCKER_HOST environment variable:

1
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/docker.sock"

Unfortunately, rootless Docker has no equivalent of podman unshare and podman mount, although you can achieve similar things with unshare and nsenter.

User lingering

By default, Podman containers are stopped when the last systemd session of your user is closed.

To keep them running after you log out, enable user lingering for your user (as root):

1
loginctl enable-linger your-username

Copyright © 2026, Elouan Martinet (Exagone313) — This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.