Skip to main content
Levelrail talks to a Docker-compatible Engine API socket. Any runtime that serves that API can in principle run it, but only some are tested. This page says which, and how to set up the rest.

What is supported today

Image-based deploys and compose are the expected path on Podman. Dockerfile and Railpack source builds are not verified on Podman yet: builds use a BuildKit that runs inside dockerd, and Podman has no embedded BuildKit. Build on another node or in CI and deploy the image. Server installs are Linux only. On a macOS laptop, levelrail-cli dev is the path; see Local development.

How the installer chooses

install.sh --runtime auto|docker|podman|existing (or LEVELRAIL_RUNTIME): For Podman the installer enables podman.socket, writes APP_CONTAINER_RUNTIME_SOCKET=unix:///run/podman/podman.sock into the same systemd drop-in as the other APP_* settings, and makes the levelrail unit require podman.socket instead of docker.service. Set LEVELRAIL_PODMAN_SOCKET to use another socket path. An upgrade keeps the runtime an install chose. install.sh --check prints the same rows: the detected runtime, its version, rootful or rootless, and the support label. It exits non-zero only on a real failure, such as --runtime podman with no Podman installed.

Manual Podman setup

Install Podman with your distro first (apt install podman, dnf install podman). Rootful, as root:
Then run install.sh --runtime podman, or set APP_CONTAINER_RUNTIME_SOCKET=unix:///run/podman/podman.sock in the levelrail service drop-in yourself. Rootless, as the user that will own the containers (the installer only prints these, it never runs user-level commands for another user):
Linger keeps the user’s services running after logout. Point APP_CONTAINER_RUNTIME_SOCKET at that socket path. Rootless Podman cannot publish ports 80 and 443 unless you lower net.ipv4.ip_unprivileged_port_start.

Podman notes

  • Source builds (Dockerfile and Railpack) need BuildKit, which Podman does not have. A source deploy on Podman fails with the class build_engine_unsupported. Deploy a prebuilt image, or run Docker on the build node.
  • Podman answers 404 for the engine’s registry digest lookup. Levelrail treats that as “unknown”, not “missing”, and lets the node pull the image itself, so short names such as nginx:1.27-alpine work.
  • App networks are carved from APP_NETWORK_POOL (default 10.88.0.0/14). The block 10.88.0.0/16 is skipped because Podman’s default network uses it.
  • Compose ports are not published on the host as written. A service port is published on a random loopback port for ingress, so do not rely on the host port you wrote in the compose file. See Compose apps.
  • The exposure controller needs the iptables DOCKER-USER chain. On Podman with netavark and nftables that chain is absent, so the controller reports it once and exposure rules are not applied.

Verify

The container_runtime check reports Docker or Podman, rootful or rootless, and which setting chose the socket. See Security for what that detection covers.

Roadmap

  • Test against a real Podman host in CI, then promote it from best-effort.
  • A source-build story for Podman (an external BuildKit), once it is verified.
  • Other runtimes only on demand.
Last modified on October 25, 2026