I heard many positive opinions about Caddy and Podman, so let’s try using them.
Why Caddy?
Caddy offers automatic HTTPS out-of-the-box, a straightforward configuration file syntax, support HTTP/2 and HTTP/3 by default, built-in security, and a modular design.
Why Podman?
Podman is daemonless, which simplifies container management and eliminates a potential central point of failure. Its native support for rootless containers enhances security by reducing the need for privileged operations.
Caddy
Let’s create directories to store the Caddy configuration, data, logs, and website content.
mkdir -p ~/containers/caddy/configmkdir -p ~/containers/caddy/datamkdir -p ~/containers/caddy/logsmkdir -p ~/containers/caddy/sites/<site-name>
Below is an example of a Caddy configuration file for a single static site:
{ email <email-address>}
<domain> { root * /srv/<domain> encode zstd gzip header { Cache-Control max-age=3600 }
file_server { precompressed br gzip }
handle_errors { rewrite * /404.html file_server }
log { format json output file /var/log/caddy/<domain>_access.log { roll true roll_size 1gb roll_keep 5 roll_keep_for 720h } }}
- It serves content from a specified directory.
- It enables compression with Brotli, Zstandard, and gzip.
- It sets a cache-control header with a maximum age of 1 hour.
- It adds 404 handling by rewriting requests to a custom error page.
- It writes logs to an access file with automatic rotation.
Now it’s time to run the server.
Podman
We can use Podlet to generate a Podman Quadlet file from a Podman command.
sudo dnf install podman podlet
Note that when using rootless containers, ports 80 and 443 cannot be used directly because ports below 1024 are restricted to privileged users. There are several options:
- Run Podman as root (which is not preferred).
- Grant low-numbered port access to Podman (for example, using a tool like
setcap
,sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/binary
). - Expose a privileged port through systemctl by adjusting system settings (like adding
net.ipv4.ip_unprivileged_port_start=443
to/etc/sysctl.conf
) - Redirect a non-privileged port to ports 80 and 443 using iptables or firewalld.
There are probably more options available, but let’s choose the last one. For example, we can redirect port 1880 to 80 and port 1443 to 443 using firewalld.
sudo systemctl enable firewalldsudo systemctl start firewalldsudo firewall-cmd --permanent --add-forward-port=port=443:proto=tcp:toport=1443sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=1880sudo firewall-cmd --reloadsudo firewall-cmd --list-all
Generate quadlet caddy.container
file.
podlet --file . --install --description Caddy podman run --name caddy --restart always -p 1880:80 -p 1443:443 -v ~/containers/caddy/config:/etc/caddy:ro -v ~/containers/caddy/sites:/srv:ro -v ~/containers/caddy/data:/data -v ~/containers/caddy/logs:/var/log/caddy docker.io/library/caddy:2.9.1
It will produce:
[Unit]Description=Caddy
[Container]ContainerName=caddyImage=docker.io/library/caddy:2.9.1PublishPort=1880:80PublishPort=1443:443Volume=/home/<user>/containers/caddy/config:/etc/caddy:roVolume=/home/<user>/containers/caddy/sites:/srv:roVolume=/home/<user>/containers/caddy/data:/dataVolume=/home/<user>/containers/caddy/logs:/var/log/caddy
[Service]Restart=always
[Install]WantedBy=default.target
Move it to the appropriate directory.
mkdir -p .config/containers/systemdmv caddy.container .config/containers/systemd/
Reload the systemd daemon, and start the server.
systemctl --user daemon-reloadsystemctl --user start caddy
In case of an error, you can check the status of the service or view detailed log output using
systemctl --user status caddy.service
and
journalctl --user -xeu caddy.service
commands.
By default, the service stops when a user logs out. To prevent this, enable lingering for your user account. Lingering allows your user services to continue running even when you’re not logged in.
loginctl enable-linger <user>
That’s all. The server will run, serve the files you store in the designated site folder, and automatically start on system boot. This is a basic configuration, so please adjust it to suit your needs.