Search code examples
dockersocketsunixunix-socket

Sharing Linux socket between Docker containers


I have two Docker containers—redis (running a Redis database) and node (running a Node.js application). My Node.js application needs to communicate with the Redis database, but I'm not sure how I should arrange this. Here are some ways I've thought of so far:

  1. Put the two containers on one network, expose (but do not publish) port 6379 (or wherever the Redis server is listening) of the redis container, and connect to the exposed port from the node container.
  2. Have the Redis server listen on a UNIX socket that is mounted to some location on the host (i.e., outside of the redis container) that is also mounted into the node container (willl that even work?).
  3. Ditch the separate containers idea altogether and put the Redis server and Node app in the same container (I really do not want to do this).

Which option is the best, or is there something else that you would suggest? I want to maximize performance and security, but I also need to use container(s).

P.S. There are some similar questions to this one out there, but none of them seem to answer my question. That being said, if you find an existing answer that might help, please do link to it.


Solution

  • Presumably, the second approach has a higher performance. There are some comparisons here and here.

    In order to implement this approach, you can simply create a docker volume and mount it in both containers. e.g. you can create a Dockerfile based on redis image:

    FROM redis:7-alpine
    
    RUN mkdir -p /run/redis-socket
    RUN chmod 777 /run/redis-socket
    COPY ./etc/redis.conf /etc/redis.conf
    
    ENTRYPOINT ["docker-entrypoint.sh", "/etc/redis.conf"]
    

    and write such config to ./etc/redis.conf:

    unixsocket /run/redis-socket/redis.sock
    unixsocketperm 777 
    port 0
    

    Then mount a docker volume to /run/redis-socket/ of redis container. Don't forget to mount that volume to an arbitrary path in your node container.

    If you use docker-compose, a sample docker-compose.yml would be like this:

    version: "2.3"
    
    services:
      redis:
        image: my-altered-redis-image
        container_name: my-redis
        volumes:
          - redis-socket:/run/redis-socket
    
      mynode:
        image: my-node-image
        container_name: my-node
        depends_on:
          - "redis"
        volumes:
          - redis-socket:/run/redis-socket
    
    volumes:
      redis-socket: