Error Medic

How to Fix 'Connection Refused' for Redis in Docker

Comprehensive guide to fixing Redis connection refused errors in Docker. Learn how to resolve localhost binding issues, Docker network misconfigurations, and po

Last updated:
Last verified:
1,564 words
Key Takeaways
  • Redis defaults to binding to 127.0.0.1, making it inaccessible outside the container.
  • Missing or incorrect Docker port publishing (-p 6379:6379) prevents host access.
  • Containers must share a Docker network to communicate using container names.
  • Quick fix: Run Redis with 'redis-server --bind 0.0.0.0' or use proper Docker networking.
Fix Approaches Compared
MethodWhen to UseTimeRisk
Publish Ports (-p 6379:6379)Connecting from host machine to container1 minLow (if host is secure)
Custom Docker NetworkConnecting between multiple containers2 minsLow (Isolated from host)
Override Bind AddressWhen Redis config restricts to localhost2 minsMedium (Exposes Redis to all interfaces)
Docker ComposeManaging multi-container applications5 minsLow (Best practice)

Understanding the Error

The Connection refused error when trying to access a Redis instance running inside a Docker container is one of the most common stumbling blocks for developers. When your application throws an error like Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379 or Could not connect to Redis at 127.0.0.1:6379: Connection refused, it means the client attempted to establish a TCP connection, but the target machine or container actively rejected it.

In the context of Docker and Redis, this almost always boils down to one of three root causes: networking, port mapping, or Redis's own security defaults.

Root Cause 1: Redis Bind Address (The Localhost Trap)

By default, Redis is configured to be highly secure. The default redis.conf includes the directive bind 127.0.0.1 -::1. This tells the Redis server to only listen for connections originating from the local loopback interface.

When you run Redis inside a Docker container, 127.0.0.1 refers to the container's internal loopback interface, not your host machine's loopback interface. If you try to connect from your host machine (even if you mapped the ports) or from another container, the connection originates from an external IP relative to the Redis container. Because Redis is only listening on its internal 127.0.0.1, it rejects the external connection.

Root Cause 2: Missing Port Publishing

Docker containers are isolated environments. By default, processes running inside a container cannot be reached from the outside world (your host OS or the external network). To allow external traffic to reach a container, you must explicitly publish the port using the -p or --publish flag.

If you run docker run -d redis, the container is running and Redis is listening on port 6379 internally, but port 6379 on your host machine is completely unaware of it.

Root Cause 3: Docker Networking Contexts

If you have a Node.js or Python application running in Container A and Redis running in Container B, they cannot communicate using localhost. To Container A, localhost is itself. To Container B, localhost is itself.

If Container A tries to connect to redis://localhost:6379, it will look for Redis inside Container A, fail to find it, and throw a Connection refused error.


Step-by-Step Troubleshooting and Fixes

Scenario A: Connecting from the Host Machine

If you are running a script, a GUI tool like RedisInsight, or a local development server directly on your Mac, Windows, or Linux host OS, and you want it to connect to the Dockerized Redis:

Step 1: Publish the Port Ensure you are using the -p flag when starting the container.

# Correct way to start Redis for host access
docker run -d --name local-redis -p 6379:6379 redis

The syntax is -p <host_port>:<container_port>. This maps port 6379 on your host machine to port 6379 inside the container.

Step 2: Connect using Localhost Now, from your host machine, you can connect using localhost or 127.0.0.1.

redis-cli -h 127.0.0.1 -p 6379

Note: The official Redis Docker image is pre-configured to bind to all interfaces (0.0.0.0) by default to make container usage easier. If you are using a custom redis.conf, ensure you have bind 0.0.0.0 set.

Scenario B: Connecting Container to Container (The Right Way)

If you are running your application in Docker as well, you should not use localhost or mapped ports to communicate between containers. Instead, use Docker Networks.

Step 1: Create a Docker Network

docker network create my-app-network

Step 2: Run Redis on the Network

docker run -d --name redis-server --network my-app-network redis

Step 3: Run your App on the same Network When running your application container, attach it to the same network. Docker's built-in DNS will automatically resolve the container name (redis-server) to its internal IP address.

# Example: Running a Node app
docker run -d --name my-node-app --network my-app-network my-node-image

Step 4: Update your Connection String Inside your application code, change the Redis host from localhost to the name of the Redis container (redis-server).

// Node.js Example
const redis = require('redis');
const client = redis.createClient({
  url: 'redis://redis-server:6379'
});

Scenario C: Using Docker Compose (Recommended for Local Dev)

Docker Compose simplifies networking drastically. Containers defined in the same docker-compose.yml file are automatically placed on a shared custom network and can resolve each other by their service names.

version: '3.8'
services:
  cache:
    image: redis:alpine
    # No 'ports' mapping needed for app-to-cache communication!
    
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      - REDIS_URL=redis://cache:6379
    depends_on:
      - cache

Notice that the api service connects to redis://cache:6379. The hostname cache perfectly matches the service name of the Redis container.

Advanced: Custom redis.conf and Protected Mode

If you provide your own redis.conf file via a volume mount, you might accidentally inherit secure defaults that break containerized setups.

docker run -v /my/custom/redis.conf:/usr/local/etc/redis/redis.conf --name myredis redis redis-server /usr/local/etc/redis/redis.conf

If your custom redis.conf contains bind 127.0.0.1, Redis will reject connections from other containers. You must change it to bind 0.0.0.0.

Additionally, Redis has a feature called Protected Mode. If protected mode is enabled and neither a bind address nor a password is set, Redis only accepts connections from the loopback interface. If you bind to 0.0.0.0 but leave protected mode on without a password, Redis might still refuse connections or only respond to PING with an error.

To fix this in your custom config:

bind 0.0.0.0
protected-mode no 
# OR set a requirepass and keep protected-mode yes

Alternatively, pass it as a command-line argument:

docker run -d -p 6379:6379 redis redis-server --protected-mode no

(Warning: Only disable protected mode in isolated Docker networks or local development. Never expose an unprotected Redis instance to the public internet.)

Debugging Checklist

When 'Connection refused' strikes, run through this checklist:

  1. Is the container actually running? Run docker ps. If it crashed immediately, run docker logs <container-id> to see why.
  2. Are you connecting from the host? Verify docker ps shows 0.0.0.0:6379->6379/tcp. If it just shows 6379/tcp, the port isn't published.
  3. Are you connecting from another container? Ensure both containers are on the same bridge network using docker network inspect <network-name>.
  4. Are you using the right hostname? Container-to-container communication must use the container name (e.g., redis-db), not localhost.
  5. Is a firewall blocking it? On Linux hosts, strict iptables rules or ufw might interfere with Docker's port forwarding. Check sudo ufw status.

By systematically verifying your port mappings, network contexts, and bind addresses, you can resolve Redis connection refused errors quickly and reliably.

Frequently Asked Questions

bash
# 1. Verify container is running and ports are published
docker ps | grep redis

# 2. Inspect Docker network to ensure both app and redis are attached
docker network inspect my-app-network

# 3. Test connection from host machine (requires -p 6379:6379)
redis-cli -h 127.0.0.1 -p 6379 ping

# 4. Start Redis with a custom bind address and protected mode disabled (for testing)
docker run -d -p 6379:6379 --name test-redis redis redis-server --bind 0.0.0.0 --protected-mode no
E

Error Medic Editorial

Error Medic Editorial comprises senior DevOps and Site Reliability Engineers dedicated to solving complex infrastructure and containerization challenges.

Sources

Related Guides