Search code examples
dockerredisdocker-composestunnel

Connect to Redis server from within a Docker image


I have 2 hosts, a web unit (WU) and a computing unit (CU). On the WU, I have my website. On the CU, I have a redis server and a (C++) app that does some computing.

The user enters input data in the website, and then I want to enqueue a job from the WU to the Redis server on the CU. I have then a worker on the CU which performs a task.

Now, I am able to enqueue a job from the WU (outside of any docker image) to the CU from the terminal (using the python rq module). However, my website is in a docker image, and I can't get it working. From within the docker image, I try to connect to 172.17.0.1:6370 (172.17.0.1 is the IP of the gateway between the image and the docker host). The error I get is connection refused. Then I thought I might have to map the ports in my docker-compose file: 6739:6739. However, then I got an error saying the port is already used. And indeed, it is used by the stunnel4 service which allows me to enqueue jobs from the WU to the redis server on the CU.

Should I run the stunnel4 service in the docker image are something? And if so, how could I do that? Or should I tackle my problem in a different way?

Network structure

WU and CU are 2 (virtual) machines. My redis server is on CU and not in a docker container. I am able to connect to the redis server from WU to CU by means of the python redis module (but not from within a docker container). I had to set up a stunnel4.service for that (redis-client on WU and redis-server on CU).


Solution

  • Finally I managed to build a stunnel service in a docker container on the WU. I can now simply connect with python redis to that stunnel service, and the end of the tunnel points to the CU.

    Here is what I did on the WU:

    Dockerfile

    FROM alpine:3.12
    RUN apk add --no-cache stunnel
    COPY ./entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    COPY ./ca_file.crt /etc/stunnel/ca_file.crt
    ENTRYPOINT ["/entrypoint.sh"]
    

    entrypoint.sh

    #!/bin/sh
    cd /etc/stunnel
    
    cat > stunnel.conf <<_EOF_
    
    foreground = yes
    
    [stunnel-client]
    client = yes
    accept = ${ACCEPT}
    connect = ${CONNECT}
    CAfile = ca_file.crt
    verify = 4
    
    _EOF_
    
    exec stunnel "$@"
    

    The ACCEPT and CONNECT values are specified in an environment file:

    .env.stunnel

    ACCEPT=6379
    CONNECT=10.110.0.3:6379
    

    where 10.110.0.3 is the IP address of my redis host.

    docker-compose

    stunnel-client:
        container_name: stunnel-client
        build:
          context: ./stunnel
          dockerfile: Dockerfile
        restart: always
        volumes:
          - stunnel_volume:/etc/stunnel
        env_file:
          - ./.env.stunnel
        networks:
          - stunnel-net
        ports:
          - "6379:6379"
    

    The stunnel-net is also in my web service so I can connect from there to the stunnel-client service by means of python redis.