Quadlets are a native Podman feature that allow users to manage containers as systemd services without manually writing complex unit files.
They function by using declarative configuration files (ending in .container, .pod, etc.)
The podman-system-generator automatically converts these high-level declarative files into standard systemd .service files during boot or when systemctl daemon-reload is executed.
Because Quadlets integrate directly with the systemd init system, they eliminate the need for Docker’s daemon or wrapper tools like podman-compose.
This allows management of container lifecycles (auto-start on boot, restart on failure, logging) using native Linux service management commands like systemctl,
making Docker a completely optional dependency.
search.brave.com: “how to use quadlet to create systemd service” overall process:
enable the service are currently resulting in the following error:Failed to enable unit: Unit /blah/blah/blah.service is transient or generatedAssuming that:
service.container files are stored at /srv/serverus/containersservice.container files MUST contain:
[Install]
# Start by default on boot
WantedBy=default.target
service.container files get symlinked to:/srv/serverus/.config/containers/systemd (instead of /etc/containers/…)loginctl enable-linger vernonsystemctl --user daemon-reloadsystemctl --user start {serviceName}.servicesystemctl --user enable --now podman-auto-update.timervi /srv/serverus/containers/jellyfin.container
contents:
[Unit]
Description=Podman - Jellyfin
Wants=network-online.target
After=network-online.target
[Container]
Image=docker.io/jellyfin/jellyfin:latest
AutoUpdate=registry
ContainerName=jellyfin
Environment=PUID=1011
Environment=PGID=100
Environment=TZ=America/Denver
Volume=/srv/serverus/containers/jellyfin-config:/config:Z
Volume=/srv/serverus/containers/jellyfin-cache:/cache:Z
Volume=/srv/media/video:/data/video:z
Volume=/srv/media/music:/data/music:z
Volume=/srv/media/pictures:/data/pictures:z
Volume=/srv/media/books:/data/books:z
PublishPort=8096:8096/tcp
PublishPort=7359:7359/udp
PublishPort=1900:1900/udp
StopTimeout=60
[Service]
Restart=always
TimeoutStartSec=900
TimeoutStopSec=70
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target
vi /srv/serverus/containers/transmission.container
contents:
[Unit]
Description=Transmission BitTorrent Client
After=network-online.target
Wants=network-online.target
[Container]
Image=lscr.io/linuxserver/transmission:latest
AutoUpdate=registry
ContainerName=transmission
PublishPort=9091:9091
PublishPort=51419:51419
PublishPort=51419:51419/udp
Volume=/srv/serverus/containers/transmission-config:/config:Z
Volume=/srv/media:/media:z
Volume=/srv/watch:/watch:z
Environment=PUID=1011
Environment=PGID=1011
Environment=TZ=America/Denver
Environment=WHITELIST=127.0.0.1,192.168.9.*
Environment=PEERPORT=51419
Environment=HOST_WHITELIST=serverus
[Service]
Restart=always
TimeoutStartSec=900
TimeoutStopSec=70
[Install]
# Start by default on boot
WantedBy=default.target
Config straight from Bazzite! (but looks to be missing some bits)
https://docs.bazzite.gg/Installing_and_Managing_Software/Quadlet/?h=samba#samba-server
[Container]
ContainerName=samba
Environment=ACCOUNT_username=password
Environment=UID_username=1011
#Environment=GROUPS_username=users
# Protected share with write access
Environment="SAMBA_VOLUME_CONFIG_dublife=[DubLife]; path=/srv; valid users = username; guest ok = no; read only = no; browseable = yes"
# Open share with readonly access
Environment="SAMBA_VOLUME_CONFIG_media=[Media Share]; path=/srv/media; guest ok = yes; read only = no; browseable = yes"
Image=ghcr.io/servercontainers/samba:smbd-only-latest
AutoUpdate=registry
Network=host
Volume=/path/to/protected:/shares/dublife:z
Volume=/path/to/guest:/shares/media:z
# Remove if you don't want autostart
[Install]
WantedBy=default.target
https://hub.docker.com/r/servercontainers/samba #for info only, use below to actually pull image
docker pull ghcr.io/servercontainers/samba:latest
samba:
image: docker.io/servercontainers/samba:latest
container_name: samba
restart: unless-stopped
# user: samba
# network_mode: host
# hostname: smb-server
environment:
ACCOUNT_samba: test
UID_samba: 1000
SAMBA_GLOBAL_STANZA: vfs objects = catia fruit streams_xattr
SAMBA_VOLUME_CONFIG_shared_home: |
[home];
path=/shares/home
valid users = samba
browsable = yes
writeable = yes
dockurr is recently updated & well regarded
https://hub.docker.com/r/dockurr/samba
search.brave.com:dockur samba example
Quadlet:
docker pull dockurr/samba:latest
# ~/.config/containers/systemd/samba.container
#https://hub.docker.com/r/dockurr/samba
[Unit]
Description=Samba SMB Server
[Container]
ContainerName=samba
Image=docker.io/dockurr/samba
PublishPort=445:445
Volume=/path/to/local/data:/storage
Environment=USER=samba
Environment=PASS=secret
Environment=NAME=Media
Network=host
# Note: If using default bridge network, ensure port mapping is correct
# and no conflicting services are on port 445.
[Install]
WantedBy=default.target
docker-compose:
services:
samba:
image: dockurr/samba
container_name: samba
environment:
NAME: "Data"
USER: "samba"
PASS: "secret"
RW: true
UID: 1000
GID: 1000
ports:
- 445:445
volumes:
- ./samba:/storage
restart: always