A unified CLI for managing rootless Podman services with systemd and Quadlets.
divban is a CLI tool for managing rootless Podman containers through systemd Quadlet generation and integration. It enables declarative TOML-based setup of containerised services and generates the required Quadlets and runs each service as an isolated system user with its own UID namespace.
Setting up rootless Podman containers with systemd integration can be complex:
- Creating dedicated users with proper SUBUID/SUBGID ranges
- Writing Quadlet files (.container, .network, .volume)
- Managing container lifecycles via systemd user sessions
- Handling multi container services with dependencies
divban automates these through a single declarative configuration file, hoping to achieve the simplicity of docker compose while taking advantage of Podman's features including running rootless by default, ability to auto-update containers (no watchtower or diun needed) and management of all processes using systemd, journald and friends.
Divban (دیوبان, IPA: /diːvˈbɒːn/) is Persian for "keeper of demons." It combines div, a demon or chaotic spirit in Zoroastrian tradition (from Avestan daēva), with -bān: "keeper" or "guardian".
Divban reflects this tool's purpose: containers are powerful but chaotic forces that, left unmanaged, consume resources and run with excessive privileges. Inspired by the legendary king Tahmuras, the mythical demon binder, divban constrains daemons through user namespaces, resource limits, and systemd integration, harnessing their power for productive work.
| Service | Description | Repository |
|---|---|---|
| Caddy | Reverse proxy with automatic HTTPS | caddyserver/caddy |
| Immich | Self-hosted photo management with ML | immich-app/immich |
| Actual | Personal finance management | actualbudget/actual |
| FreshRSS | Self-hosted RSS feed aggregator | FreshRSS/FreshRSS |
- Linux with systemd (user session support required)
- Podman 5.0+ with pasta networking
- Root privileges for initial setup only
Download the latest release from GitHub Releases:
| Architecture | Binary | Notes |
|---|---|---|
| amd64 | linux-amd64 |
Baseline, compatible with older systems |
| amd64v3 | linux-amd64v3 |
Modern CPUs with AVX2+ (2013+) |
| arm64 | linux-arm64 |
Raspberry Pi 4+, cloud ARM instances |
# Download and extract (example for amd64v3)
VERSION="0.7.3"
curl -fsSL --proto-redir =https --tlsv1.2 -O "https://github.com/aryonoco/divban/releases/download/v${VERSION}/divban-${VERSION}-linux-amd64v3.tar.zst"
tar -xf "divban-${VERSION}-linux-amd64v3.tar.zst"
# Install to ~/.local/bin
mkdir -p ~/.local/bin
install -m 755 "divban-${VERSION}-linux-amd64v3/divban" ~/.local/bin/If ~/.local/bin is not in your PATH, add it:
# bash (~/.bashrc)
export PATH="$HOME/.local/bin:$PATH"
# zsh (~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"
# fish (~/.config/fish/config.fish)
fish_add_path ~/.local/binTo allow running divban with sudo (required for setup commands):
sudo ln -s "$HOME/.local/bin/divban" /usr/local/bin/divbanIf you want to modify the code. Requires Bun 1.3+:
git clone https://github.com/aryonoco/divban.git
cd divban
bun install
bun run build
# Binary output: bin/divbandivban <service> <command> [config] [options]
| Command | Description |
|---|---|
| validate | Validate TOML configuration |
| generate | Generate Quadlet files |
| diff | Show pending changes |
| setup | Create user, directories, and install quadlets |
| start | Start the service |
| stop | Stop the service |
| restart | Restart the service |
| reload | Graceful config reload (Caddy only) |
| status | Show service status |
| logs | View service logs |
| update | Check for and apply container image updates |
| backup | Back up service data |
| backup-config | Back up service configuration files |
| restore | Restore from backup |
| remove | Remove a service and its user |
| secret | Manage service secrets (show, list) |
The special service name all may be used to run commands across all registered services.
Services are configured via TOML files. Example configurations are provided in the examples/ directory.
Configuration files are searched in the following order:
- Path specified on command line
./divban-<service>.toml./<service>/divban-<service>.toml/etc/divban/divban-<service>.toml
Each service runs as a dedicated system user (divban-<service>) with:
- Dynamically allocated UID from range 10000-59999
- Isolated UID namespace mapping
- Quadlet files installed to
~/.config/containers/systemd/ - Data stored in directory (default:
/srv/divban-<service>/)
just dev # Run in development mode
just test # Run tests
just lint # Run linter
just fmt # Format code
just ci # Run full CI pipelineThis project was developed with significant LLM involvement. I'm a systems architect by trade, not a programmer. I designed the core logic, made technical decisions and directed development, but AI/LLM tools generated most of the code.
All code was reviewed, tested, and iterated on by me. The design choices (Effect for typed errors and resource management, service abstraction patterns, etc.) are mine. The TypeScript syntax is not. I'm publishing this because it works for me, not because of how it was written.
Copyright 2026 Aryan Ameri.
| Content | Licence |
|---|---|
Source code (src/, tests/) |
MPL-2.0 |
| Config/plumbing | 0BSD |
| Documentation | CC-BY-4.0 |
This project is REUSE compliant. See REUSE.toml for details.