Docker Alternative with Podman, Cockpit, and Nginx Proxy Manager

In this tutorial, we installing an Ubuntu Linux Server with the latest version 21.04. Instead of Docker, we’re using Podman to containerize our applications, and Cockpit to manage our entire Linux server with a nice graphical web interface. So you can still manage containers on your Linux server easily and securely! And of course, we’re protecting our web interface with trusted SSL certs.

Why should we want to replace Docker?

If you follow my YouTube Channel and my tutorial, you know that I absolutely love Docker. And I don’t think there is necessarily something bad about it, but still, it’s always good to have alternate options. Podman is a very nice alternative to Docker because it just uses the same syntax.

It also has some security advantages over Docker. If you want to learn more about Podman and the technical differences, check out my YouTube Video about Docker vs Podman.

You could also combine parts of this tutorial, like the Cockpit Project with Portainer and Docker of course.

How to install Podman

You can install Podman on Linux, Mac OS, or Windows. In our example, because we’re using Ubuntu 21.04, we can just install it from the Ubuntu repository.

sudo apt install podman

For older Ubuntu versions or other Linux Distributions, just follow the official installation instructions.

Linux Server Management with Cockpit

Although Linux servers are often managed via the terminal, sometimes it’s nice to have a web interface. Because you can better see metrics, quickly check events, and so on.

The Cockpit-Project is such a graphical interface. It was originally developed for Red Hat Enterprise Linux and is the default management tool there. Therefore it also works the best on RHEL based Distributions, but other Distros are also supported. Especially since Ubuntu 21.04, it’s also working very well on Ubuntu.

Install Cockpit on Ubuntu 21.04

Note, if you’re using an older version of Ubuntu, I wouldn’t necessarily recommend upgrading yet. Especially if you are using the LTS version, keep running it. The only package that’s not available in older LTS versions of Ubuntu is the cockpit-podman package. So, my experience is, that it works best with Ubuntu 21.04 and probably newer versions as well.

With the following command we install cockpit and the podman extension.

sudo apt install cockpit cockpit-podman

When the installation was successful, just access it on port 9090. The interface is very easy and intuitive. You can manage your entire Linux server, update packages, set up basic configuration, and manage containers with Podman. Awesome, right?

Manage Podman containers with Podman-Compose

Now, we can start managing Podman containers with Cockpit. It’s nice to get some metrics, restart and stop containers. But to be honest, the Cockpit-Podman extension is missing some crucial features, when creating them. You can’t even edit Container configuration files, once they are deployed. Something that’s possible with Docker and Portainer, for example.

Therefore, I’ve searched for another method to comfortable manage containers in the CLI. And my preferred solution is Podman-Compose, which is an implementation of the Docker-Compose tools with Podman in the backend. It’s a Python script we can simply install via the following commands.

sudo apt install pyton3-pip

pip3 install podman-compose

# You can also put this command into your .bashrc or .zshrc file to make it persistent!
export PATH=$PATH:$HOME/.local/bin

Managing Pods and Containers with Podman-Compose is pretty easy, just like Docker-Compose. One difference I’ve recognized is, that you need to create any volume folders first before starting the containers!

Protect Cockpit with a Reverse Proxy

To easily protect Cockpit with trusted SSL certs, we will use the Nginx Proxy Manager. It’s very easy to configure, because it also has a web interface. And we can use Podman and Podman-Compose to deploy it simply on our server!

I’ve done several videos and tutorials on Nginx Proxy Manager. If you want to learn more about it and how to deploy it also with Docker, check out my other tutorial.

Change unprivileged ports

Before we can start running Podman containers rootless we need to configure unprivileged ports. Because by default Podman doesn’t allow us to expose any ports lower than 1024, without root privileges.

Simply open the /etc/sysctl.conf file and add this line at the end.


Deploy Nginx Proxy Manager

Let’s create a new project folder in the /opt directory called /opt/npm. We should also create folders for our persistent volumes.

sudo mkdir -p /opt/npm /opt/npm/data /opt/npm/ssl /opt/npm/db

sudo chown <username>:<username> -R /opt/npm

Once we have created all folders, let’s create a new compose file called “docker-compose.yaml” in the /opt/npm directory.

version: '3'
     image: ''
       - '80:80'
       - '81:81'
       - '443:443'
       DB_MYSQL_HOST: "db"
       DB_MYSQL_PORT: 3306
       DB_MYSQL_USER: "npm"
       DB_MYSQL_PASSWORD: "npm"
       DB_MYSQL_NAME: "npm"
       - /opt/npm/data:/data
       - /opt/npm/ssl:/etc/letsencrypt
     image: ''
       MYSQL_DATABASE: 'npm'
       MYSQL_USER: 'npm'
       MYSQL_PASSWORD: 'npm'
       - /opt/npm/db:/var/lib/mysql

We can start our services from inside the /opt/npm directory with the following command.

podman-compose up -d

Then you should be able to access the web interface of Nginx Proxy Manager on Port 81.

Authenticate with the default username “[email protected]” and the default password “changeme“.

Configure a new Proxy Host

For the Cockpit web interface, we can simply create a new proxy host. This will obtain trusted SSL certificates and expose them securely.

Add a new Proxy Host and make sure you select the port HTTPS because Cockpit is using HTTPS by default. As a Forward Hostname / IP just use the internal or public IP address of your server. If you use the internal IP address, you can limit the listening address of Cockpit later. With this method, you’re disabling access from external networks without going through the reverse proxy!

In this example I’ve used the public DNS name “” and forwarded it to the internal IP address of my server, using the Cockpit Port 9090.

Let’s test if we’re able to connect with the domain name. And you can see our connection to Cockpit is now secured via a trusted SSL cert.

Stop listening on Port 9090

Let’s also limit the access to our Cockpit Web Interface. Because you could still just use the public IP address on port 9090 to access Cockpit. If you have used the servers internal IP address in Nginx Proxy Manager, you can now limit the access on this IP address. So that only Nginx Proxy Manager and other internal servers are able to connect to our administrative interface.

Create a new file /etc/systemd/system/cockpit.socket.d/listen.conf and add the following lines.


To make these settings active execute the following commands in the terminal.

sudo systemctl daemon-reload

sudo systemctl restart cockpit.socket

And now you can only access your Cockpit web interface through a secured reverse proxy! I think it’s a nice alternative to Docker. And with the Cockpit UI you also have a cool amazing system to manage your Linux server.

11 thoughts on “Docker Alternative with Podman, Cockpit, and Nginx Proxy Manager”

  1. Hallo, super Artikel! Hat mir viel geholfen.
    Unter Opensuse MicroOS hatte ich aber Probleme Podman-Compose zum Laufen zu bekommen. Daher habe ich mir den Compose File für NPM in Podman Kommandos übersetzt.
    Vielleicht kann das Jemand brauchen:
    podman pod create –name=npm-pod -p 80:80 -p 443:443 -p 81:81

    podman run –label “io.containers.autoupdate=image” –name=npm_app -d –pod=npm-pod -e DB_MYSQL_HOST= -e DB_MYSQL_PORT=3306 -e DB_MYSQL_USER=npm
    -v /home/pod/opt/npm/data:/data:z -v /home/pod/opt/npm/ssl:/etc/letsencrypt:z

    podman run –label “io.containers.autoupdate=image” –name=npm_db -d –pod=npm-pod -e MYSQL_PASSWORD=npm -e MYSQL_DATABASE=npm -e MYSQL_USER=npm -e MYSQL_ROOT_PASSWORD=npm -e MYSQL_ROOT_PORT=3306 -v /home/pod/opt/npm/db:/var/lib/mysql:z

    Funktioniert so bei mir.

  2. Hat auf meinem NetCup Rootserver wunderbar funktioniert.
    Was mir noch fehlen würde wäre eine –restart=always funktion für nginx,
    laut github issues scheint es aber damit einige Probleme zu geben.

    • Zitat: “We cannot support ‘–unless-stopped’ as it implies the container will be
      restarted after a reboot, but Podman cannot do this. Docker has a daemon
      that starts on boot and it uses this to start containers on boot; Podman
      does not have a daemon and this cannot do the same. This limitation is
      documented in the manpages.

      We recommend using Systemd unit files from ‘podman generate systemd’ if you
      wish to autostart containers on boot.”

  3. This was a great tutorial, and I hoped it would help me get started with running my homelab services in podman containers. However, I never got the `podman-compose up -d` to work. I’m trying this on Fedora Server, so I don’t believe the fault is with you or your tutorial because you did this on tutorial on Ubuntu 21.04. The pod never started correctly, because of what I believe to be SELinux blocking the mariadb container from accessing the volumes. So although the container for nginx started, the mariadb container exited with errors, so when I attempted to go to port 81 Nginx Proxy Manger web interface never came up.

    Do you have content or are you planning similar content that runs on Fedora Server? If not that’s okay, Ubuntu Server is a wonderful distribution and perhaps one that would be easier for me to learn podman as evidence of my struggles. I just figured since podman came out of the Fedora/CentOS/RedHat family I would try your tutorial on there.

    Also, since your example showed podman running Nginx Proxy Manager rootless, is there an advantage in building the container and its volumes in /opt instead of /home?

    Thanks for your great content. As mentioned I don’t thing my struggles were the result of your content, but my distro of choice. Thanks.

  4. For some reason with the mentioned docker-compose.yaml my application is not able to find the database.
    it is up and running, but name resolution does not seem to be working for some reason. Did i miss something?
    Also i have to mention i am running it on RHEL / CentOS. I temporarily disabled firewalld, and also i added “:Z” to the volumes for selinux to work.

    db_1 | 2021-11-30 8:21:44 0 [Note] Reading of all Master_info entries succeeded
    db_1 | 2021-11-30 8:21:44 0 [Note] Added new Master_info ” to hash table
    db_1 | 2021-11-30 8:21:44 0 [Note] /usr/bin/mysqld: ready for connections.
    db_1 | Version: ‘10.4.15-MariaDB’ socket: ‘/run/mysqld/mysqld.sock’ port: 3306 MariaDB Server
    app_1 | [11/30/2021] [8:24:08 AM] [Global ] › ✖ error getaddrinfo ENOTFOUND db
    app_1 | [11/30/2021] [8:24:09 AM] [Global ] › ✖ error getaddrinfo ENOTFOUND db
    app_1 | [11/30/2021] [8:24:10 AM] [Global ] › ✖ error getaddrinfo ENOTFOUND db
    app_1 | [11/30/2021] [8:24:11 AM] [Global ] › ✖ error getaddrinfo ENOTFOUND db

    • Ok, got it myself.
      I was not using podman-compose, but docker-compose, as it is working since podman v3 (i guess).
      But i missed to install the podman dnsname plugin, which is necessary for the internal dns name resolution in docker-compose services to work within podman.

      A short: dnf install podman-plugins
      and a restart of the service fixed it.


Leave a Comment

I accept the Privacy Policy