docker
connection issues
container troubleshooting
networking
port configuration

Connection refused on docker container

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A "connection refused" error when trying to reach a Docker container means that the network connection to the container was established at the transport level, but nothing was listening on the target port. This is one of the most common Docker networking issues and can stem from misconfigured port mappings, services binding to the wrong interface, or the container application not running correctly.

Common Causes

1. Service Binding to localhost Inside the Container

The most frequent cause is that the application inside the container is listening on 127.0.0.1 (localhost) instead of 0.0.0.0 (all interfaces). Inside a container, localhost refers to the container's own loopback, which is not reachable from outside:

bash
1# This will NOT be accessible from outside the container
2python -m http.server 8080 --bind 127.0.0.1
3
4# This WILL be accessible from outside the container
5python -m http.server 8080 --bind 0.0.0.0

For common frameworks:

bash
1# Node.js/Express — bind to 0.0.0.0
2app.listen(3000, '0.0.0.0');
3
4# Flask
5flask run --host=0.0.0.0
6
7# Django
8python manage.py runserver 0.0.0.0:8000
9
10# Rails
11rails server -b 0.0.0.0

2. Incorrect Port Mapping

The -p flag maps a host port to a container port. The syntax is HOST_PORT:CONTAINER_PORT:

bash
1# Maps host port 8080 to container port 80
2docker run -p 8080:80 my-app
3
4# Common mistake: reversing the order
5# This maps host port 80 to container port 8080 (probably wrong)
6docker run -p 80:8080 my-app

3. Service Not Running Inside the Container

The application may have crashed on startup:

bash
1# Check if the container is running
2docker ps
3
4# Check container logs for startup errors
5docker logs my-container
6
7# If the container exited, check why
8docker ps -a | grep my-container

4. EXPOSE vs -p

The EXPOSE instruction in a Dockerfile is documentation only. It does not actually publish the port. You must use -p at runtime:

dockerfile
# Dockerfile — EXPOSE is informational only
EXPOSE 8080
bash
# You still need -p to actually map the port
docker run -p 8080:8080 my-app

5. Docker Network Isolation

Containers on different Docker networks cannot reach each other by default:

bash
1# Create a shared network
2docker network create my-network
3
4# Run both containers on the same network
5docker run --network my-network --name backend my-backend
6docker run --network my-network --name frontend my-frontend

Within the same network, containers can reach each other by container name.

How to Diagnose

Step 1: Verify the Container is Running

bash
docker ps

Step 2: Check Port Mappings

bash
docker port my-container
# Output: 80/tcp -> 0.0.0.0:8080

Step 3: Test from Inside the Container

bash
docker exec -it my-container sh
curl localhost:80
# If this works but external access fails, it's a port mapping or binding issue

Step 4: Check What the Service is Listening On

bash
docker exec my-container netstat -tlnp
# or
docker exec my-container ss -tlnp

Look for the Local Address column. If it shows 127.0.0.1:8080, the service is only listening on localhost.

Docker Compose Example

In Docker Compose, use the ports directive:

yaml
1services:
2  web:
3    build: .
4    ports:
5      - "8080:80"
6    networks:
7      - app-network
8  api:
9    build: ./api
10    ports:
11      - "3000:3000"
12    networks:
13      - app-network
14
15networks:
16  app-network:

Common Pitfalls

  • Firewall rules: On Linux hosts, iptables or ufw rules may block Docker's port mappings. Check sudo iptables -L -n if connections fail.
  • Docker Desktop on Mac/Windows: Docker runs in a VM, so host.docker.internal is needed to reach the host machine from inside a container.
  • Health check timing: If you connect immediately after docker run, the service may not have started yet. Add a health check or a brief wait.
  • Conflicting ports: If another process on the host is already using the mapped port, Docker will fail to bind it. Check with lsof -i :8080.

Summary

SymptomLikely CauseFix
Connection refused from hostService bound to 127.0.0.1Bind to 0.0.0.0
Connection refused, container runningWrong port mappingCheck -p HOST:CONTAINER order
Container not in docker psService crashedCheck docker logs
Containers cannot reach each otherDifferent networksUse shared Docker network

Course illustration
Course illustration

All Rights Reserved.