惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
爱范儿
爱范儿
T
The Exploit Database - CXSecurity.com
量子位
T
Tailwind CSS Blog
T
Threatpost
The GitHub Blog
The GitHub Blog
AWS News Blog
AWS News Blog
云风的 BLOG
云风的 BLOG
K
Kaspersky official blog
P
Proofpoint News Feed
博客园 - 司徒正美
L
LangChain Blog
T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
S
Secure Thoughts
The Last Watchdog
The Last Watchdog
Spread Privacy
Spread Privacy
H
Hacker News: Front Page
T
Troy Hunt's Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
W
WeLiveSecurity
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Proofpoint News Feed
T
Tor Project blog
T
The Blog of Author Tim Ferriss
I
Intezer
P
Privacy & Cybersecurity Law Blog
美团技术团队
N
Netflix TechBlog - Medium
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
Attack and Defense Labs
Attack and Defense Labs
T
Tenable Blog
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
J
Java Code Geeks
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog
A
About on SuperTechFans
Last Week in AI
Last Week in AI

Solene'%

Solene'% : Software to keep photos organized Solene'% : Make your own container base images from trusted sources Solene'% : File transfer made easier with Tailscale Solene'% : Comparison of cloud storage encryption software Solene'% : Revert fish shell deleting shortcuts behavior Solene'% : Hardware review: ergonomic mouse Logitech Lift Solene'% : URL filtering HTTP(S) proxy on Qubes OS Solene'% : Introduction to Qubes OS when you do not know what it is Solene'% : How to trigger a command on a running Linux laptop when disconnected from power
Solene'% : Declaratively manage containers on Linux
2026-02-10 · via Solene'%

Written by Solène, on 10 February 2026.
Tags: #systemd #linux #containers

Table of contents

  • 1. Introduction
  • 2. Setup (simple service)
  • 3. Setup (advanced service)
  • 4. Ops
    • 4. 1. Getting into a user shell
    • 4. 2. Disabling a user
    • 4. 3. Automatic updates
  • 5. Conclusion
  • 6. Going further

1. Introduction §

When you have to deal with containers on Linux, there are often two things making you wonder how to deal with effectively: how to keep your containers up to date, and how to easily maintain the configuration of everything running.

It turns out podman is offering systemd unit templates to declaratively manage containers, this comes with the fact that podman can run in user mode. This combination gives the opportunity to create files, maintain them in git or deploy them with a configuration management tool like ansible, and keep things separated per user.

It is also very convenient when you want to run a program shipped as a container on your desktop.

For some reason, this is called "quadlets".

podman-systemd.unit man page

In this guide, I will create a kanboard service (a PHP software to run a kanban) under the kanban user.

2. Setup (simple service) §

You need to create files that will declare containers and/or networks, this can be done in various places depending on how you want to manage the files, the man page gives all the details, but basically you want to stick with the two following options:

  • system-wide configuration: /etc/containers/systemd/users/$(UID)
  • user configuration: ~/.config/containers/systemd/

Both will run rootless containers under the user UID, but one keep the files in /etc/ which may be more suitable for central management.

As systemd is used to run the containers, if you want to run a container for a user that is not one where you are logged, you need to always enable it so its related systemd processes / services are running, including the containers, this is done by enabling "linger".

useradd -m kanban
loginctl enable-linger kanban

This will immediately create a session for that user and pop all related services.

Now, create a file /etc/containers/systemd/users/1001/ (1001 being the uid of kanban user) with this content:

[Container]
Image=docker.io/kanboard/kanboard:latest
Network=podman
PublishPort=10080:80
Volume=kanboard_data:/var/www/app/data
Volume=kanboard_plugins:/var/www/app/plugins
Volume=kanboard_ssl:/etc/nginx/ssl

[Service]
Restart=always

[Install]
WantedBy=default.target

This can exactly map to a very long podman command line that would use the image docker.io/kanboard/kanboard:latest in network podman and declaring three different container volumes and associated mount points. This generator even allows you to add command line arguments in case an option is not available with systemd format.

Because the user already runs, the container will not start yet except if you use disable-linger and then enable-linger the kanban user, and that would not be ideal to be honest. There is a better way to proceed: systemctl --user --machine kanban@ daemon-reload which basically runs systemctl --user daemon-reload by the user kanban except we do it as root user which is more convenient for automation.

Running the container this way will trigger exactly the same processes as if you started it manually with podman run -v kanboard_data:/var/www/app/data/ [...] docker.io/kanboard/kanboard:latest.

Note that you can skip the [Install] section if you do not want to automatically start the container, and prefer to manually start/stop it with "systemctl", this is actually useful if you have the container under your regular user and do not always need it.

3. Setup (advanced service) §

If you want to run a more complicated service that need a couple of containers to talk together like a web server, a backend runner and a database, you only need to configure them in the same network.

If you need them to start the containers of a group in a specific order, you can add use systemd dependency declaration in [Install] section.

Podman will run a local DNS resolver that translates the container name into a working hostname, this mean if you have a postgresql container called "db", then you can refer to the postgresql host as "db" from another container within the same network. This works the same way as docker-compose.

4. Ops §

4.1. Getting into a user shell §

To have a working environment for journalctl or systemctl commands to work requires to use machinectl shell kanban@, otherwise the dbus environment variables will not be initialized. Note that it works too when connecting with ssh, but it is not always ideal if you use it locally.

From this shell, you can run commands like systemctl --user status kanboard.container for our example or journalctl --user -f -u kanboard.container, or run a shell in a container, inspect a volume etc...

Using sudo -u user or su - user will not work.

4.2. Disabling a user §

If you want to disable the services associated with an user, use this command:

loginctl disable-linger username

This will immediately close all its sessions and stop services running under that user.

4.3. Automatic updates §

This is the very first reason I went into using quadlets for local services using containers, I did not want to have to manually run some podman pull commands over a list then restart related containers that were running.

Podman gives you a systemd services doing all of this for you, this works for containers with the parameter AutoUpdate=registry within the section [Container].

Enable the timer of this service with: systemctl --user enable --now podman-auto-update.timer then you can follow the timer information with systemctl --user status podman-auto-update.timer or logs from the update service with journalctl --user -u podman-auto-update.service.

Make sure to pin your container image to a branch like "stable" or "lts" or "latest" if you want a development version, the update mechanism will obviously do nothing if you pin the image to a specific version or checksum.

5. Conclusion §

Quadlets made me switch to podman as it allowed me to deploy and maintain containers with ansible super easily, and also enabled me to separate each services into different users.

Prior to this, handling containers on a simple server or desktop was an annoying task to figure what should be running, how to start them and retrieving command lines from the shell history or use a docker/podman compose file. This also comes with all the power from systemd like querying a service status or querying logs with journalctl.

6. Going further §

There is a program named "podlet" that allow you to convert some file format into quadlets files, most notably it is useful when getting a docker-compose.yml file and transforming it into quadlet files.

podlet GitHub page