Notes on Podman and Quadlets
This post contains notes on and examples of my Podman containers on Debian setup.
Table of Contents
- On running Podman containers rootless
- Enable lingering
- Enable automatic updates
- “Manually” auto-updating
- Reverse Proxy container
- Port forwarding
On running Podman containers rootless
I run a few containers for web services (http/https servers) behind another container which serves as a reverse proxy.
All containers run rootless under their own user
account. If I have a site, say, jkossen.nl, it runs under
the jkossen-nl user account which has no privileges on the
rest of the system.
Since the reverse proxy runs rootless as well, it has to listen on a
high port above 1000. To make the web services
work on ports 80 (http) and 443 (https), I use
port forwarding using firewalld. See Port Forwarding.
Enable lingering
Without lingering enabled, systemd will terminate processes for users when their login session is closed. This would kill your podman containers as well.
You can enable lingering with:
loginctl enable-linger "username"Enable automatic updates
Podman comes with a handy automatic container update service. To enable, switch to your container user and execute:
systemctl --user enable --now podman-auto-update.timerTo verify that your timer is enabled:
systemctl --user list-timers podman-auto-update.timer“Manually” auto-updating
To manually execute auto-updates, you can use
podman auto-update:
Test what podman auto-update would do:
podman auto-update --dry-runDo the updates:
podman auto-updateReverse Proxy container
This is an example configuration for my reverse proxy container.
Put the quadlets (the files rproxy.container,
rproxy-data.volume and podman-ipv6.network) in
the .config/containers/systemd/ subfolder within the home
folder of the user account that runs the container.
This should create the rproxy systemd service
automatically. If it does not, switch to the relevant container user
account and check your configuration with:
/usr/libexec/podman/quadlet --dryrun --userEnable the service with:
systemctl --user enable rproxyrproxy.container
[Container]
Image=docker.io/caddy:latest
PublishPort=[::]:10080:80
PublishPort=[::]:10443:443
Volume=/containers/rproxy/Caddyfile:/etc/caddy/Caddyfile
Volume=/containers/rproxy/security-headers.conf:/etc/caddy/security-headers.conf
Volume=rproxy-data.volume:/data
Network=podman-ipv6.network
AutoUpdate=registry
[Install]
WantedBy=default.targetrproxy-data.volume
[Volume]Yes, that one line should be all you need ;-)
podman-ipv6.network
[Network]
Driver=bridge
IPv6=true
Subnet=10.85.1.0/24
Gateway=10.85.1.1
Subnet=fd41:22a1:adca:2142::/64
Gateway=fd41:22a1:adca:2142::1
IPAMDriver=host-local
DisableDNS=trueNote 1
In the version of Podman I use (5.4.2 at this moment), the requests that the reverse proxy receives are from internal (podman network) ip addresses. So if you need to know who visits your services (think website visitor statistics), I don’t have a solution for that other than running the reverse proxy on the host itself instead of in a container.
Note 2
When I started using Podman, I ran the reverse proxy container as root, since it needed to run on privileged ports (< 1000). I also created a new network since IPv6 was disabled in the default network. But the IPv6 part never worked. I did not investigate this further, since the same network configuration for a rootless pod worked perfectly fine with both IPv4 and IPv6.
Port forwarding
Using firewalld, i run a set of rich rules to forward
incoming traffic on ports 80 and 443 to the
reverse proxy container on port 10080 and
10443:
rule family="ipv6" forward-port port="80" protocol="tcp" to-port="10080"
rule family="ipv6" forward-port port="443" protocol="tcp" to-port="10443"
rule family="ipv4" forward-port port="80" protocol="tcp" to-port="10080"
rule family="ipv4" forward-port port="443" protocol="tcp" to-port="10443"To add such a rule, use the firewall-cmd command in a
terminal:
firewall-cmd \
--permanent \
--zone=public \
--add-rich-rule='rule family="ipv4" forward-port to-port="10443" protocol="tcp" port="443"'You have to enable the services (open up the ports in the firewall) as well:
firewall-cmd --permanent --add-service="http"
firewall-cmd --permanent --add-service="https"