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

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 });

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.

Unable to connect to postgresql through node/express; postgresql and node running in docker container

Client (React), server (Node) and database(postgres) are all running in docker container. I am using npm package 'pg' to create pool and connect to the postgres database through express. However, I am not able to connect. Not able to run any query.
But I am able to connect the same postgres image through pgAdmin in my local machine. By connecting to port 5435.
I am new to docker and I am not able to figure out anything.
Help.
docker-compose.yml
version: '3'
services:
postgres:
image: postgres:latest
environment:
- POSTGRES_PASSWORD=postgres_password
ports:
- '5435:5432'
web-app:
build:
context: ./client
dockerfile: Dockerfile.dev
volumes:
- /app/node_modules
- ./client:/app
ports:
- '4001:3000'
restart: on-failure
to-do-api:
build:
context: ./server
dockerfile: Dockerfile.dev
ports:
- '5001:3001'
restart: on-failure
volumes:
- /app/node_modules
- ./server:/app
environment:
- PGUSER=postgres
- PGHOST=postgres
- PGDATABASE=postgres
- PGPASSWORD=postgres_password
- PGPORT=5432
index.js
require('dotenv').config();
// Express App Setup
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const cors = require('cors');
const uuid = require('uuid/v4');
// Config
const config = require('./config');
// Initialization
const app = express();
app.use(cors());
app.use(bodyParser.json());
// Postgres client
const { Pool, Client } = require('pg');
console.log('config.pgUser', config.pgUser);
const pool = new Pool({
user: config.pgUser,
host: config.pgHost,
database: config.pgDatabase,
password: config.pgPassword,
port: config.pgPort,
max : 20,
});
async function testConnection() {
try {
return await pool.query("DROP TABLE IF EXISTS task"+
"CREATE TABLE task (id serial PRIMARY KEY, name VARCHAR(50), lastname VARCHAR(50));");
} catch (e) {
console.log(e)
}
async function main() {
await testConnection();
}
main()
.then (() => {
console.error('Done');
process.exit(0);
})
.catch((err) => {
console.error('Error: %s', err);
console.error('Error: %s', err.stack);
process.exit(1);
});
main();
pool.on('error', () => console.log('Lost Postgres connection'));
// Server
const port = process.env.PORT || 3001;
const server = http.createServer(app);
server.listen(port, () => console.log(`Server running on port ${port}`));
Note: I am trying to connect to postgres running in docker container and create a table by running the query using node postgresql
Make sure you are using one of the recent versions of the postgres npm dependency.
You can set the pg npm package version 8.7.1 by adding "pg": "8.7.1" in depencecies object in package.json file in your express server folder.
There can be 2 possible reasons:
You need to pass the environment variables like: POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD in the docker compose file.
For Example:
# docker-compose.yml
version: '3.1'
services:
db:
image: postgres
restart: always
container_name: 'Postgresql'
ports:
- "5432:5432"
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- ./data:/var/lib/postgresql/data
Sometimes if you are working in windows you need to find you IPv4 Address address using ipconfig command in CMD and replace it with localhost.
This worked for me.

Go backend to redis connection refused after docker compose up

I'm currently trying to introduce docker compose to my project. It includes a golang backend using the redis in-memory database.
version: "3.9"
services:
frontend:
...
backend:
build:
context: ./backend
ports:
- "8080:8080"
environment:
- NODE_ENV=production
env_file:
- ./backend/.env
redis:
image: "redis"
ports:
- "6379:6379"
FROM golang:1.16-alpine
RUN mkdir -p /usr/src/app
ENV PORT 8080
WORKDIR /usr/src/app
COPY go.mod /usr/src/app
COPY . /usr/src/app
RUN go build -o main .
EXPOSE 8080
CMD [ "./main" ]
The build runs successfully, but after starting the services, the go backend immediately exits throwing following error:
Error trying to ping redis: dial tcp 127.0.0.1:6379: connect: connection refused
Error being catched here:
_, err = client.Ping(ctx).Result()
if err != nil {
log.Fatalf("Error trying to ping redis: %v", err)
}
How come the backend docker service isn't able to connect to redis? Important note: when the redis service is running and I start my backend manually using go run *.go, there's no error and the backend starts successfully.
When you run your Go application inside a docker container, the localhost IP 127.0.0.1 is referring to this container. You should use the hostname of your Redis container to connect from your Go container, so your connection string would be:
redis://redis
I found I was having this same issue. Simply changing (in redis.NewClient(&redis.Options{...}) Addr: "localhost:6379"to Addr: "redis:6379" worked.
Faced similar issue with Golang and redis.
version: '3.0'
services:
redisdb:
image: redis:6.0
restart: always
ports:
- "6379:6379"
container_name: redisdb-container
command: ["redis-server", "--bind", "redisdb", "--port", "6379"]
urlshortnerservice:
depends_on:
- redisdb
ports:
- "7777:7777"
restart: always
container_name: url-shortner-container
image: url-shortner-service
In redis configuration use
redisClient := redis.NewClient(&redis.Options{
Addr: "redisdb:6379",
Password: "",
DB: 0,
})

Redis connection failure with Docker compose files

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.

Resources