Exposing a Redis DB docker container to a NodeJS docker container
Launching windows 7 with vagrant version 1.6.5 and virtual box. I have two docker containers; - nodejs - redis
Part of my solution works and works! A nodejs app, when I run it outside of a VM, can connect to a redis container on port 6379. When I run the same app inside a nodejs docker container, I get the following exception:
Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
I can replicate the exception in an external project by stopping the redis container to make the problem appear to be related to how containers are bound / bound to internal ports in the VM.
The containers are started like this:
$ docker run -d -p 6379:6379 --name redis myproject/redis
$ docker run --rm -it -P -p 9090:9090 --name node --link redis:rs myproject/node
The second command allows me to launch and delete the image so that I can test and debug the problem. In my opinion, the communication between containers is correct!
I want to remove host port 6379 so that you can only hit port 9090 which will show the Redis functionality.
Sample dockerfile nodejs;
# DOCKER-VERSION 0.10.0
FROM ubuntu
RUN env
# make sure apt is up to date
RUN apt-get update
# install nodejs and npm
RUN apt-get install -y nodejs npm git git-core
RUN PATH=/usr/bin/node:$PATH
# Bundle app source
ADD src /opt/app/
# use changes to package.json to force Docker not to use the cache
# when we change our application nodejs dependencies:
ADD src/package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
RUN cp -a /tmp/node_modules /opt/app/redis
EXPOSE 9090
CMD ["nodejs", "/opt/app/redis/server.js"]`
Any help is appreciated.
Sample Redis dock file
# Pull base image.
FROM dockerfile/ubuntu
# Install Redis.
RUN \
cd /tmp && \
wget http://download.redis.io/redis-stable.tar.gz && \
tar xvzf redis-stable.tar.gz && \
cd redis-stable && \
make && \
make install && \
cp -f src/redis-sentinel /usr/local/bin && \
mkdir -p /etc/redis && \
cp -f *.conf /etc/redis && \
rm -rf /tmp/redis-stable* && \
sed -i 's/^\(bind .*\)$/# \1/' /etc/redis/redis.conf && \
sed -i 's/^\(daemonize .*\)$/# \1/' /etc/redis/redis.conf && \
sed -i 's/^\(dir .*\)$/# \1\ndir \/data/' /etc/redis/redis.conf && \
sed -i 's/^\(logfile .*\)$/# \1/' /etc/redis/redis.conf
# Define mountable directories.
VOLUME ["/data"]
# Define working directory.
WORKDIR /data
# Define default command.
ENTRYPOINT ["redis-server"]
# Define default command.
#CMD ["redis-server", "/etc/redis/redis.conf"]
# Expose ports locally on VM
EXPOSE 6379
J
source to share
Found a solution !!!
I updated my JS file as follows:
var redisHost = process.env.REDIS_PORT_6379_TCP_ADDR;
var redisPort = process.env.REDIS_PORT_6379_TCP_PORT;
console.log('Settings ' + redisHost + ' ' + redisPort);
var http = require("http"), server, redis_client = require("redis").createClient(redisPort, redisHost);
These environment variables are set based on the alias used when linking containers, that is, by running the following command;
docker run --rm -it -P -p 9090:9090 --name node --link redis:redis sapvagrant/node env
will produce the following output:
TERM=xterm
REDIS_PORT=tcp://172.17.0.38:6379
REDIS_PORT_6379_TCP=tcp://172.17.0.38:6379
REDIS_PORT_6379_TCP_ADDR=172.17.0.38
REDIS_PORT_6379_TCP_PORT=6379
REDIS_PORT_6379_TCP_PROTO=tcp
REDIS_NAME=/node/redis
HOME=/root
The important thing here is the alias used in the redis: redis link, if I were to rename this to redis: rs then the environments would be:
RS_PORT=tcp://172.17.0.38:6379
RS_PORT_6379_TCP=tcp://172.17.0.38:6379
RS_PORT_6379_TCP_ADDR=172.17.0.38
RS_PORT_6379_TCP_PORT=6379
RS_PORT_6379_TCP_PROTO=tcp
RS_NAME=/node/redis
Now when I run the nodejs container it can bind to the Redis database and Im able to expose port 9090 which will display some database functionality but port 6379 is not displayed.
Sample project available at; https://github.com/longieirl/docker-redis-nodejs
Happy Days.
J
source to share