return to main page
status: experimental
graph TB
a1[curl localhost:80] -.->a2[nginx container in systemd system service with directive User=]
Set up a systemd system service example3.service that is configured to run as the user test3 (systemd configuration User=test3
)
where rootless podman is running the container image docker.io/library/nginx.
Configure socket activation for TCP port 80.
The default configuration for ip_unprivileged_port_start can be used
$ cat /proc/sys/net/ipv4/ip_unprivileged_port_start
1024
Unprivileged users can only listen on TCP port 1024 and above.
The reason the unprivileged user test3 is able to run a socket-activated nginx container on port 80 is that
the syscalls socket()
and bind()
were run by the systemd system manager (systemd
) which is running as root.
The socket file descriptor is then inherited by the rootless podman process.
Side note: There is a Podman feature request
for adding Podman support for User=
in systemd system services.
The feature request was moved into a GitHub discussion.
These instructions were tested on Fedora 39 with Podman 4.7.2.
- Create the user test3
$ sudo useradd test3
- Check the UID of the user test3
$ id -u test3 1000
- Create the file /etc/systemd/system/example3.service with the contents
[Unit] Wants=network-online.target After=network-online.target Requires=user@1000.service After=user@1000.service RequiresMountsFor=/run/user/1000/containers [Service] User=test3 Environment=PODMAN_SYSTEMD_UNIT=%n KillMode=mixed ExecStop=/usr/bin/podman rm -f -i --cidfile=/run/user/1000/%N.cid ExecStopPost=-/usr/bin/podman rm -f -i --cidfile=/run/user/1000/%N.cid Delegate=yes Type=notify NotifyAccess=all SyslogIdentifier=%N ExecStart=/usr/bin/podman run \ --cidfile=/run/user/1000/%N.cid \ --cgroups=split \ --rm \ --env "NGINX=3;" \ -d \ --replace \ --name systemd-%N \ --sdnotify=conmon \ docker.io/library/nginx
- Edit the file /etc/systemd/system/example3.service and replace
1000
with the UID found in step 2. - Optional step for improved security: Edit the file /etc/systemd/system/example3.service
and add the option
--network none
to thepodman run
command. For details, see section Possibility to restrict the network in the container - Create the file /etc/systemd/system/example3.socket with the contents
[Unit] Description=Example 3 socket [Socket] ListenStream=0.0.0.0:80 [Install] WantedBy=sockets.target
- Reload the systemd configuration
$ sudo systemctl daemon-reload
- Start the socket
$ sudo systemctl start example3.socket
- Test the web server
$ curl -s localhost:80 | head -4 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>