Redis connection failure with Docker compose files - docker

I'm working with a docker-compose file from an open-source repo. Notably, it's missing the version and services keys, but it still works (up until now, I have not seen a compose file without these keys).
redis:
image: redis
ports:
- '6379'
app:
build: .
environment:
- LOG_LEVEL='debug'
links:
- redis
docker-compose up starts everything up and the app is able to talk to redis via 127.0.0.1:6379.
However, when I add the version and services keys back in, connections to redis are refused:
version: '3'
services:
redis:
image: redis
ports:
- '6379'
app:
build: .
environment:
- LOG_LEVEL='debug'
links:
- redis
Which results in:
[Wed Jan 03 2018 20:51:58 GMT+0000 (UTC)] ERROR { Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
at Object.exports._errnoException (util.js:896:11)
at exports._exceptionWithHostPort (util.js:919:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1073:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 6379 }
Why does adding version: '3' and services: lead to failure to connect?

You don't need to specify the ports neither the links for services in the same network (compose file). You can use:
version: '3'
services:
redis:
image: redis
app:
build: .
environment:
- LOG_LEVEL='debug'
And then in your app code refer to redis just as 'redis:6379'. If you see the Dockerfile for the redis image you can see the port is already exposed at the end.

When you want to expose the service to a specific host port, in Docker Compose version 3 you should use this syntax:
ports:
- '6379:6379'
Check the docs here:
Either specify both ports (HOST:CONTAINER), or just the container port
(a random host port will be chosen).

This is what worked for me after having the same issue:
docker-compose.yml
version: "3"
services:
server:
...
depends_on:
- redis
redis:
image: redis
My redis config file:
const redis = require('redis');
const redisHost = 'redis';
const redisPort = '6379';
let client = redis.createClient(redisPort, redisHost);
client.on('connect', () => {
console.log(`Redis connected to ${redisHost}:${redisPort}`);
});
client.on('error', (err) => {
console.log(`Redis could not connect to ${redisHost}:${redisPort}: ${err}`);
});
module.exports = client;

The port might be in use. Either kill the container using it or restarting docker will release the port.

Related

Could not get a resource from the pool - Error when connecting with redis docker container using Java

My Docker File:
version: "3.8"
services:
cache:
image: redis:latest
container_name: local-redis
restart: always
ports:
- '6379:6379'
command: redis-server --save 20 1 --loglevel warning --requirepass thisismypassword
volumes:
- cache:/data
volumes:
cache:
driver: local
My code to connect with the redis container:
JedisPoolConfig poolConfig = new JedisPoolConfig(); JedisPool jedisPool = new
JedisPool(poolConfig, "http://localhost", 6379, Protocol.DEFAULT_TIMEOUT, "thisismypassword");
Jedis jedis = jedisPool.getResource();
I still get the exception
redis.clients.jedis.exceptions.JedisConnectionException: Could not get
a resource from the pool
Some stackoverflow articles suggest that the redis server may not be running, which does not seem to be the case because trying to connect with the below code succeeds and I can perform any operation:
Jedis jedis = new Jedis("http://localhost:6379");
jedis.auth("thisismypassword");
However, I do not want to do this since below constructor is deprecated
Jedis jedis = new Jedis("http://localhost:6379");
You would have to send the hostname or host address for the concerned parameter. http://localhost is neither of them. Just use localhost for the value of that parameter.
So,
JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379, Protocol.DEFAULT_TIMEOUT, "thisismypassword");

issue redis and docker

I currently have a very strange error with docker more precisely with redis.
My backend runs with nodejs and typescript:
code
const redisPubSubOptions: any = {
host: process.env.REDIS_HOST || "127.0.0.1",
port: process.env.REDIS_PORT || 6379,
connectTimeout: 10000,
retryStrategy: (times: any) => Math.min(times * 50, 2000),
};
export const pubsub: RedisPubSub = new RedisPubSub({
publisher: new Redis(redisPubSubOptions),
subscriber: new Redis(redisPubSubOptions),
});
Dockerfile
FROM node:14-alpine as tsc-builder
WORKDIR /usr/src/app
COPY . .
RUN yarn install
EXPOSE 4000
CMD yarn run dev
docker-compose
version: "3.8"
services:
backend:
build: .
container_name: backend
ports:
- 4242:4242
depends_on:
- redis
env_file:
- ./docker/env/.env.dev
environment:
- ENVIRONMENT=development
- REDIS_PORT=6379
- REDIS_HOST=redis
redis:
image: redis:6.0.12-alpine
command: redis-server --maxclients 100000 --appendonly yes
hostname: redis
ports:
- "6379:6379"
restart: always
when I start my server the backend works and then the redis error comes after:
Error: connect ECONNREFUSED 127.0.0.1:6379
Both Redis and your backend run on different containers, so they have different IP addresses in the docker network. You are trying to connect to 127.0.0.1, which is the local address of the backend container.
Method 1:
Since you are using docker-compose (and of course it creates a network between services), you can use the service name instead of 127.0.0.1. For example:
const redisPubSubOptions: any = {
host: process.env.REDIS_HOST || "redis",
port: process.env.REDIS_PORT || 6379,
connectTimeout: 10000,
retryStrategy: (times: any) => Math.min(times * 50, 2000),
};
export const pubsub: RedisPubSub = new RedisPubSub({
publisher: new Redis(redisPubSubOptions),
subscriber: new Redis(redisPubSubOptions),
});
Method 2:
The other method is to expose the Redis port to the IP address of the Docker interface in the Host machine. Most of the time that is 172.17.0.1, but with ip -o a (If you are using Linux) you can see the Docker interface and its IP address.
so you need to do this for that:
redis:
image: redis:6.0.12-alpine
command: redis-server --maxclients 100000 --appendonly yes
hostname: redis
ports:
- "172.17.0.1:6379:6379"
restart: always
This address 172.17.0.1:6379 (Or any Docker interface IP address on the Host) should be exposed for Redis. Easily you can use this address in the application.
Note: You can handle these values using environment variable which is a better and more standard solution. You can take a look at this.

"Docker redis error": connect ECONNREFUSED 127.0.0.1:6379 [duplicate]

This question already has answers here:
Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
(7 answers)
Closed 1 year ago.
###############
Docker file
###############
FROM node:alpine
WORKDIR '/app'
COPY package.json .
RUN yarn
COPY . .
CMD ["yarn","run","start"]
###################
docker-compose.yml
###################
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build: .
ports:
- "8081:8081"
---------------------------app.js---------------------------------------
const express = require('express');
const redis = require('redis');
const app = express();
const client = redis.createClient({
host:'localhost',
port: 6379
});
client.set('visits', 0);
app.get('/', (req, res) => { client.get('visits', (err, visits) => { res.send('Number of visits is ' + visits); client.set('visits', parseInt(visits) + 1); }); });
app.listen(8081, () => { console.log('Listening on port 8081'); });
##################################
Error message
##################################
node:events:346
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED 127.0.0.1:6379
As I see from app.js code, you're trying to access one docker container from another by using localhost, which is wrong. Docker-compose creates a network for your services and gives them hostname equal to service name by default. You can reference docker compose networking documentation for more details.
So, you should access redis service from your app by redis-server host instead of localhost.
Also, there is no exposed redis port in your docker-compose file. It should look like
version: '3'
services:
redis-server:
image: 'redis'
- "6379:6379"
node-app:
build: .
ports:
- "8081:8081"
And your application should create redis connection next way:
const client = redis.createClient({ host:'redis-server', port: 6379 });

Docker-compose: cannot connect api container to Minio container

I'm trying to connect my api server to a minio container, i'm using dockercompose like this:
minio:
image: "minio/minio"
# volumes:
# - ./docker-data/minio/data:/data
command: minio server /data
networks:
- backend
environment:
MINIO_ACCESS_KEY: 7PDZZCOFGYUASDCBWW9L
MINIO_SECRET_KEY: cSqaXmYpTk91asduFJ7ZKsZ+8e2pSLOXfc6ycogq
ports:
- "9000:9000"
api:
image: "applications-api"
networks:
- backend
environment:
NODE_ENV: test
ports:
- 3000:3000
# command: npm run dockertest
networks:
backend:
But I keep getting this error, the credentials are the same i cannot understand what i'm doing wrong, I appreciate any kind of help.
Error: connect ECONNREFUSED 172.22.0.2:443
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
errno: 'ECONNREFUSED',
code: 'NetworkingError',
syscall: 'connect',
address: '172.22.0.2',
port: 443,
region: 'eu-central-1',
hostname: 'minio',
retryable: true,
time: 2020-08-28T13:24:39.702Z```
I suspect the problem is your API tries to connect its own container's localhost.
If so, in your API code:
Try using host.docker.internal instead of localhost as minio client endpoint.
This will connect your API to the host's localhost.

Docker compose cross containers communication

I'm a very beginner in docker world, and I'm not able to make two containers communicate using docker compose.
I have two containers:
Service Registry: a simple spring boot application using Netflix Eureka to implement a service registry feature.
API Gateway: a simple spring boot application using Netflix Zuul. This application will try periodically to be registered into the Service Registry application by connecting to a given URL
All work fine without docker !!
And now with docker-compose, the gateway is not able to find the Eureka server URL.
docker-compose.yml file:
version: '3.5'
services:
gateway:
build:
context: ../robots-store-gateway
dockerfile: Dockerfile
image: robots-store-gateway
ports:
- 8000:8000
networks:
- robots-net
serviceregistry:
build:
context: ../robots-sotre-serviceregistry
image: robots-sotre-serviceregistry
ports:
- 8761:8761
networks:
- robots-net
networks:
robots-net:
name: custom_network
driver: bridge
The application.yml file of the gateway is:
eureka:
client:
service-url:
default-zone: http://serviceregistry:8761/eureka/
I receive this exception:
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException:
Connection refused (Connection refused)
I tried different ways to configure the Eureka client but no way !! it doesn't work.
Thanks in advance.
I don't exactly why !!! But finally, this works for me:
version: '3.5'
services:
gateway:
container_name: gateway
build:
context: ../robots-store-gateway
dockerfile: Dockerfile
image: robots-store-gateway
ports:
- 8000:8000
hostname: gateway
environment:
eureka.client.serviceUrl.defaultZone: http://serviceregistry:8761/eureka/
serviceregistry:
container_name: serviceregistry
build:
context: ../robots-sotre-serviceregistry
image: robots-sotre-serviceregistry
ports:
- 8761:8761
hostname: serviceregistry
environment:
eureka.client.serviceUrl.defaultZone: http://serviceregistry:8761/eureka/
You didn't set the container name.
Link
And the url or ip should replace to container name.
Example:
mongodb://{container_name}:27017

Resources