Linking Docker Containers

2019-06-09 23:43发布

问题:

I have a nodejs app i'm trying to run in a docker container. My app uses mongodb and redis.

I've pulled down both a mongo and redis container and dockerized my app.

I started up my mongo and redis containers like:

docker run -i -t --name redis -d redis
docker run -i -t --name mongo -d mongo

Now, I link my nodejs app container to both of these and run the app:

docker run -i -t --name myapp --link mongo:mongo --link redis:redis mseay/myapp node /myapp/server.js

When I run my app, it fails with the error

Error: Redis connection to localhost:6379 failed - connect ECONNREFUSED

My app cannot connect to either my redis container or mongo even though they're both running.

CONTAINER ID        IMAGE                     COMMAND                    CREATED             STATUS              PORTS                     NAMES
8709c818014a        redis:latest              "/entrypoint.sh redi   12 minutes ago      Up 12 minutes       6379/tcp                  redis
6d87364ad4c9        mongo:latest              "/entrypoint.sh mong   12 minutes ago      Up 12 minutes       27017/tcp                 mongo

Any ideas?

回答1:

Make sure that you are connecting to your mongodb and redis instance as so:

Note that I have made some changes how you link your containers. The names are important as they are referred later.

docker run -i -t --name myapp --link mongo:MONGODB --link redis:REDIS mseay/myapp node /myapp/server.js

For connecting to MongoDB:

IP = process.env.MONGODB_PORT_27017_TCP_ADDR
PORT = process.env.MONGODB_PORT_27017_TCP_PORT
var mongoUrl = 'mongodb://' + IP + ':' + PORT + '/';

or you can simply use:

var mongoUrl = 'mongodb://' + MONGODB + ':27017/';

Similarly connect to redis database by using its ip as REDIS.

Explanation:

When you create a docker container and link other docker containers via the --link parameter, docker modifies your containers hosts file and inserts the IP of the linked containers against their names (that you choose as --link=container_name:NAME_OF_YOUR_CHOICE).

Hence, if you open a bash in your new container and try to run

ping MONGODB
ping REDIS

you can see that both are reachable, and hence if you try connecting to them, it works (assuming your have mongodb and redis installed in the new container, and that your redis and mongodb instances are running on default ports)

mongo --host=MONGODB

redis-cli -h REDIS


回答2:

If you are using the official repo for redis https://registry.hub.docker.com/_/redis/,run the command docker run --name redis -d redis insted of

docker run -i -t --name redis -d redis

-i -t opens an interactive session -d opens as a daemon process so both should not be used together .

The linking command seems appropriate.

To check if the container is linked properly with your app, go into your app using /bin/bash and use env command.You should be able to see two environment variables stating redis host and redis port

This worked for me.Please let us know if you this worked for you also.



回答3:

Your error message says that you're trying to connect to localhost to get to redis. But you started your container with --link redis:redis, so you should be looking for Redis at hostname redis.



回答4:

Another cause of "connection refused" can be the Redis config not allowing anything else but 127.0.0.1 to connect. This is for example the default setting if you installed Redis using apt-get install redis-server.

Since the container linking to Redis will get a different originating ip-adress, you will get "Connection refused" when trying to connect.

One solution is to put a hash character in front of the line bind 127.0.0.1 in redis.conf.

This will however allow any host or container to connect to your Redis container, so this is only recommended if you have control over the host, so you can add firewall filters using on the host. Also, make sure that you trust all other containers that are executing on the host, otherwise they will be able to connect to your Redis container. Note that Redis also supports password upon connecting, which would make things safer even though you are sharing the host environment with other peoples containers.