
Docker makes it straightforward to run applications inside containers, but networking problems can quickly become a challenge when services cannot communicate with one another. An application might run perfectly on its own yet fail to connect to a database, respond to browser requests or access an external API.
Understanding how Docker networks operate and knowing which commands to use when troubleshooting can save considerable development time. In this article, we will explore common Docker networking issues, how to diagnose them and the steps you can take to get your containers communicating correctly.
Understanding Docker Networking
Before investigating a networking problem, it helps to understand how Docker connects containers and exposes applications to the outside world.
Docker provides several network drivers, including bridge, host, overlay and none. Each serves a different purpose, but the bridge network is particularly common in local development environments.
A bridge network allows containers running on the same Docker host to communicate with one another. User-defined bridge networks also provide automatic DNS resolution, allowing containers to reach other containers by their names rather than relying on IP addresses.
For example, a web application running in one container might need to connect to a SQL Server database running in another. Both containers should be attached to a suitable network, and the application should use the database container's network name as its hostname.
Problems often arise when containers are attached to different networks, an incorrect hostname is configured or a required port has not been published.
Start by Inspecting Your Containers
The first step in troubleshooting is to establish whether the affected containers are running and identify any obvious configuration problems.
Use the following command to list running containers:
docker ps
This displays information including container names, status and published ports. If the container you expect to use is missing, list all containers, including those that have stopped:
docker ps -a
A container that repeatedly exits may indicate an application startup failure rather than a networking issue. You can investigate its output using the logs command:
docker logs my-container
Replace my-container with the name or ID of your container.
Look for connection errors, failed hostname lookups, port binding failures and application startup messages. These details can help narrow down the problem before you start changing network settings.
Check Your Docker Network Configuration
Once you have identified the affected containers, inspect the networks available on your Docker host.
Run the following command to list them:
docker network ls
You will normally see networks such as bridge, host and none, along with any custom networks created for your projects.
To examine a particular network, use:
docker network inspect my-network
The output contains details about the network, including its subnet, gateway and connected containers.
Check whether the containers that need to communicate are attached to the same appropriate network. If they are connected to separate bridge networks, they will not normally be able to communicate directly using their container addresses.
You can also connect an existing container to a user-defined network:
docker network connect my-network my-container
This can be useful when diagnosing a network membership problem, although you should also correct the underlying Docker Compose or container configuration if the connection needs to persist after recreation.
Troubleshooting Port Mapping Problems
One of the most common Docker networking mistakes is confusing a container port with a host port.
Suppose your web application listens on port 80 inside its container. You want to access it through port 8080 on your development machine.
You can publish the port when starting the container:
docker run -d -p 8080:80 nginx
In this example, port 8080 belongs to the host, while port 80 belongs to the container. You can then open http://localhost:8080 in your browser.
If you cannot reach the application, inspect its port mappings:
docker port my-container
You can also inspect the published ports using:
docker ps
Check that the host port maps to the correct container port and that the application is actually listening on the expected port.
An application can be running without accepting connections if it listens on the wrong interface. Inside a container, a web server that listens only on 127.0.0.1 may not accept connections arriving through the container's network interface. In many cases, it needs to listen on 0.0.0.0 instead.
Remember that publishing a port can make a service accessible beyond your development machine. If the application should only be available locally, you can bind the published port to the loopback address:
docker run -d -p 127.0.0.1:8080:80 nginx
This restricts the published port to the host's IPv4 loopback interface, subject to the relevant Docker and operating system behaviour.
Fixing Container DNS Resolution
DNS problems occur when a container cannot resolve a hostname into an IP address.
For example, a web application might attempt to connect to a database using the hostname sqlserver, but the connection fails because the hostname cannot be resolved.
First, check that both containers are attached to the same user-defined bridge network. Docker provides automatic name resolution between containers on these networks.
A typical connection string for an application connecting to SQL Server in another container might look like this:
Server=sqlserver,1433;Database=MyDatabase;User Id=sa;Password=YourPassword;Encrypt=True;TrustServerCertificate=True;
Here, sqlserver is the database service or container name, and 1433 is the SQL Server port inside the container. The credentials and encryption settings must match your actual database configuration.
Do not use localhost to refer to another container. Within a container, localhost refers to that same container, not to other containers or automatically to the Docker host.
If the application cannot resolve the hostname, inspect the network configuration and verify that the target container is attached to the expected network. You can also examine DNS settings from inside the container where suitable diagnostic tools are available.
For containers that need to resolve external domain names, check whether DNS queries are working and whether the Docker host has a valid DNS configuration. Custom DNS settings may be necessary in some environments, particularly when using internal corporate hostnames or VPN connections.
Debugging Docker Compose Networking
Docker Compose simplifies multi-container applications by allowing services to be defined in a single YAML file.
Consider an application that contains a web service and a database:
services:
web:
image: nginx
ports:
- "8080:80"
depends_on:
- database
database:
image: postgres:17
environment:
POSTGRES_PASSWORD: example
Docker Compose normally creates a project network and attaches both services to it. The services can communicate using their service names as hostnames.
For example, the web service can resolve database to reach the PostgreSQL service. The database connection should use the database's internal port, rather than a host port published for external access.
If communication fails, start by checking the Compose services:
docker compose ps
Then inspect the network created for the project:
docker network ls docker network inspect myproject_default
The exact network name depends on the Compose project name and configuration.
You can also inspect the published port for a service:
docker compose port web 80
This reports the host binding associated with the service's port.
Another useful technique is to examine the service logs:
docker compose logs web
Or follow the output as it appears:
docker compose logs -f
When using depends_on, remember that it controls service startup ordering but does not, by itself, guarantee that a database is ready to accept connections. Applications should handle temporary connection failures, and database services can use health checks where appropriate.
Testing Network Connectivity from Inside a Container
Sometimes the Docker network configuration appears correct, but the application still cannot reach another service. In these situations, testing connectivity from inside the affected container can help identify the cause.
For a running Compose service, you can open a shell using:
docker compose exec web sh
This example assumes the web service provides a shell. Some minimal images do not include sh or common networking utilities.
If curl is available, test an HTTP endpoint:
curl -v http://database:5432
This is only an example of a connectivity test; PostgreSQL does not speak HTTP, so an HTTP error or protocol mismatch is not evidence that a PostgreSQL connection works correctly. Use a database client or a TCP connection test for database services.
For a TCP port test, tools such as nc may be available:
nc -vz database 5432
Replace the hostname and port with the service you are investigating.
A successful TCP connection confirms that a connection can be established, but it does not prove that the application protocol, authentication or database configuration is correct.
If the required tools are missing, use an appropriate diagnostic image on the same network or temporarily add suitable utilities to a development image. Avoid installing troubleshooting tools into production images unnecessarily.
Investigating Firewall and Host Networking Issues
Not every networking failure originates inside Docker. Host firewalls, VPN software, routing rules and operating system network settings can also affect connectivity.
On Linux, Docker manages firewall rules to implement network isolation and port publishing. Manually modifying these rules can interfere with normal Docker networking.
If a container cannot access an external service, check whether the host itself can reach that service. If the host connection also fails, investigate the host's routing, DNS and firewall configuration before changing Docker settings.
IP forwarding can also be relevant on Linux hosts, particularly where containers need to communicate beyond their local network. Docker normally configures forwarding for its own networking requirements, but other network management tools or custom system settings can interfere.
On Docker Desktop for Windows and macOS, networking is implemented through Docker Desktop's virtualised environment. The host and container do not necessarily share the same network interfaces, so Linux-specific troubleshooting commands may not apply directly.
When a container needs to connect to a service running on the Docker Desktop host, the special hostname host.docker.internal is often useful:
http://host.docker.internal:5000
Replace port 5000 with the port on which the host application is listening. The application must also be configured to accept connections through an appropriate host interface.
Diagnosing IP Address and Subnet Conflicts
Docker networks use IP address ranges to assign addresses to containers. Problems can occur when these ranges overlap with an existing network, a VPN subnet or another route available to the host.
For example, a Docker network might use an address range that conflicts with a corporate VPN. Traffic intended for the VPN could then be routed incorrectly, causing unexpected connection failures.
Inspect the network's subnet and gateway using:
docker network inspect my-network
Compare the configured subnet with the address ranges used by your host, VPN and other relevant networks.
If you identify a conflict, consider recreating the Docker network with a suitable non-overlapping subnet. Before doing so, check the impact on running containers and existing network configuration.
Avoid assigning static container IP addresses unless your application genuinely requires them. Service names and Docker's built-in DNS resolution are generally easier to maintain.
A Practical Docker Networking Troubleshooting Workflow
When faced with an unexplained connectivity problem, work through the issue methodically rather than changing multiple settings at once.
First, confirm that the affected containers are running and inspect their logs for errors. Next, establish which Docker networks they use and verify that the required containers share an appropriate network.
Then check whether the application listens on the expected port, whether the relevant host port is published and whether the correct hostname is being used. Test connectivity from inside the container, paying attention to the difference between DNS failures, TCP connection failures and application-level errors.
Finally, investigate host firewall rules, VPN routing, IP forwarding and subnet conflicts if the earlier checks do not reveal the problem.
Change one thing at a time and repeat the same test after each change. This makes it much easier to identify the actual cause and avoid introducing additional problems.
Conclusion
Docker networking issues can initially seem complicated, but most can be investigated by understanding how containers communicate, checking network membership, verifying port mappings and testing DNS resolution.
Commands such as docker ps, docker network inspect, docker port and docker compose logs provide a useful starting point for identifying common problems. When these checks are not enough, testing connectivity from inside a container can help distinguish between network configuration issues and application-level failures.
By following a consistent troubleshooting process, you can diagnose networking problems more efficiently and build Docker applications that are easier to develop, maintain and deploy.
Become a member
Get the latest news right in your inbox. It's free and you can unsubscribe at any time. We hate spam as much as we do, so we never spam!
Read next
Reducing Image Size in .NET Containers
Docker makes deploying .NET applications easier, but container images can become unnecessarily large if they include development tools, unused files and dependencies. In this article, we’ll explore practical ways to reduce the size of .NET container images using multi-stage builds, smaller runtime images, efficient publishing and Docker build optimisation, helping you create leaner, faster and more maintainable deployments.
Deploying a .NET App with Docker Compose
Multi-Stage Docker Builds for .NET
