cancel
Showing results for 
Search instead for 
Did you mean: 
isudoajl
Mission Specialist
Mission Specialist
  • 36.2K Views

How to map a port on RUNNING container using PODMAN?

Jump to solution

Hello!

Somebody can help me on how to do this? The main idea that I have is that I need to stop it first..

The little I have found has been with Docker platform and didtn work with Podman.

Thanks.

Labels (4)
0 Kudos
1 Solution

Accepted Solutions
Carey
Mission Specialist
Mission Specialist
  • 31K Views

i thought i saw it on DO180 class also googled. I will take it next year.

Let’s consider a situation where we forgot to do the port mapping when starting the Docker container. There would be no way to access the service from a TCP/IP connection on the host.

 

There are three ways to deal with this:

  • Start over by stopping the existing container and relaunching a new one with the same original Docker image
  • Commit the existing container and relaunch a new container from the committed Docker image, keeping the state of the container we’re trying to access
  • Add a new port mapping by manipulating the Docker configuration files

Let’s dive deep into each of these solutions.

This is a naive solution where we remove the running Docker container and relaunch it using the same Docker image. But this time, we add the port mappings that we forgot to add in the old container.

This is the simplest and most straightforward approach, but it doesn’t suit all situations.

Consider a case where we launch the Docker container (without any port mapping) and perform some operations inside it, such as installing a few packages, launching processes, updating files and so on.

 

After all these changes, we realize that the port mapping is missing. Now if we launch a new Docker container using the same old Docker image, we’ll lose all those changes.

The next approach comes to the rescue under these circumstances.

However, we should note that it’s a good practice to use Docker volumes for our important data to make it easy to replace containers.

5. Relaunch From Docker Commit

 

Instead of launching a new container from zero, we can commit the old Docker container to create a new Docker image and use that to start a new container with the right ports open.

Since we’re committing the old Docker container, the persistent state of the first will be available in the newly launched one.

Let’s try this out.

First, we’ll stop our Docker container and create its image using the docker commit command:

$ docker stop httpd-container
httpd-container
$ docker commit httpd-container httpd-image
sha256:33da33fcad051c90ac9b7dea9b2dbda442767e05ddebd8d6db8ac6893ef4ef40

Next, we’ll remove the container and start a fresh container using the image that we just created.

 

We need to make sure we add/update the port mappings in the run command this time:

$ docker rm httpd-container
httpd-container
$ docker run -d -p 83:80 --name httpd-container httpd-image
dd2535c477ad74e80b3642abca9055efacb89eaf14572b91f91bf20cd3f0cbf3

Now we have a new container with the right port mappings to pick up where the previous one left off.

6. Reconfigure Docker in Flight

 

In the two approaches we’ve discussed so far, we removed the existing Docker container and started up a new one. Although the container works the same way, its metadata is completely different from the previous one.

Let’s now look at how to modify the existing Docker container instead.

First, let’s run a new Docker container without any port mapping:

$ docker run -d --name httpd-container httpd 
a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7
$ docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED             STATUS          PORTS       NAMES
a0ed1c9fc60c   httpd     "httpd-foreground"   1 second ago        Up 1 second     80/tcp      httpd-container

The docker run command returns the full docker container ID, which is 64 characters in length.

Alternatively, this ID can also be found using the docker inspect command:

$ docker inspect --format="{{.Id}}" httpd-container
a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7

We’ll use the ID later to find the Docker configuration file path.

 

6.1. Stop Docker Container and Docker Service

 

The first step of reconfiguring the running container is to stop it.

This can be done using the docker stop command:

$ docker stop httpd-container
httpd-container

Since we’ll be updating the config files of the Docker container, we also need to stop the Docker service itself.

We should note that this will take all Docker containers down until we’re finished:

$ systemctl stop docker

6.2. Find Config Files

 

All the config files related to Docker containers, images, volumes and networks can be found inside the /var/lib/docker directory. This directory will differ in the case of Windows and macOS.

We will focus mainly on two Docker container config files — hostconfig.json and config.v2.json.

These files are present inside this directory:

/var/lib/docker/containers/<ID>/

Here ID denotes the complete Docker container ID that we computed at the beginning of Section 6.

 

This is what its value came out to be:

a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7

So, in our case, the config files are present inside this directory:

$ ls /var/lib/docker/containers/a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7/
a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7-json.log  checkpoints  config.v2.json  hostconfig.json  hostname  hosts  mounts  resolv.conf  resolv.conf.hash

6.3. Update Config Files

 

Let’s first update the hostconfig.json file. We need to search for the PortBindings key in this JSON file. This field contains all the port mappings for that particular container.

Since we didn’t add any port mappings while running the Docker container, the PortBindings key will be empty for the httpd-container:

{
  ...
  ...
  "PortBindings": {},
  ...
  ...
}

Let’s now assign host port 82 to port 80 of the Docker container httpd-container by updating the PortBindings in the JSON file:

{
  ...
  ...
  "PortBindings": {"80/tcp":[{"HostIp":"","HostPort":"82"}]},
  ...
  ...
}

Once the port is mapped, we need to expose port 80 of the Docker container in the config.v2.json file.

We should add the ExposedPorts field (if not already present) inside the Config key:

{
  ...
  "Config":
  {
    ...
    "ExposedPorts":
    {
      "80/tcp":{}
    },
    ...
  }
}

By doing so, we inform the Docker daemon that the container is listening on port 80 within that network interface.

 

Multiple ports can be exposed by passing the values as comma-separated key-value pairs:

{
  ...
  "Config":
  {
    ...
    "ExposedPorts":
    {
      "80/tcp":{},
      "82/tcp":{},
      "8080/tcp":{}
    },
    ...
  }
}

6.4. Verify the Changes

 

It’s time to verify the changes that we’ve made so far.

First, let’s start the Docker service:

$ systemctl start docker

Now let’s start the docker container httpd-container and verify the port mapping using the docker ps command:

$ docker start httpd-container
httpd-container
root@ip-172-31-40-187:~# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED             STATUS          PORTS                               NAMES
a0ed1c9fc60c   httpd     "httpd-foreground"   1 hours ago         Up 1 seconds    0.0.0.0:82->80/tcp, :::82->80/tcp   httpd-container

Here we can see that the port mapping has been updated.

We can now access the httpd service from outside the Docker environment using port 82:

$ curl http://localhost:82
<html><body><h1>It works!</h1></body></html>

In this approach, the container id and other container-related metadata are preserved since we are not replacing the original Docker container.

6.5. Update the Port Mapping of a Running Container

 

We can also modify existing port mappings of any Docker container using the same procedure.

 

The only difference is that the PortBindings key in the hostconfig.json file will not be empty. We just need to update which port numbers we’re using.

If we update the Docker container TCP port in the port mapping, we also need to expose the same port inside the config.v2.json file.

Finally, we start the Docker service and the Docker container to bring the changes into effect.

7. Conclusion

 

In this article, we learned three different approaches for starting containers with the port mappings we need.

The first two approaches remove an existing Docker container and spin up a replacement.

Finally, we saw how to change the port mapping in an existing container by updating various Docker system config files while the Docker service was stopped.

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!;; that is googling

 

 

View solution in original post

19 Replies
Tracy_Baker
Starfighter Starfighter
Starfighter
  • 31K Views

The podman option is publish (it's a bit like port forwarding):
-p <host_port>:<container_port>

Like:
podman run -d --name=<container_name> -p <host_port>:<container_port> <image>

For example:
$ podman run -d --name=web_server -p 8080:8080 rhcsl/httpd-24-rhel7

The container needs to listening on the <container_port> you specify.

To verify:
$ podman port <container_name>

Program Lead at Arizona's first Red Hat Academy, est. 2005
Estrella Mountain Community College
isudoajl
Mission Specialist
Mission Specialist
  • 30.9K Views

Hello Tracy! But this solution I think that not fit to my question bc is when a container is already deployed, so if you already install many stuff on it and you forgot that you dont put the port mapping.

The normal thing would be to delete the container and launch a new one and reinstall everything again...

But docker has the peculiarity that you can stop de container, edit the configuration file and relaunch it without having to delete the container, but I have not been able to implement that solution in podman.

Anyway thanks for your help.

0 Kudos
Fran_Garcia
Starfighter Starfighter
Starfighter
  • 30.8K Views

It sounds your container is doing too many things in manual ways. Why is it so costly to restart it?

The approach would be to build a static container with a Containerfile/Dockerfile, and restarting it should be pretty painless.  Restarting could/shold be done via a script or systemd unit to ensure nobody forgets a required port.

0 Kudos
EchoCharlie
Flight Engineer Flight Engineer
Flight Engineer
  • 30.3K Views

Instead of installing software on a running container, try modifying the containerfile and building that into the image. Things that need to change frequently (database names, passwords, etc.) can be baked in as enviroment variables passed at container startup.

Carey
Mission Specialist
Mission Specialist
  • 31K Views

i thought i saw it on DO180 class also googled. I will take it next year.

Let’s consider a situation where we forgot to do the port mapping when starting the Docker container. There would be no way to access the service from a TCP/IP connection on the host.

 

There are three ways to deal with this:

  • Start over by stopping the existing container and relaunching a new one with the same original Docker image
  • Commit the existing container and relaunch a new container from the committed Docker image, keeping the state of the container we’re trying to access
  • Add a new port mapping by manipulating the Docker configuration files

Let’s dive deep into each of these solutions.

This is a naive solution where we remove the running Docker container and relaunch it using the same Docker image. But this time, we add the port mappings that we forgot to add in the old container.

This is the simplest and most straightforward approach, but it doesn’t suit all situations.

Consider a case where we launch the Docker container (without any port mapping) and perform some operations inside it, such as installing a few packages, launching processes, updating files and so on.

 

After all these changes, we realize that the port mapping is missing. Now if we launch a new Docker container using the same old Docker image, we’ll lose all those changes.

The next approach comes to the rescue under these circumstances.

However, we should note that it’s a good practice to use Docker volumes for our important data to make it easy to replace containers.

5. Relaunch From Docker Commit

 

Instead of launching a new container from zero, we can commit the old Docker container to create a new Docker image and use that to start a new container with the right ports open.

Since we’re committing the old Docker container, the persistent state of the first will be available in the newly launched one.

Let’s try this out.

First, we’ll stop our Docker container and create its image using the docker commit command:

$ docker stop httpd-container
httpd-container
$ docker commit httpd-container httpd-image
sha256:33da33fcad051c90ac9b7dea9b2dbda442767e05ddebd8d6db8ac6893ef4ef40

Next, we’ll remove the container and start a fresh container using the image that we just created.

 

We need to make sure we add/update the port mappings in the run command this time:

$ docker rm httpd-container
httpd-container
$ docker run -d -p 83:80 --name httpd-container httpd-image
dd2535c477ad74e80b3642abca9055efacb89eaf14572b91f91bf20cd3f0cbf3

Now we have a new container with the right port mappings to pick up where the previous one left off.

6. Reconfigure Docker in Flight

 

In the two approaches we’ve discussed so far, we removed the existing Docker container and started up a new one. Although the container works the same way, its metadata is completely different from the previous one.

Let’s now look at how to modify the existing Docker container instead.

First, let’s run a new Docker container without any port mapping:

$ docker run -d --name httpd-container httpd 
a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7
$ docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED             STATUS          PORTS       NAMES
a0ed1c9fc60c   httpd     "httpd-foreground"   1 second ago        Up 1 second     80/tcp      httpd-container

The docker run command returns the full docker container ID, which is 64 characters in length.

Alternatively, this ID can also be found using the docker inspect command:

$ docker inspect --format="{{.Id}}" httpd-container
a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7

We’ll use the ID later to find the Docker configuration file path.

 

6.1. Stop Docker Container and Docker Service

 

The first step of reconfiguring the running container is to stop it.

This can be done using the docker stop command:

$ docker stop httpd-container
httpd-container

Since we’ll be updating the config files of the Docker container, we also need to stop the Docker service itself.

We should note that this will take all Docker containers down until we’re finished:

$ systemctl stop docker

6.2. Find Config Files

 

All the config files related to Docker containers, images, volumes and networks can be found inside the /var/lib/docker directory. This directory will differ in the case of Windows and macOS.

We will focus mainly on two Docker container config files — hostconfig.json and config.v2.json.

These files are present inside this directory:

/var/lib/docker/containers/<ID>/

Here ID denotes the complete Docker container ID that we computed at the beginning of Section 6.

 

This is what its value came out to be:

a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7

So, in our case, the config files are present inside this directory:

$ ls /var/lib/docker/containers/a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7/
a0ed1c9fc60c358d53400dc244e94ef0db4d1347e70bd4be725a890b062ebbe7-json.log  checkpoints  config.v2.json  hostconfig.json  hostname  hosts  mounts  resolv.conf  resolv.conf.hash

6.3. Update Config Files

 

Let’s first update the hostconfig.json file. We need to search for the PortBindings key in this JSON file. This field contains all the port mappings for that particular container.

Since we didn’t add any port mappings while running the Docker container, the PortBindings key will be empty for the httpd-container:

{
  ...
  ...
  "PortBindings": {},
  ...
  ...
}

Let’s now assign host port 82 to port 80 of the Docker container httpd-container by updating the PortBindings in the JSON file:

{
  ...
  ...
  "PortBindings": {"80/tcp":[{"HostIp":"","HostPort":"82"}]},
  ...
  ...
}

Once the port is mapped, we need to expose port 80 of the Docker container in the config.v2.json file.

We should add the ExposedPorts field (if not already present) inside the Config key:

{
  ...
  "Config":
  {
    ...
    "ExposedPorts":
    {
      "80/tcp":{}
    },
    ...
  }
}

By doing so, we inform the Docker daemon that the container is listening on port 80 within that network interface.

 

Multiple ports can be exposed by passing the values as comma-separated key-value pairs:

{
  ...
  "Config":
  {
    ...
    "ExposedPorts":
    {
      "80/tcp":{},
      "82/tcp":{},
      "8080/tcp":{}
    },
    ...
  }
}

6.4. Verify the Changes

 

It’s time to verify the changes that we’ve made so far.

First, let’s start the Docker service:

$ systemctl start docker

Now let’s start the docker container httpd-container and verify the port mapping using the docker ps command:

$ docker start httpd-container
httpd-container
root@ip-172-31-40-187:~# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED             STATUS          PORTS                               NAMES
a0ed1c9fc60c   httpd     "httpd-foreground"   1 hours ago         Up 1 seconds    0.0.0.0:82->80/tcp, :::82->80/tcp   httpd-container

Here we can see that the port mapping has been updated.

We can now access the httpd service from outside the Docker environment using port 82:

$ curl http://localhost:82
<html><body><h1>It works!</h1></body></html>

In this approach, the container id and other container-related metadata are preserved since we are not replacing the original Docker container.

6.5. Update the Port Mapping of a Running Container

 

We can also modify existing port mappings of any Docker container using the same procedure.

 

The only difference is that the PortBindings key in the hostconfig.json file will not be empty. We just need to update which port numbers we’re using.

If we update the Docker container TCP port in the port mapping, we also need to expose the same port inside the config.v2.json file.

Finally, we start the Docker service and the Docker container to bring the changes into effect.

7. Conclusion

 

In this article, we learned three different approaches for starting containers with the port mappings we need.

The first two approaches remove an existing Docker container and spin up a replacement.

Finally, we saw how to change the port mapping in an existing container by updating various Docker system config files while the Docker service was stopped.

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!;; that is googling

 

 

isudoajl
Mission Specialist
Mission Specialist
  • 30.9K Views

Hello Carey, but this method of editing the configuration file dont work in Podman. I already tried it and didn't work.

Anyway thanks for your help.

0 Kudos
drlavery
Mission Specialist
Mission Specialist
  • 30.9K Views

I would imagin it to be similar to port forwarding:

"-p 8080:80/tcp docker.io/library/httpd"

 

0 Kudos
drlavery
Mission Specialist
Mission Specialist
  • 30.9K Views

To add... i guess you could also:

Create a "container".service, then you can stop it with sudo systemctl stop "container".service

edit the config on container then sudo systemctl start "container".service

notes on making service...

vim /etc/systemd/system/container.service

[Unit]
Description=container Podman 'container name' 
Wants=syslog.service
[Service]
Restart=always
ExecStart=/usr/bin/podman start -a 'container name'
ExecStop=/usr/bin/podman stop -t 10 'container name'
[Install]
WantedBy=multi-user.target
0 Kudos
SaifBassim
Mission Specialist
Mission Specialist
  • 30.9K Views

Simply use -p option with the host port first 8080(host):80(container)

0 Kudos
Join the discussion
You must log in to join this conversation.