Skip to content

Rootless Systemd & Quadlet Execution Model

StackPilot utilizes Red Hat's Podman Quadlets to bridge containerized application workflows directly with the native Linux service manager (systemd).


1. How Quadlets Work

Quadlets are declarative configuration files placed in systemd generator search paths: - User-scoped path: ~/.config/containers/systemd/ - System-scoped path: /etc/containers/systemd/

When systemctl --user daemon-reload is executed, the Quadlet generator parses these files and dynamically synthesizes standard .service units on the fly.

sequenceDiagram
    autonumber
    actor Admin as Central Hub / Admin
    participant Agent as Host Agent (:9091)
    participant FS as Host Filesystem (~/.config/containers/systemd/)
    participant Systemd as systemd --user
    participant Podman as Podman Runtime

    Admin->>Agent: POST /api/apps/deploy (Quadlet Definition)
    Agent->>Agent: Validate Path & Realpath Jail
    Agent->>FS: Atomic Write <app>.container / <app>.pod
    Agent->>Systemd: systemctl --user daemon-reload
    Note over Systemd,Podman: Systemd Quadlet generator translates<br/>.container definitions into transient service units
    Agent->>Systemd: systemctl --user start <app>.service
    Systemd->>Podman: Execute rootless podman run
    Podman-->>Systemd: Process PID / cgroups boundary established
    Systemd-->>Agent: Service Active (Running)
    Agent-->>Admin: Deployment Success Envelope

2. Quadlet File Types

StackPilot handles four primary Quadlet unit types:

.container

Defines a single container instance:

[Unit]
Description=Nextcloud Application
After=network-online.target

[Container]
Image=docker.io/library/nextcloud:stable
ContainerName=nextcloud-app
Environment=POSTGRES_HOST=nextcloud-db
Volume=nextcloud-data.volume:/var/www/html
PublishPort=8080:80

[Install]
WantedBy=default.target

.pod

Defines a shared network and IPC pod boundary where multiple containers communicate over localhost:

[Unit]
Description=Arrstack Pod
After=network-online.target

[Pod]
PodName=arrstack
PublishPort=8080:8080
PublishPort=8989:8989

[Install]
WantedBy=default.target

.volume & .network

Manage persistent storage volumes and isolated container networks declaratively without calling manual podman volume create commands.


3. Lingering Sessions (loginctl enable-linger)

By default, Linux systemd user sessions terminate when the user logs out.

To ensure homelab containers survive terminal disconnects and boot on machine startup:

sudo loginctl enable-linger $USER

The StackPilot installer automatically configures lingering, ensuring the rootless user manager runs as a standing service.