Search code examples
dockerredis

docker redis: Failed opening Unix socket: bind: Address in use


I am trying to create a Docker container for redis. I want other services to connect to this container using a Unix socket instead of a TCP/IP socket.

This is my docker-compose.yml file:

services:
  redis:
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
    container_name: redis
    image: redis:alpine
    restart: unless-stopped
    volumes:
      - ./conf:/usr/local/etc/redis
      - /var/run/redis.sock:/var/run/redis.sock

In the redis.conf file I have enabled the Unix socket:

unixsocket /var/run/redis.sock
unixsocketperm 700

When I try to start the container, I get this error:

Failed opening Unix socket: bind: Address in use

I do not have any Redis instance already running on my machine.

I have seen some solutions which use a second container to hold the Unix socket and then share it using docker volumes, like this one:

services:
    tmp:
        image: busybox
        command: chmod -R 777 /tmp/docker
        volumes:
            - /tmp/docker/    
    redis:
        image: redis
        command: redis-server /etc/redis.conf
        volumes:
            - /redis/redis.conf:/etc/redis.conf
        volumes_from:
            - tmp

I have not tried this solution, but anyway I would like to avoid this additional container and simply expose the Unix socket on the Docker host.


Solution

  • After some digging I was able to fix this problem.

    docker-compose.yml for the Redis container:

    services:
      redis:
        # create a directory for the UDS and start Redis using the config file
        command: [
          "/bin/sh", "-c",
          "mkdir -p /var/run/redis && chown -R redis /var/run/redis && redis-server /usr/local/etc/redis/redis.conf"
        ]
        container_name: redis
        image: redis:${REDIS_VERSION}-alpine
        volumes:
          - ./conf:/usr/local/etc/redis
          - redis_socket:/var/run/redis
    
    # create a Docker volume for the Redis UDS
    volumes:
      redis_socket:
        name: redis_socket
    

    And this is the relevant Docker compose configuration to make another container (e.g. Nextcloud) able to talk to Redis through an UDS:

    services:
     nextcloud:
        container_name: nextcloud
        environment:
          - REDIS_HOST=/var/run/redis/redis.sock
          - REDIS_HOST_PORT=0
        image: nextcloud:${NEXTCLOUD_VERSION}-fpm-alpine
        volumes:
          - redis_socket:/var/run/redis
    
    volumes:
      redis_socket:
        external: true