I have the following docker-compose.yml
:
version: '3'
services:
web:
build: .
image: webapp
env_file: .env.docker
ports:
- "3000:3000"
links:
- redis
- mongo
redis:
image: "redis:alpine"
mongo:
image: "mongo"
And I'm using the following env variables to connect to Mongo and Redis
REDIS_URL=redis://redis:6379
DATABASE_URL=mongodb://mongo:27017/webapp
With this configuration, when the app starts it can connect to the Mongo container, but it fails to connect to Redis with the following error:
Error: connect ECONNREFUSED 127.0.0.1:6379
I tried exposing and mapping the ports:
expose:
- "6379"
ports:
- "6379:6379"
but it still doesn't solve the issue. Mapping the ports I can use redis-cli to connect to Redis, so I know the container is running.
Any clues?
EDIT: Running the webapp on my machine without Docker works normally. I tried both, native Redis and Mongo as well as running with the docker-compose
below commenting out the web
section and mapping the ports.
EDIT 2: Output of lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
com.docke 3136 JayC 20u IPv4 0x7dac4a08aadc94c9 0t0 TCP *:6379 (LISTEN)
com.docke 3136 JayC 21u IPv6 0x7dac4a08bbf50781 0t0 TCP localhost:6379 (LISTEN)
EDIT 3: Adding where the app connects to Redis:
const { RedisPubSub } = require('graphql-redis-subscriptions');
console.log(`-------------- REDIS_URL: ${process.env.REDIS_URL} --------------`);
const engine = new RedisPubSub({
connection: {
url: process.env.REDIS_URL,
},
connectionListener: err => {
if (err) {
Logger.sys.error(
`redis connection failed at ${process.env.REDIS_URL}`,
);
Logger.sys.error(err);
} else {
Logger.sys.info(
`pubsub connected to redis at ${process.env.REDIS_URL}`,
);
}
},
});
The log output:
-------------- REDIS_URL: redis://redis:6379 --------------
2018-06-05T13:21:37.658Z - error: redis connection failed at redis://redis:6379
2018-06-05T13:21:37.659Z - error: { Error: connect ECONNREFUSED 127.0.0.1:6379
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1182:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 6379 }
The configuration you described is not being used by your application:
REDIS_URL=redis://redis:6379
When you see the connection run, it's trying to connect to 127.0.0.1 instead of the container ip:
Error: connect ECONNREFUSED 127.0.0.1:6379
To solve this, you'll need to reconfigure your app so that it uses the redis DNS name instead of 127.0.0.1. Each container has its own private loopback interface, so connecting to this inside a container will connect to the container itself, not your host or any other container running on the host.
As an aside, do not use links. They have been deprecated. The built in DNS will give name resolution to the service name. If you have dependencies between containers, it's best to handle this in the application or entrypoint. You can also use depends_on
to list service dependencies, but this only works with docker-compose, and does not verify the health of the dependent services.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With