Autostart Podman Nginx container with Quadlet
I explain how to setup a systemd service with Quadlet to ensure a rootless Nginx Podman container runs after a user logs out of the host server.
I finally got my next server at Linux ready, running just Podman. In short, Podman is the more secure version of Dockers running rootless without needing a daemon to run containers. Hence, there is a need to create a separate systemd service to ensure a container runs even when a user is logged out.
If you are new to Podman and trying to get a Nginx container running, you will notice that each time you log out of your server, the Nginx container will stop running. Once you log back into your server, the Nginx container will restart. Normally, I would do a web search or go through one of the AI chatbots; finally, after finding the right source, I could generate a working systemd for the Nginx container.
Server Setup
First, I would like to let you know about my server setup. For my AI project, I want to run Supabase on my server. Since I use Red Hat Enterprise Linux at work, I choose Rocky Linux for my projects. I could make life easier by running Coolify, a great front-end Docker container PaaS, and saving the hassle of managing my containers. Yet, since I wanted a more secure server environment, I decided to set up a server running just Podman, which gives me a mixture of containers and pods.
I am hosting the current server with Linode at the Seattle data center. I chose a Dedicated 4 GB Plan with 2 CPUs and 4 GB of RAM. I will upgrade, if needed, in the future, but this configuration should be fine.
Be sure to open the required ports with firewall-d and your WAF if you have that set up. I have SELinux enabled enforcing, but I did not have to open any ports with semanage. In a future post, I may talk more about SELinux.
Setting up Nginx with Podman
Nginx is by far my favorite httpd web server and reverse proxy. In the past, before using Coolify, I had Nginx act as the reverse proxy for my Docker containers. It is easy to set up and enable SSL certificates with Certbot, which is a breeze.
I want to run Nginx entirely on its container because why not?
Make sure you have already installed Podman. You can use the Rocky Linux Podman Guide if you need to install it.
If you like docker-compose, then also go ahead and install podman-compose.
Remember to use sudo only if it is mentioned in the commands below. You are creating a rootless Podman container. If you are running root, your systemd services must be stored in another location.
$ sudo dnf install podman
$ podman -v
podman version 5.2.2
$ sudo dnf install podman-compose
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 5.2.2
podman-compose version 1.0.6
podman --version
podman version 5.2.2
exit code: 0
Now let's use Podman run to create an Nginx container using port 8080 to access the Nginx container from the internet and link it to port 80 inside the container:
$ podman run -d -p 8080:80 nginx
You should see the following:
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ccb2c33ae5cc docker.io/library/nginx:latest nginx -g daemon o... 47 minutes ago Up 47 minutes 0.0.0.0:8080->80/tcp, 80/tcp systemd-nginx
Check to see if it is online with curl:
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
You can also check using your server IP at port 8080 in your browser:
123.YOURSERVERIP.12.1:8080
Setting up systemd with Quadlet
Now, this is where I am simplifying things for myself. In the past, I used to post a lot about my fixes to things related to SvelteKit, Ghost, Linux, etc. I decided to do this again. My frustration was remembering how to set up the system properly to get my Podman containers running while I logged out of my server.
Previously, you could use podman generate systemd to generate systemd system files, but that has been deprecated and replaced with Quadlet. One thing to note is that if you use any of the current AI chatbots, they will give incorrect information on how to set up systemd (at this time).
So, after doing some reviews, here is how I set up systemd to ensure the Nginx container remains running after I log out. I am running Podman rootless, so following each step is essential.
First, create a systemd folder for your username; remember you are running Podman rootless:
$ mkdir $HOME/.config/containers/systemd/
Then create your systemd nginx service:
$ vi .config/containers/systemd/nginx.container
Then, add the following to nginx.container:
[Unit]
Description=Nginx container
[Container]
Image=nginx
PublishPort=8080:80
[Service]
Restart=always
[Install]
WantedBy=default.target
Restart=always ensures the Nginx container will restart when the server is restarted.
RemainAfterExit=yes ensures that the Nginx container remains running after you log out of your server.
I will keep the explanation simple now. For now, you will need to enable systemd by the following:
$ systemctl --user daemon-reload
$ systemctl --user status nginx.service
$ systemctl --user start nginx.service
$ loginctl enable-linger $USER
You don't need to enable the system since the [Install] sections do this for the container in your nginx service file.
loginctl enable-linger ensures your user processes are still running after you log out.
Now log out, wait about 3-5 seconds, and then check your IP at port 8080. Nginx should still be running.
It is as simple as that.
Next post
In my next post, I will show how to get your domain to point directly to the Nginx container on port 8080 using Cloudflare's Origin Rules and SSL Certs. That is another slight headache and one reason I ran Nginx locally on the host server, acting as a reverse proxy.