Podman Deployment
Run OmniRoute with Podman via Quadlet (systemd integration) or podman compose.
Option A: Quadlet (recommended)
1. Build the image
cd /path/to/omniroute
podman build --target runner-base -t omniroute:base .
# For web-cookie providers (gemini-web, claude-web, claude-turnstile):
podman build --target runner-web -t omniroute:web .
# For CLI tool support:
podman build --target runner-cli -t omniroute:cli .
2. Copy Quadlet files to the systemd directory
mkdir -p ~/.config/containers/systemd/omniroute
cp contrib/podman/*.container ~/.config/containers/systemd/omniroute/
cp contrib/podman/*.network ~/.config/containers/systemd/omniroute/
cp contrib/podman/*.volume ~/.config/containers/systemd/omniroute/
3. Mount the project .env for secrets
Edit ~/.config/containers/systemd/omniroute/omniroute.container and
uncomment/replace the EnvironmentFile line with the absolute path to
your project .env:
EnvironmentFile=/home/USER/code/docker/OmniRoute/.env
Make sure CONTAINER_HOST=podman is set in that .env.
Alternatively, edit the env vars directly in the .container file.
4. Reload systemd and start
systemctl --user daemon-reload
systemctl --user start omniroute-redis
systemctl --user start omniroute
5. Verify
systemctl --user status omniroute
curl http://localhost:20128/v1/models
To follow logs:
journalctl --user -u omniroute -f
6. Enable on boot
systemctl --user enable omniroute-redis
systemctl --user enable omniroute
Option B: podman compose
The project's docker-compose.yml now works with both Docker and Podman.
Just set CONTAINER_HOST=podman in .env before starting.
1. Prepare the data directory
Rootless Podman maps container UIDs into a subordinate range. The
node user (UID 1000) inside the container maps to a different UID
on the host, so it cannot write to ./data owned by your host user.
Fix the ownership before starting:
mkdir -p data
podman unshare chown 1000:1000 ./data
2. Set the runtime in .env
Make sure .env contains:
CONTAINER_HOST=podman
3. Start
podman compose --profile base up -d
Profiles
Same profiles as docker compose:
| Profile | Command |
|---|---|
base (no CLIs) |
podman compose --profile base up -d |
web (+Chromium/Playwright) |
podman compose --profile web up -d |
cli (+CLI tools) |
podman compose --profile cli up -d |
host (host-mounted binaries) |
podman compose --profile host up -d |
cliproxyapi (sidecar) |
podman compose --profile cliproxyapi up -d |
How it works
The docker-compose.yml uses fully-qualified image names
(docker.io/library/redis:7-alpine) and flat variable expansions so it
works with both Docker and Podman without a separate compose file.
The entrypoint script (check-permissions.sh) reads CONTAINER_HOST
from .env to give the correct fix instructions:
- docker:
sudo chown -R ... ./data - podman:
podman unshare chown 1000:1000 ./data