Happy Friday! Today we are tackling the single most confusing topic in modern RHEL administration.
We are going to deploy a containerized service. Sounds easy, right? podman run and you're done?
Wrong.
Today, you must deploy a Rootless Container that integrates fully with the host system. This changes the rules of everything: networking, file permissions, and startup behavior. If you miss one flag, it fails silently.
You need to deploy an Nginx web server container.
The Constraints (The Nightmare):
web_dev. You are NOT allowed to run Podman as root/sudo./home/web_dev/html.The Map:
Rootless containers break standard rules. Use these maps to find your way back:
man podman-generate-systemd (Or man podman-systemd.unit for Quadlets)man loginctl (The secret to reboot survival)man podman-run (Look for the :Z option)You need to navigate 4 specific traps to make this work. How do you solve them?
Nginx wants to listen on port 80 inside the container. You map it to host port 80 (-p 80:80). It fails immediately "Permission Denied."
You map the volume: -v /home/web_dev/html:/usr/share/nginx/html. The container starts, but Nginx gives a 403 Forbidden because SELinux blocked access to the host files.
:?)You generated the Systemd unit file. You enabled it with systemctl --user enable container-nginx. You reboot the server. The container does not start. It only starts when you SSH in as web_dev.
loginctl command must you run to allow this user's services to start at boot without an active session?The container is running on a high port (e.g., 8080). You opened port 8080 in firewall-cmd, but external users still can't connect.
Good luck!
Hello
To answer the questions:
Trap 1:
The option of -p 8080:80 would allow for a non-root user to map from port 8080 on the host to the port 80 on the container.
Ports on the host numbered from 1-1023 are priveleged ports which require root level access to bind to a process.
Trap 2:
Adding an uppercase Z to the end of the volume mount as follows will resolve the SE Linux permissions issue:
-v /home/web_dev/html:/usr/share/nginx/html:Z
This will allow the container exclusive acccess to the bind mount. Using a lowercase z would permit other containers to share access to the bind mount.
Trap 3:
Using loginctl enable-linger will allow for the containerized service to run on system start or reboot, even if the user is not logged in.
Trap 4:
Running the command podman port <container-id> will show the port mapping for a running container. If a host was not specified, the container is assigned the broadcast address (0.0.0.0). This means that the container is accessible from all networks on the host machine.
It is also possible to assign a specific network on the host machine to the port mapping on a container by prefixing the port mapping with an specific network on the host. For example:
-p 192.168.0.100:8080:80 <container-id>
This would allow you to fine tune your firewall rules.
@Ad_astra good job covering all the traps !
Red Hat
Learning Community
A collaborative learning environment, enabling open source skill development.