You're experiencing a classic Docker networking issue where:
- The service works inside the container (
docker exec curl
succeeds) - Host-to-container communication fails with connection reset
- The container ports are correctly mapped (0.0.0.0:80->80/tcp)
First, verify the container's listening ports:
docker exec b56fa0d76d5c netstat -tulnp | grep 80
Check if the service binds to localhost only:
docker exec b56fa0d76d5c ss -tulnp | grep 80
# If output shows "127.0.0.1:80", that's the problem
The web service inside your container might be configured to:
- Bind only to 127.0.0.1 (localhost)
- Reject connections from outside the container
- Have firewall rules blocking the traffic
1. Modify Service Binding
For Node.js applications, change the listen address:
app.listen(80, '0.0.0.0', () => {
console.log('Server listening on all interfaces');
});
For Python Flask:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
2. Docker Network Inspection
Check your container's network configuration:
docker inspect b56fa0d76d5c | jq '.[].NetworkSettings'
3. Testing with Alternative Tools
Try telnet to verify basic connectivity:
telnet localhost 80
# Or for more detailed debugging:
nc -zv localhost 80
Use tcpdump inside the container:
docker exec -it b56fa0d76d5c bash -c "apt-get update && apt-get install tcpdump -y"
docker exec b56fa0d76d5c tcpdump -i any port 80 -vv
Check container logs for errors:
docker logs --tail 50 b56fa0d76d5c
When binding to 0.0.0.0:
- Ensure proper firewall rules are in place
- Consider using Docker's built-in firewall (--iptables flag)
- Implement authentication for sensitive endpoints
When working with Docker containers on AWS EC2 instances, a common but frustrating scenario occurs when a service is accessible from within the container but refuses connections from the host. Let's examine this networking puzzle through a real-world example.
# Container is running with ports exposed
docker ps
CONTAINER ID IMAGE PORTS NAMES
b56fa0d76d5c registry/work/metrics:v0.1.0 0.0.0.0:80->80/tcp, 0.0.0.0:9000->9000/tcp insane_leakey
First, confirm the service works inside the container:
docker exec -it b56fa0d76d5c bash
root@b56fa0d76d5c:/# curl 'http://localhost/health'
Request is missing required query parameter 'apiName'
But fails from host:
curl 'http://localhost/health'
curl: (56) Recv failure: Connection reset by peer
The connection reset typically indicates one of these issues:
# 1. Check container binding
docker inspect b56fa0d76d5c | grep HostPort
# 2. Verify firewall rules
sudo iptables -L -n | grep 80
# 3. Test alternative ports
curl -v 'http://localhost:9000/health'
# 4. Validate service binding
docker exec b56fa0d76d5c netstat -tulnp | grep 80
Docker's default bridge networking can sometimes cause routing issues. Try these alternatives:
# Option 1: Use host networking
docker run --network=host ...
# Option 2: Explicit port binding
docker run -p 127.0.0.1:80:80 ...
On AWS environments, additional checks are needed:
# Check security group inbound rules
aws ec2 describe-security-groups --group-ids sg-xxxxxx
# Verify instance metadata service
curl http://169.254.169.254/latest/meta-data/...
- Confirm container port exposure with
docker port <container>
- Test with different IP bindings (127.0.0.1 vs 0.0.0.0)
- Verify SELinux/AppArmor policies aren't blocking connections
- Check Docker daemon logs for networking errors
- Test with simplified container images (nginx) to isolate the issue