DeployU
Interviews / Cloud & DevOps / Two containers can't communicate with each other. Diagnose and fix the networking issue.

Two containers can't communicate with each other. Diagnose and fix the networking issue.

debugging Networking Interactive Quiz Code Examples

The Scenario

You have a Node.js API container trying to connect to a Redis container:

$ docker ps
CONTAINER ID   IMAGE      PORTS                    NAMES
a1b2c3d4e5f6   api:v1     0.0.0.0:3000->3000/tcp   api
b2c3d4e5f6g7   redis:7    0.0.0.0:6379->6379/tcp   redis

$ docker logs api
Error: connect ECONNREFUSED 127.0.0.1:6379
    at TCPConnectWrap.afterConnect

The API can’t reach Redis, but you can connect to Redis from your host machine. What’s wrong?

The Challenge

Diagnose the networking issue and fix it. Explain the different Docker networking modes and when to use each.

Wrong Approach

A junior engineer might try using localhost or 127.0.0.1 to connect between containers, expose more ports thinking that's the issue, restart both containers hoping the network resets, or try to use the container's IP address directly. These fail because localhost inside a container refers to that container itself, exposing ports is for host access not container-to-container communication, restarts don't fix architectural issues, and container IPs are dynamic and change on restart.

Right Approach

A senior engineer understands that containers need to be on the same Docker network to communicate by name. The fix is to create a user-defined bridge network and connect both containers to it. Then containers can reach each other using their container names as hostnames. This provides automatic DNS resolution, better isolation, and more control over networking.

Step 1: Understand the Problem

# Check which networks each container is on
docker inspect api --format='{{range .NetworkSettings.Networks}}{{.NetworkID}}{{end}}'
docker inspect redis --format='{{range .NetworkSettings.Networks}}{{.NetworkID}}{{end}}'

# List all networks
docker network ls

# Inspect the default bridge network
docker network inspect bridge

The issue: By default, containers on the default bridge network can’t resolve each other by name. They need to be on a user-defined network for DNS resolution.

Step 2: Create a User-Defined Network

# Create a custom bridge network
docker network create app-network

# Verify it was created
docker network ls

Step 3: Connect Containers to the Network

# Option 1: Connect running containers
docker network connect app-network api
docker network connect app-network redis

# Option 2: Start containers on the network
docker run -d --name redis --network app-network redis:7
docker run -d --name api --network app-network -p 3000:3000 api:v1

Step 4: Update Application Configuration

// Before (wrong)
const redis = new Redis({
  host: '127.0.0.1',  // This is the container itself!
  port: 6379
});

// After (correct)
const redis = new Redis({
  host: 'redis',  // Container name as hostname
  port: 6379
});

Step 5: Verify Connectivity

# Test DNS resolution from API container
docker exec api ping redis

# Test TCP connection
docker exec api nc -zv redis 6379

# Check network configuration
docker inspect api --format='{{json .NetworkSettings.Networks}}' | jq

Docker Network Types

Network TypeUse CaseContainer-to-ContainerHost Access
bridge (default)Default for standalone containersBy IP only (no DNS)Via port mapping
user-defined bridgeMulti-container appsBy name (DNS)Via port mapping
hostPerformance-critical appsVia localhostDirect (no port mapping)
noneMaximum isolationNo networkingNone
overlayMulti-host (Swarm/K8s)By name across hostsVia routing mesh

Docker Compose Solution

The best way to handle multi-container networking:

# docker-compose.yml
version: '3.8'

services:
  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      - REDIS_HOST=redis
    depends_on:
      - redis
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  redis-data:

Docker Compose automatically:

  • Creates a network named <project>_app-network
  • Connects all services to it
  • Enables DNS resolution by service name

Debugging Network Issues

# Check container's network configuration
docker inspect <container> --format='{{json .NetworkSettings}}' | jq

# List containers on a network
docker network inspect app-network --format='{{range .Containers}}{{.Name}} {{end}}'

# Test connectivity from inside container
docker exec -it api sh
$ ping redis
$ nc -zv redis 6379
$ curl http://other-service:8080/health

# Check DNS resolution
docker exec api nslookup redis

# Check iptables rules (on host)
sudo iptables -L -n | grep DOCKER

Practice Question

Why can't containers on the default bridge network communicate using container names?