Baeldung Pro – Ops – NPI EA (cat = Baeldung on Ops)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

It’s common for developers and DevOps engineers to change the network of a Docker container when working with microservices. For instance, when reorganizing infrastructure, troubleshooting connectivity issues, or modifying container behavior. However, Docker’s networking system contains limitations that make this process less flexible than we may expect.

In this tutorial, we’ll walk through changing the network of a running Docker container. First, we’ll explore a common Docker networking issue we may encounter when containers are running. Next, we’ll show an easy and correct way to update a container’s network as well as a few best practices.

2. Why Docker Networks Are Important

Even though Docker containers are lightweight and isolated, they still need to communicate with each other or with the outside world. Docker manages this through its built-in networking system, which supports different drivers:

  • bridge – creates a private internal network on the host and acts as a default for standalone containers
  • host – removes network isolation, making the container share the host’s network stack
  • overlay – used with Docker Swarm for multi-host networking
  • macvlan – makes containers appear as physical devices by assigning a MAC address to them
  • none – disables networking completely

When starting a container, we can use the –network flag to specify the network the container should attach to. However, if we forget to do this or want to change it later, we need to understand how Docker handles these networks.

3. Issue With Changing a Running Container’s Network

By default, when we start a container without specifying any network, it’s placed on the bridge network. Now, let’s discuss what happens when we want to move the container to a custom network to enable its communication with other containers:

$ docker network connect my-custom-network <container-id>

Normally, this works unless our container is utilizing the host network, in which we may encounter the error:

Error response from daemon: container sharing network namespace with another container or host cannot be connected to any other network

Here, Docker informs us that we’re locked in since we’re using host mode.

The approach that Docker takes to handle network namespaces is the reason behind this limitation. Typically, each container runs in its own isolated namespace. However, when we use –network host, the container shares the host’s namespace. In this scenario, Docker cannot attach new networks without risking unpredictable behavior like namespace conflicts.

4. Practical Example

Let’s explore a basic example of how we can change a container’s network from the default bridge to a custom one.

4.1. Using a bridge Network

Firstly, let’s create a custom network:

$ docker network create --driver bridge app-network
ae1ae3745a4e55c492ea335a46d8e90ebe63f016e0a47e7bb4f562639270bceb

Here, we create the bridge network app-network.

Secondly, let’s run a container without specifying a network:

$ docker run -d --name web-server nginx
11beef3f1ce532670909f59258f99a745e16b8e4acaba4ee5c2ebdcf4a21e649

Docker attaches this container to the default bridge network.

Now, let’s attach our container web-server to the new custom network:

$ docker network connect app-network web-server

The command above works fine since we’re not using the host network. To verify, we can use:

$ docker inspect web-server --format='{{json .NetworkSettings.Networks}}' | jq
{
  "app-network": {
    ...
  },
  "bridge": {
    ...
  }
}

Above, we see that our container is connected to both the bridge and app-network networks. Additionally, we use jq optionally to improve the format of our output.

4.2. Using a Host Network

Let’s now simulate using the host network:

$ docker run -d --name host-server --network host nginx
215b5a0b841f248ff080683ae1c14071371370019a735f140cdb711586213ae5

After this, let’s try connecting the container to another network:

$ docker network connect app-network host-server
Error response from daemon: container sharing network namespace with another container or host cannot be connected to any other network

As previously discussed, we get the expected error.

4.3. Resolving the Issue

For a container attached to a host network, we cannot change its network.

To resolve the issue, we need to first stop and remove the container in question. Once this is done, we can recreate the container with the correct network.

While recreating the container, we need to preserve the container’s state. To start, we inspect the existing configuration to capture the container’s current settings:

$ docker inspect host-server

Here, we can look for key fields such as:

  • Mounts – for volumes or bind mounts
  • Config.Env – for environment variables
  • HostConfig.PortBindings – for published ports

With this information, we can recreate the container and preserve its state. For example, let’s assume our container was started in this manner:

$ docker run -d --name host-server --network host -e ENV=production nginx
8a27164e288b00116c89a7e0555f1121742be711135f74087297a2a5269f83ba

To recreate the container using the new network, we can run:

$ docker stop host-server && docker rm host-server &&  docker run -d --name host-server --network app-network -e ENV=production nginx
host-server
host-server
150be709ed58e4a9b0bdf14cd9db10b89165a18146f7ff2dce7124f19ddc249f

The above approach preserves the environment variable (-e), which also applies to volume (-v) and port mapping (-p).

4.4. Disconnecting From a Network

There are situations where we may want to remove the container from a specific network. For instance, when cleaning up old networks or reconfiguring the connectivity of the container.

To illustrate, let’s disconnect the container web-server from the default bridge network:

$ docker network disconnect bridge web-server

Once we run the command, let’s verify the disconnection:

$ docker inspect web-server --format='{{json .NetworkSettings.Networks}}' | jq
{
  "app-network": {
    ...
  }
}

The above output verifies that the container is now only connected to the network app-network. Notably, we cannot disconnect a container from its last remaining network since Docker requires it to be attached to at least one network.

4.5. Effect on Port Mappings and Network Aliases

When changing a container’s network, we need to understand how it may affect port mappings as well as network aliases.

Port mappings (-p) work with the default bridge network. If we move the container to a host network, the container uses the host’s ports directly and ignores -p mappings. With custom bridge networks, port mappings still work, but how they behave may vary depending on the network setup.

Network aliases, set with –network-alias, only apply to the network where they were defined. If we attach the container to a new network and want to use the same alias, we need to reassign it:

$ docker network connect --alias my-app app-network container-name

After changing networks, always verify that the container is reachable and works as expected.

5. Best Practices

To avoid network issues, we can start by planning the network setup. We can use docker network ls and docker network inspect <network-name-or-id> to understand the existing setups before launching containers.

Secondly, we can avoid using the host network unless it’s necessary, for instance, if performance demands it. Host mode removes isolation and can lead to port conflicts.

Thirdly, for communication between containers, we can consider user-defined bridge networks. To explain, containers attached to the same custom bridge network can access each other through container names:

$ docker run --network app-network --name api-service my-api
$ docker run --network app-network --name web-app my-web

Here, web-app can access api-service with the help of its name.

Further, when we need to recreate a container, we can always save the configuration, such as environment variables, ports, and volumes, to recreate it seamlessly:

$ docker inspect container-name > config.json

Above, we save the container’s configuration in the config.json file.

Lastly, we can consider Docker Compose or Kubernetes to manage container networks declaratively. With the help of these tools, we can reconfigure easily.

6. Conclusion

In this article, we tackle changing the network of a running Docker container.

Here, we saw that we can change the network of a running Docker container, but under specific conditions. If the container is on the host network, Docker prevents it from joining other networks to maintain stability. In this case, the safest and effective approach we can use for this issue is to stop and recreate the container with the correct network configurations.

Thus, we can now plan our network configuration in advance and leverage custom networks to create a flexible container infrastructure.