Collection of quadlets.
I also make use of some compose stacks: compose-bucket.
- Service-based dirs:
actual/,beaver/, etc.<container-name>.container: Quadlet unitcontainer-data/: Datacontainer-config/: Config.env: Private vars.env.example: Template
All .container files follow this structure:
[Unit]
[Service]
[Install]
[Container]
# Container properties
ContainerName -> Image -> AutoUpdate -> Pull
# Environment options
Environment vars -> EnvironmentFile
# User options
User -> Group -> UserNS
# Network options
Network -> NetworkAlias -> PublishPort
# Volume binds
Data -> Config -> System files
# Traefik Labels
enable -> rule -> entrypoints -> middlewares -> services
# Glance Labels
name -> icon -> url -> description -> id
See beaver.container for reference.
- Clone repo
- Symlink:
ln -s (pwd) ~/.config/containers/systemd systemctl --user daemon-reload- Copy/edit
.envfrom.env.example
- Start:
systemctl --user start <service>.container - Stop:
systemctl --user stop <service>.container - Status:
systemctl --user status <service>.container - Enable:
systemctl --user enable <service>.container
I auto-update container images via Renovate + auto-deploy on push. Well, not truly "auto" since I merge manually to make sure there's some level of stability via pinning.
Renovate (hourly + on-push) -> PR with update -> Manual Merge via Web UI or Mobile app
-> Update .container images -> Forgejo Push Trigger -> Webhook
-> touch trigger -> systemd .path -> Pull changes -> Restart relevant containers
To install or check the status of the systemd automation units (paths, timers, services) responsible for GitOps, use:
./gitops/scripts/manage-systemd.sh status
./gitops/scripts/manage-systemd.sh install- Update
.env.examplefiles withqh generate env(quadlet-helper). There's also a pre-commit hook in the .githooks directory.
- Update Cloudflare IPs in
traefik.yamlwithqh cloudflare run. Automate usingqh cloudflare install. - Update
traefik.yaml.examplefile withqh generate traefik.
- Systemd service for Immich's rclone mount