Docker Redis Connection refused

31,744

Solution 1

Your Problem

Docker Compose creates separated docker container for different services. Each container are, logically speaking, like different separated computer servers that only connected with each other through docker network.

Consider each boxes in this diagram as an individual computer, then this is practically what you have:

+----------------------------------------------------------+
|                       your machine                       |
+----------------------------------------------------------+
                               |                    
        +------ (virtual network by docker) -------+
        |                      |                   |
+-----------------+ +-------------------+ +----------------+
| "php" container | | "redis" container | | "db" container |
+-----------------+ +-------------------+ +----------------+

Your PHP container doesn't see any redis in "localhost" because there is no redis in it. Just like it would't see any MySQL in "localhost". Your redis is running in the "redis" container. Your MySQL is running in your "db" container.

The things that confuses you is the port binding directives (i.e. ports in this definition):

redis:
  build:
    context: .
    dockerfile: Dockerfile_redis
  ports:
    - "6379:6379"

The port 6379 of the "redis" container is binded to your computer, but to your computer ONLY. Other container doesn't have the same access to the port bindings. So even your computer can connect it with '127.0.0.1:6379', the php container cannot do the same.

Solution

As described in Networking in Docker Compose, each docker compose container can access other container by using the service name as hostname. For example, your programming running by service php can access your MySQL service with the hostname db.

So you should connect redis with its hostname redis

$redis = new \Redis();
try {
    $redis->connect('redis', 6379);
} catch (\Exception $e) {
    var_dump($e->getMessage())  ;
    die;
}

Solution 2

just remove the redis port and change the redis hostname to redis in your Laravel project .env file.

REDIS_HOST=redis
#REDIS_PORT=6379

Solution 3

If using a static-ip for your network use below instead of localhost

$redis->connect('<static-ip>', 6379);
Share:
31,744

Related videos on Youtube

Isuru Buddhika
Author by

Isuru Buddhika

Updated on July 09, 2022

Comments

  • Isuru Buddhika
    Isuru Buddhika almost 2 years

    I'm trying to access Redis server through the code and it's not connecting. But if i bash to the redis container i can access the redis-cli.

    docker-compose.yml looks like this

    version: '2'
    services:
      web:
       build:
        context: .
        dockerfile: Dockerfile_nginx
       ports:
        - "9000:80"
       environment:
        - NGINX_SERVERNAME=xxx.dev *.xxx.dev
       command: /bin/bash -c "envsubst '$$NGINX_SERVERNAME' < /var/www/site.template > /etc/nginx/conf.d/default.conf
                              && dos2unix /var/www/provision/init_storage.sh && sh /var/www/provision/init_storage.sh
                              && nginx -g 'daemon off;'"
       volumes:
         - .:/var/www
       links:
         - php
       networks:
         frontend
    
      php:
        build:
          context: .
          dockerfile: Dockerfile_php-fpm
        command: /bin/bash -c "composer install
                  && php-fpm"
        volumes:
              - .:/var/www
        environment:
              - APP_ENV=local
              - APP_DEBUG=true
        networks:
          - frontend
          - backend
        links:
             - redis
      db:
        build:
          context: .
          dockerfile: Dockerfile_mariadb
        volumes:
          - ./initdb:/docker-entrypoint-initdb.d
        ports:
          - "3309:3306"
        environment:
          MYSQL_ROOT_PASSWORD: xxxx
          MYSQL_DATABASE: xxxx
        networks:
          - backend
      redis:
        build:
          context: .
          dockerfile: Dockerfile_redis
        ports:
          - "6379:6379"
    
    networks:
      frontend:
        driver: bridge
      backend:
        driver: bridge
    

    Dockerfile_redis

    FROM redis:latest
    

    When i try to connect to the redis server using this code

    $redis = new \Redis();
        try {
            $redis->connect('127.0.0.1', 6379);
        } catch (\Exception $e) {
            var_dump($e->getMessage())  ;
            die;
        }
    

    It gives this warning

    Warning: Redis::connect(): connect() failed: Connection refused
    

    Does anyone know how to connect Redis container to PHP container ?

  • Isuru Buddhika
    Isuru Buddhika about 7 years
    Forgot to mention that I've added networks. redis: build: context: . dockerfile: Dockerfile_redis networks: - frontend - backend
  • TimCO
    TimCO over 3 years
    great ascii diagram and explanation!
  • Prasan Dutt
    Prasan Dutt about 3 years
    Good explanation, I had similar problem for python program. I started the docker image with outbound port and network as host to make it accessible from python client program.