<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<atom:link href="https://seanbehan.ca/posts/tag/podman/rss.xml" rel="self" type="application/rss+xml" />
		<title>Sean Behan — Podman</title>
		<link>https://seanbehan.ca/posts/tag/podman</link>
		<description>Posts tagged “Podman”.</description>
		<language>en-CA</language>
		<!-- RSS wants an address here and readers show the name beside it. -->
		<managingEditor>sean@seanbehan.ca (Sean Behan)</managingEditor>
		<webMaster>sean@seanbehan.ca (Sean Behan)</webMaster>
		<lastBuildDate>Mon, 24 Aug 2026 08:56:20 GMT</lastBuildDate>
		<item>
		<guid isPermaLink="true">https://seanbehan.ca/posts/quadlets</guid>
		<title><![CDATA[Podman Quadlets]]></title>
		<description><![CDATA[Quadlets describe a container as a systemd unit, so systemd owns the lifecycle instead of Podman.]]></description>
		<link>https://seanbehan.ca/posts/quadlets</link>
		<pubDate>Fri, 28 Mar 2025 14:39:58 GMT</pubDate>
		<category>linux</category><category>systemd</category><category>podman</category><category>containers</category><category>quadlet</category>
		<content:encoded><![CDATA[<!--[--><h3>What are Quadlets?</h3> <p>In this post I’ll show you what a quadlet is and how you can use it to manage
your containers.</p> <p>Quadlets are a new way to manage containers using systemd. They are a new
format for systemd units that allow you to manage containers using systemd.</p> <h3>Container Quadlets</h3> <p>Here’s an example of a container quadlet.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/library/alpine:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Exec</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">sleep infinity</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span></code></pre><!----> <p>If you put this in ~/.config/containers/systemd/alpine.container you can start
it with <code>systemctl --user start alpine</code> and it will start a new container.</p> <p>Just make sure to <code>systemctl --user daemon-reload</code> to reload the systemd daemon
after you create the quadlet. You have to do this every time, I won’t repeat
this throughout the blog post.</p> <h3>Pod Quadlets</h3> <p>You can also use quadlets to manage pods. Here’s an example of a pod quadlet.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Pod]</span></span></code></pre><!----> <p>Yep, that’s it. If you put it in <code>~/.config/containers/systemd/mypod.pod</code> you can
start it with <code>systemctl --user start mypod-pod</code> and it will start a new pod.</p> <p>But the best part is this. If you want to add a container to a pod all you have
to do is this.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/library/alpine:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Exec</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">sleep infinity</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Pod</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">mypod.pod</span></span></code></pre><!----> <p>Now when you start <code>mypod-pod</code> it will start the container as well.</p> <h3>Dependencies</h3> <p>You can add dependencies.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Unit]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">After</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">alpine.service</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/library/archlinux:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Exec</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">sleep infinity</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Pod</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">mypod.pod</span></span></code></pre><!----> <p>Now archlinux will start after alpine.</p> <p>There are even more options. You can start .kube, .network, and .build quadlets
too and they can depend on each other. See the <a href="https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html" rel="nofollow noopener noreferrer" target="_blank">docs</a> for more info!</p> <hr/> <h3>Example: Nginx and Certbot</h3> <p>Okay so now lets run something useful :)</p> <p>How about an nginx container and a certbot container to get a certificate for it?</p> <h3>Nginx Container</h3> <p>First lets create a directory to hold our files.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">mkdir</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ~/.config/containers/systemd/www</span></span></code></pre><!----> <p>Next we create a quadlet for our nginx container.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/nginx:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">PublishPort</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:80</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">PublishPort</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">443</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:443</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">./www:/usr/share/nginx/html</span></span></code></pre><!----> <p>This will run a web server for us. If you aren’t root, you’ll need to enable unprivleged ports.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">sudo</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> sysctl</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> net.ipv4.ip_unprivileged_port_start=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0</span></span></code></pre><!----> <p>Now we can start it with <code>systemctl --user start nginx</code> and it will start a new container.</p> <p>If you browse to <code>http://localhost</code> you should see the nginx welcome page.</p> <h3>Certbot Container</h3> <p>Now we need to get a certificate for it. We can use certbot for this.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/certbot/certbot:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">letsencrypt:/etc/letsencrypt</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">./www:/mnt</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Exec</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">certonly --webroot --webroot-path /mnt --agree-tos --email your@email.com -d your.domain.com</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span></code></pre><!----> <p>Make sure to replace <a href="mailto:your@email.com">your@email.com</a> and your.domain.com with your own email and domain.</p> <p>Then start the container with <code>systemctl --user start certbot</code> and it will get a certificate for you.</p> <h3>Nginx with SSL</h3> <p>Now you can use the certificate in your nginx container.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/nginx:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">PublishPort</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:80</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">PublishPort</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">443</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:443</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">letsencrypt:/etc/letsencrypt</span></span></code></pre><!----> <p>That’s great, but now we need to configure nginx to use the certificate. We can
do this by adding a volume for the configuration file.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/nginx:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">PublishPort</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:80</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">PublishPort</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">443</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:443</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">letsencrypt:/etc/nginx/certs</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">./nginx.conf:/etc/nginx/conf.d</span></span></code></pre><!----> <p>Along with a configuration file for nginx.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> &#123;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    listen </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">443</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ssl;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    server_name </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">your.domain.com;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    ssl_certificate </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/etc/nginx/certs/live/your.domain.com/fullchain.pem;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    ssl_certificate_key </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/etc/nginx/certs/live/your.domain.com/privkey.pem;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    location</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> / </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#123;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        root </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/usr/share/nginx/html;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        index </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">index.html;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#125;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#125;</span></span></code></pre><!----> <p>Again, make sure to replace your.domain.com with your own domain.</p> <p>Now you can start the container with <code>systemctl --user start nginx</code> and it will
start a new container with the certificate. You can verify this by going to <code>https://your.domain.com</code>.</p> <p>Now you have a web server with HTTPS.</p> <h3>Automatic Certificate Renewal</h3> <p>If you want to renew your certificate automatically it’s as simple as this.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Container]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Image</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">docker.io/certbot/certbot:latest</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Exec</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">renew</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">AutoUpdate</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">registry</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Volume</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">letsencrypt:/etc/letsencrypt</span></span></code></pre><!----> <p>Now you can create a timer for it in <code>~/.config/systemd/user/certbot.timer</code>.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Unit]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Description</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">Renew Certbot certificates</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Timer]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">OnCalendar</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">Sun </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">00</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:00:00</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Persistent</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Unit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">certbot.service</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">[Install]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">WantedBy</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">timers.target</span></span></code></pre><!----> <p>Now you enable the timer.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">systemctl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --user</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> enable</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --now</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> certbot.timer</span></span></code></pre><!----> <p>Now your certificate will be renewed every Sunday at midnight.</p> <p>That’s it! Now you have a web server with HTTPS and a certificate that will be
renewed automatically.</p><!--]-->]]></content:encoded>
	</item>
<item>
		<guid isPermaLink="true">https://seanbehan.ca/posts/x11docker</guid>
		<title><![CDATA[Using X11Docker for secure GUI applications]]></title>
		<description><![CDATA[Running GUI applications like telegram-desktop inside a container with x11docker, xpra and Wayland.]]></description>
		<link>https://seanbehan.ca/posts/x11docker</link>
		<pubDate>Thu, 07 Oct 2021 20:51:51 GMT</pubDate>
		<category>docker</category><category>podman</category><category>graphics</category>
		<content:encoded><![CDATA[<!--[--><h3>Introduction</h3> <p>X11Docker is a nice command line tool that allows you to run graphical
applications inside podman or docker by passing them to xpra or your wayland
socket. To do this you first need a <code>Containerfile</code> or <code>Dockerfile</code> to build an
image with the application you want to run. In this example I’m going to run <code>telegram-desktop</code>.</p> <h3>Building a Container Image</h3> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span>FROM ubuntu:latest</span></span>
<span class="line"><span></span></span>
<span class="line"><span>RUN apt-get update</span></span>
<span class="line"><span>RUN apt-get install -y telegram-desktop</span></span>
<span class="line"><span></span></span>
<span class="line"><span>CMD ["telegram-desktop"]</span></span></code></pre><!----> <h3>Running the Application with X11Docker</h3> <p>We build this image with <code>podman build . -t telegram</code> and wait for it to
install our packages. When it’s done we can simply run it with <code>x11docker localhost/telegram</code> and it starts Telegram in Xpra.</p> <h3>Running with Wayland</h3> <p>If we wanted to start it under Wayland instead, we could run <code>x11docker --wayland localhost/telegram</code> however the package for Telegram on Ubuntu
doesn’t seem to have support for Wayland when I tried it.</p> <p>This should work for any graphical software, even that which isn’t in the
repositories. You can even install more than one piece of software in a single
image. Then you pass the CMD as an argument to x11docker like so <code>x11docker localhost/telegram telegram-desktop</code>.</p><!--]-->]]></content:encoded>
	</item>
<item>
		<guid isPermaLink="true">https://seanbehan.ca/posts/podman-systemd</guid>
		<title><![CDATA[Podman Auto Updating Systemd Services]]></title>
		<description><![CDATA[podman generate systemd plus an autoupdate label: containers that start on boot and update themselves.]]></description>
		<link>https://seanbehan.ca/posts/podman-systemd</link>
		<pubDate>Thu, 23 Sep 2021 14:34:43 GMT</pubDate>
		<category>linux</category><category>docker</category><category>podman</category>
		<content:encoded><![CDATA[<!--[--><h3>Introduction</h3> <p>Podman<a href="https://podman.io" rel="nofollow noopener noreferrer" target="_blank">^1</a> has a nice feature called <code>generate</code> that lets you generate
different kinds of configuration files for starting pods. One that I use often
is <code>podman generate systemd</code> which generates a new user service that can be
started with <code>systemctl --user start container-yourcontainer.service</code> or
enabled.</p> <h3>Auto-Updating Containers</h3> <p>If you want your container to auto update you can simply pass it the flag <code>--label "io.containers.autoupdate=registry"</code> when you’re creating it. The
systemd service will automatically pull the latest versions of containers
before starting them. You can manually update your container images now using <code>podman auto-update</code>.</p> <p>If you want to update your images on a schedule you can enable the <code>podman-auto-update.timer</code> using <code>systemctl --user enable --now podman-auto-update.timer</code> which will auto update your containers every Monday
morning.<a href="https://fedoramagazine.org/auto-updating-podman-containers-with-systemd/" rel="nofollow noopener noreferrer" target="_blank">^2</a></p> <h3>Kubernetes YAML Generation</h3> <p>You can also generate a Kubernetes YAML configurations using <code>podman generate kube</code>. This can then be loaded in Kubernetes to run your containers.</p><!--]-->]]></content:encoded>
	</item>
<item>
		<guid isPermaLink="true">https://seanbehan.ca/posts/podman-crun</guid>
		<title><![CDATA[Podman crun and cgroups v2]]></title>
		<description><![CDATA[Getting Podman onto cgroups v2 and crun on distributions that still default to cgroups v1 and runc.]]></description>
		<link>https://seanbehan.ca/posts/podman-crun</link>
		<pubDate>Sun, 19 Sep 2021 03:09:02 GMT</pubDate>
		<category>linux</category><category>docker</category><category>podman</category>
		<content:encoded><![CDATA[<!--[--><h3>Introduction</h3> <p>Podman<a href="https://podman.io" rel="nofollow noopener noreferrer" target="_blank">^1</a> is a container management software similar to Docker that can run
OCI containers as regular users (not root) by using container management
libraries such as crun or runc, and cgroups v1 or v2. It can be used as a
drop-in replacement for Docker and supports docker-compose using
podman-compose.</p> <p>Unfortunately for some distributions after installing podman the operating
system defaults to cgroups v1 and runc, not cgroups v2 and crun. As was the
case on Rocky Linux for me.</p> <h3>Switching to crun</h3> <p>First we can switch to crun instead of runc by installing crun with our package
manager. It was already installed for me, but on Fedora you would use <code>sudo dnf install crun</code></p> <p>Then you can edit the file <code>/usr/share/containers/containers.conf</code> and change
the line <code>runtime = "runc"</code> to <code>runtime = "crun"</code>. Now you can verify that
you’re using crun with <code>podman info | grep crun</code>.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span>name: crun</span></span>
<span class="line"><span>package: crun-0.20.1-1.module+el8.4.0+643+525e162a.x86_64</span></span>
<span class="line"><span>path: /usr/bin/crun</span></span>
<span class="line"><span>  crun version 0.20.1</span></span></code></pre><!----> <h3>Enabling cgroups v2</h3> <p>Now the harder part was enabling cgroups v2. Luckily I found a <a href="https://github.com/containers/podman/issues/9410#issuecomment-785840320" rel="nofollow noopener noreferrer" target="_blank">comment</a> on a GitHub issue outlining the steps you need to complete to get cgroups v2 to
work.</p> <p>First we can enable it in the kernel with</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span>sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"</span></span></code></pre><!----> <p>Then we can enable linger. This will also allow our containers to remain
running after logging out.</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span>sudo loginctl enable-linger codebam</span></span></code></pre><!----> <p>Then the last step which made everything work for me is to set the <code>pid_limit=0</code>. For me it was in <code>/usr/share/containers/containers.conf</code> instead
of <code>/etc/containers/</code>.</p> <h3>Verification</h3> <p>Now you can reboot. <code>podman info | grep cgroup</code> should say</p> <!----><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code><span class="line"><span>cgroupControllers: []</span></span>
<span class="line"><span>cgroupManager: systemd</span></span>
<span class="line"><span>cgroupVersion: v2</span></span></code></pre><!----> <p>Now we’re using cgroups v2 and crun.</p><!--]-->]]></content:encoded>
	</item>
	</channel>
</rss>