Ubuntu 24.04 ships with a fully‑featured Podman package that works out of the box.
Rootless mode lets a normal user spin up containers without any privileged
operations, which is a great fit for a home lab or a small self‑hosted service.
Below is a step‑by‑step guide to build a minimal Nginx image, run it rootlessly,
and keep the whole thing under tight, sane defaults.
Prerequisites
- Ubuntu 24.04 (LTS) installed on a machine or VM.
- A non‑root user with sudo privileges (the example assumes
alice). - Basic knowledge of the shell,
sudo, andsystemd.
# Verify the kernel version – user namespaces require 5.8+ (Ubuntu 24.04 uses 6.6)
uname -r
# Install Podman if it isn’t already
sudo apt update
sudo apt install -y podman
Enable rootless mode
Podman automatically falls back to rootless when run as a normal user, but you should confirm that the user‑namespace mapping is in place:
podman info | grep -i userns
If you see userns: true, you’re good to go.
If not, add the following to /etc/subuid and /etc/subgid:
echo "alice:100000:65536" | sudo tee -a /etc/subuid /etc/subgid
Then log out and back in.
Building a Tiny Nginx Image
The official nginx:alpine image is already lightweight (~20 MB).
We’ll add a minimal configuration and a single static page.
# Dockerfile
FROM nginx:alpine
# Remove the default config
RUN rm /etc/nginx/conf.d/default.conf
# Add our own minimal config
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Add a simple index page
RUN mkdir -p /usr/share/nginx/html && \
echo "<h1>Hello from rootless Podman!</h1>" > /usr/share/nginx/html/index.html
# Expose HTTP
EXPOSE 80
nginx.conf:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Build the image locally:
podman build -t tiny-nginx .
The resulting image is ~25 MB – small enough to pull from a remote registry or build locally on a low‑bandwidth connection.
Running the Container Rootlessly
Direct run
podman run -d --name tiny-nginx \
-p 8080:80 \
--restart=always \
tiny-nginx
-d– detach.--name– gives the container a friendly name.-p 8080:80– maps host port 8080 to container port 80.--restart=always– ensures the container restarts after a reboot.
Open a browser to http://localhost:8080 – you should see the “Hello” page.
Using a systemd user unit
Rootless containers are best managed with systemd user units.
Create ~/.config/systemd/user/containers-tiny-nginx.service:
[Unit]
Description=Rootless Tiny Nginx
After=network-online.target
[Service]
Restart=always
ExecStart=/usr/bin/podman run --rm --name tiny-nginx -p 8080:80 tiny-nginx
ExecStop=/usr/bin/podman stop -t 10 tiny-nginx
ExecStopPost=/usr/bin/podman rm -f tiny-nginx
[Install]
WantedBy=
See also
- How I Prevented a Rootless Podman Container From Filling My Disk With Logs
- Recovering a single config file from a corrupted Borg backup without restoring the whole archive
- Preventing Rootless Podman from Filling Up My Home Directory with Container Logs
- Running My Home NAS Backups with `nice` and `ionice` So My Desktop Never Freezes
- Docker builds on a 32 GB Raspberry Pi: How I recovered from a full disk