---
# System prepended metadata

title: Share Host's Network Stack with Container - Podman for example
tags: [Podman, Container]

---

# Share Host's Network Stack with Container - Podman for example

###### tags: `Container` `Podman`

## Normal Case

Have an HTTP server which listens on:
* IP: `0.0.0.0` -> any network interface
* Port: `TCP 8080`
```shell=
$ cat ./http.js 
var http = require('http');

http.createServer(function (req, res) {
  console.log ("Client: " + req.socket.remoteAddress + ":" + req.socket.remotePort);
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World!');
}).listen({host: '0.0.0.0', port: 8080});
```
Make the HTTP server run in a container:
```shell=
$ podman run -dt --rm -v ./http.js:/tmp/http.js -p 8080:8080 docker.io/library/node:alpine node /tmp/http.js
fb43918d92791448c79ebaa90e0024d4230cf3fb434546ab7208d0bc9e2db346
$ podman ps -a
CONTAINER ID  IMAGE                          COMMAND            CREATED         STATUS             PORTS                   NAMES
fb43918d9279  docker.io/library/node:alpine  node /tmp/http.js  10 seconds ago  Up 10 seconds ago  0.0.0.0:8080->8080/tcp  angry_robinson
```
In this model, it is port forwarding from host's TCP 8080 port to the contianer's TCP 8080 port.
The host can query the HTTP server locating in the container and get the response easily by:
```shell=
$ curl http://localhost:8080
Hello World!
```

## The Server only Listens on the Loopback Interface

There are some cases that the server only listens on the loopback interface, which means localhost.

However, if the server runs in a **container**, then the server is listening on the **container's loopback interface**, instead of the host's.  Since they are **different loopback interfaces**, an user on host will be failed to query the server listening on the container's loopback interface.

Here is an example that the HTTP server listens on `127.0.0.1:8080`:
```shell=
$ cat http.js 
var http = require('http');

http.createServer(function (req, res) {
  console.log ("Client: " + req.socket.remoteAddress + ":" + req.socket.remotePort);
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World!');
}).listen({host: '127.0.0.1', port: 8080});
```

### Have the HTTP Server Run in a Container like Normal Case

```shell=
$ podman run -dt --rm -v ./http.js:/tmp/http.js -p 8080:8080 docker.io/library/node:alpine node /tmp/http.js
636d8b6dfe2b07c487a5019682bfaf9b64b10adb9e2bfdc5be3d1cd1ddcea9d0
$ podman ps -a
CONTAINER ID  IMAGE                          COMMAND            CREATED       STATUS            PORTS                   NAMES
636d8b6dfe2b  docker.io/library/node:alpine  node /tmp/http.js  1 second ago  Up 2 seconds ago  0.0.0.0:8080->8080/tcp  gallant_chatelet
```

Try to query the HTTP server locating in the container from host:
```shell=
$ curl http://localhost:8080
curl: (56) Recv failure: Connection reset by peer
```
The query is failed to have a connection.  Because, it tried to query an HTTP server listening on host's loopback interface, which does not exist.

### Have the HTTP Server Run in a Container Sharing Host's Network Stack

There is the option [`--network=mode`](https://docs.podman.io/en/latest/markdown/podman-run.1.html#network-mode-net) mentioned in Podman's document:
```
--network=mode, --net
...
  * host: Do not create a network namespace, the container will use the host’s network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
...
```
Since the option `--network=host` can force the container **share the same network stack** with the host, the container shares **the same loopback interface** with the host as well.

Have the HTTP server run in a container with `--network=host`:
```shell=
$ podman run -dt --rm -v ./http.js:/tmp/http.js --network=host docker.io/library/node:alpine node /tmp/http.js
a810e197824ac04a47ce829b234767274a27eeb786e6c18094606b61f10bc6fd
$ podman ps -a
CONTAINER ID  IMAGE                          COMMAND            CREATED        STATUS            PORTS       NAMES
a810e197824a  docker.io/library/node:alpine  node /tmp/http.js  2 seconds ago  Up 3 seconds ago              gracious_vaughan
```
Try to query the HTTP server locating in the container from host again:
```shell=
$ curl http://localhost:8080
Hello World!
```
Now, it works!