Rootless container/host networking in Podman, without the hassle

Podman Linux Containers

I’m guessing that you’re here because you want to run an application in a Podman container, and access it from the host.

For example, you’re running Podman on Linux, and you want to be able to run a component in a rootless container – such as a database, a message broker, or a data cache – and access it from your application.

You can do this with port publishing, but how do you do it without needing to do that?

One solution is to choose your networking option wisely. There is one network mode which makes host networking rather simple. Let’s have a quick look at network modes first.

Network modes control how your container interacts with other systems

The thing you need to know about Podman is that, like docker, it has a few different network modes.

A mode changes the networking capabilities of the container – like which other containers it can interact with, or whether it can see the host.

Industrial switch with cabled connectors
To play with containers, choose your network mode
(Brett Sayles)

Podman has a few different network modes which you can set on a container:

Mode What it does
bridge Creates a network stack on the default bridge network
none No networking is set up at all
container:<id> Uses the same network as another container with ID id
host Uses the host’s network stack
network-id Uses a user-defined network (which you can create using podman network create ...)
ns:<path> Joins a network namespace found at path <path>
private Creates a new network namespace for the container
slirp4netns Creates a user network stack with slirp4netns (This is the default option for rootless containers.)

As you can see there’s a mind-boggling array of options.

The mode I’ve highlighted, the host mode, is the simplest solution for host-to-container and container-to-host networking. We’ll look at that next.

For simple container-to-host networking, connect your container to the host network

In the ‘host’ network mode, a container shares the host’s networking namespace; which means it shares the same network interface, routing tables and so on, so it can ‘see’ the same things that the host can.

Being able to sharing the same network interface and routing tables can be really useful, because it means that your container can see and access services as if it was a regular (non-container) process. And your host can see and access services running in containers.

Use the host network to access the container’s port from the host

Let’s see the host network in action, to see how we can access a service running in a container, from the host.

We’ll use podman run to run a process in a new, rootless container, and add --network=host to attach it to the host network:

podman run --network=host nginxinc/nginx-unprivileged

The Nginx web server is now running on port 8080, inside a container.

(The nginx-unprivileged image is a variation on the standard nginx image, which is configured to run Nginx on an unprivileged port.)

If I go to my web browser on the host and access http://localhost:8080, I’ll see the nginx welcome page:

Firefox browser showing the nginx welcome page on localhost:8080
When a rootless container is connected to the host network, you can access its ports from outside the container

How is that? I didn’t configure any port publishing or forwarding…..

Since the container is connected to the host network, it binds to a port in the host’s network namespace. This is another way of saying that it binds to a port on the host.

You don’t need to set up any extra port publishing, or forwarding, or anything like that. With host network mode, the network is shared between the host and the container. Stuff on localhost in the container can be accessed on localhost from the host.

On the host network, a container can also access ports on the host

When you use the host network mode, you can also access ports on the host from inside the container.

(This is why it’s considered somewhat insecure.)

On my host operating system, I’m running Apache web server on port 80. I use curl to make a request to the server and get a silly little test page I created:

$ curl http://localhost:80
Hello, internet friend!

Now what happens when I run that same curl http://localhost:80 command, but inside a container that’s configured with the host network mode?

$ podman exec -it 8918c8ebbbfd curl http://localhost:80
Hello, internet friend!

I get the same result! My container able to hit the web server that’s running on my host, simply using localhost.

So when a rootless container uses the host network mode, it can access ports on the host, too, using the localhost address.

Next steps

I hope you got 🌠 VALUE 🌠 out of this article and it’s helped save you some time when setting up ports and networking with your rootless Podman containers.

Don’t forget you shouldn’t really use this in production. But it’s a time-saver for development and lets you run software in containers very easily without fiddling about with port publishing.

Want to learn something else next? I recommend these: