Node in docker container can't connect to redis container - node.js

Here we are with another docker issue. I am writing a node app that needs to use redis, node app is inside a container and redis another container both on the same custom network.
Using docker compose:
node-app-test:
platform: linux/amd64
container_name: node-app-test
depends_on:
- redis-test
image: my-custom-image
ports:
- 8000:8000
networks:
- my-network-test
links:
- redis-test
redis-test:
platform: linux/amd64
container_name: redis-test
image: redis
ports:
- 6379:6379
networks:
- my-network-test
The basics of the node app that connects to redis is simply:
const redis = require("redis");
const redisClient = redis.createClient({
host: 'redis-test',
port: 6379
})
redisClient.connect();
redisClient.on("connect", () => {
console.log("REDIS IS CONNECTED")
})
redisClient.on("error", (error) => {
console.log("REDIS ERROR", error)
})
The error event is trapped with the following:
connect ECONNREFUSED 127.0.0.1:6379
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1195:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 6379
}
I have done a test outside of the container and the redis container does accept connections, not sure what's going on.
UPDATE
I think it's the redis node library that's the issue, it works if i connect by URL instead of host and port

Related

Bull queue not connecting with docker redis service. Error: connect ECONNREFUSED 127.0.0.1:6379

I am trying to establish a redis connection in nestjs via docker. I am using ioredis to connect to the redis but when I start my nest application I am keep on getting ECONNREFUSED. It also looks like the bull queue is also not establishing the connection with redis.
Error: connect ECONNREFUSED 127.0.0.1:6379 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16)
I have went through many solutions provided but nothing seems to be working.
#Module({
imports: [
ConfigModule.forRoot({
load: [redisConfig],
}),
BullModule.registerQueueAsync({
name: 'jobs',
imports: [ConfigModule.forFeature(bullQueueConfig)],
useFactory: async (configService: ConfigService) => ({
redis: {
...configService.get('bullQueue'),
},
}),
inject: [ConfigService],
}),
],
controllers: [ConfigurationController],
providers: [ConfigurationService, ConfigurationRepository],
exports: [ConfigurationService],
})
export class ConfigurationModule {}
bull queue config
export default registerAs('bullQueue', () => {
const redisURL =
process.env.NODE_ENV === 'local'
? {
host: process.env.BULL_QUEUE_REDIS_HOST,
port: parseInt(process.env.BULL_QUEUE_REDIS_PORT ?? '6379'),
}
: JSON.parse(JSON.stringify(process.env.REDIS_URL));
const env = {
...redisURL,
};
return env;
I get ECONNREFUSED error after the configuration module initialized.
In my .ts file
this.redisClient = new Redis({
...newRedisObj,
});
newRedisObj also holds the correct values
{host: 'redis', port: 6379}
Redis config
export default registerAs('redis', () => {
const redisURL =
process.env.NODE_ENV === 'local'
? {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT ?? '6379'),
}
: JSON.parse(JSON.stringify(process.env.REDIS_URL));
const env = {
...redisURL,
};
return env;
The config is returning the correct json with
{host: 'redis', port: 6379}
But it is still try to connect with 127.0.0.1:6379 and hence ECONNREFUSED.
The docker-compose has also the correct setup
redis:
container_name: redis_container
image: "bitnami/redis"
environment:
- ALLOW_EMPTY_PASSWORD=yes
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- "redis_data:/bitnami/redis/data"
I have this setup for redis and redis commander. Try it with docker compose -up
version: '3'
services:
redis:
image: 'redis:alpine'
ports:
- '6379:6379'
volumes:
- 'redis-data:/data'
redis-commander:
image: rediscommander/redis-commander:latest
environment:
- REDIS_HOSTS=local:redis:6379
ports:
- '8081:8081'
depends_on:
- redis
volumes:
redis-data:
external: false
Iguess it's because you have to use:
export default registerAs('redis', () => {
const redisURL =
process.env.NODE_ENV === 'local'
? {
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT ?? '6379'),
}
: JSON.parse(JSON.stringify(process.env.REDIS_URL));
// look here is surrounded by redis prop
const env = {
redis:...redisURL,
};
return env;
nestjs bull screenshoot

Express/NodeJS : Unable to connect to REDIS in docker from express app [duplicate]

I'm following a tutorial from youtube creating a simple dockerized CRUD application in Express, Node.js, Mongo & Redis. I stucked at video 3:06:57 on Authentication with sessions & Redis.
The initial issue I faced below when I send a POST
ClientClosedError: The client is closed
at Commander._RedisClient_sendCommand (/app/node_modules/#node-redis/client/dist/lib/client/index.js:408:31)
at Commander.commandsExecutor (/app/node_modules/#node-redis/client/dist/lib/client/index.js:166:154)
at Commander.BaseClass.<computed> [as set] (/app/node_modules/#node-redis/client/dist/lib/commander.js:8:29)
at RedisStore.set (/app/node_modules/connect-redis/lib/connect-redis.js:65:21)
at Session.save (/app/node_modules/express-session/session/session.js:72:25)
at Session.save (/app/node_modules/express-session/index.js:406:15)
at ServerResponse.end (/app/node_modules/express-session/index.js:335:21)
at ServerResponse.send (/app/node_modules/express/lib/response.js:221:10)
at ServerResponse.json (/app/node_modules/express/lib/response.js:267:15)
at exports.login (/app/controllers/authController.js:45:28)
[nodemon] app crashed - waiting for file changes before starting...
I found out that the issue above was due to Redis version, the tutorial video was using Redis 3.0+ if not mistaken , but I'm having Redis 6.0+ .So I added the line redisClient.connect().catch(console.error); but second issue happen.
Error: connect ECONNREFUSED 127.0.0.1:6379
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1138:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 6379
}
the source files as below:
index.js:
const express = require("express");
const mongoose = require("mongoose");
const session = require("express-session");
const redis = require("redis");
let RedisStore = require("connect-redis")(session);
const { MONGO_PASSWORD, MONGO_IP, MONGO_PORT, MONGO_USER, REDIS_URL, REDIS_PORT, SESSION_SECRET } = require("./config/config");
let redisClient = redis.createClient({
host: REDIS_URL,
port: REDIS_PORT,
})
// let redisClient = createClient({
// host: REDIS_URL,
// port: REDIS_PORT
// });
//redisClient.connect().catch(console.error);
redisClient.on('error', err => {console.log('Error ' + err);});
docker-compose.yml:
version : "3"
services :
node-app:
build : .
ports:
- "3000:3000"
environment:
- PORT=3000
depends_on:
- mongo
mongo:
image: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-db:/data/db
redis:
image: redis
volumes:
mongo-db:
docker-compose.dev.yml:
version : "3"
services :
node-app:
build:
context: .
args:
NODE_ENV: development
volumes:
- ./:/app
- /app/node_modules
environment:
- NODE_ENV=development
- MONGO_USER=admin
- MONGO_PASSWORD=password
- SESSION_SECRET=secret
command: npm run dev
mongo:
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
config.js:
module.exports = {
MONGO_IP: process.env.MONGO_IP || "mongo",
MONGO_PORT: process.env.MONGO_PORT || 27017,
MONGO_USER: process.env.MONGO_USER,
MONGO_PASSWORD: process.env.MONGO_PASSWORD,
REDIS_URL: process.env.REDIS_URL || "redis",
REDIS_PORT: process.env.REDIS_PORT || 6379,
SESSION_SECRET: process.env.SESSION_SECRET
}
I did a check to the redis container logs and it's up and running. Also it should be in the same network with the node-app.
docker command : docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
Full source code from tutor https://github.com/Sanjeev-Thiyagarajan/node-docker
Redis client doesn't work in v4 of Redis. Replace the redisClient code with this:
let redisClient = redis.createClient({
legacyMode: true,
socket: {
port: REDIS_PORT,
host: REDIS_URL
}
})
redisClient.connect().catch(console.error)
I've tried this code and it solves the problem at 100%.
let redisClient = redis.createClient({
legacyMode: true,
socket: {
port: REDIS_PORT,
host: REDIS_URL
}
});
redisClient.connect().catch(console.error)

Postgres isn't accepting any connection from other containers using docker-compose

I'm trying to connect my nodejs app with postgres using docker-compose.
Here's my docker-compose.yml
version: "3.9"
services:
db:
container_name: db
image: postgres
restart: always
environment:
POSTGRES_USER: agoodusername
POSTGRES_PASSWORD: astrongpassword
POSTGRES_DB: dbname
volumes:
- ./pgdata:/var/lib/postgresql/data
ports:
- 5433:5432
networks:
- postgres
pgadmin:
container_name: pgadmin4
platform: linux/amd64
image: dpage/pgadmin4
restart: always
depends_on:
- db
environment:
PGADMIN_DEFAULT_EMAIL: admin#admin.com
PGADMIN_DEFAULT_PASSWORD: root
ports:
- 5050:80
networks:
- postgres
be:
container_name: be
depends_on:
- db
build:
context: .
dockerfile: ./Dockerfile
ports:
- 3333:3333
networks:
- postgres
networks:
postgres:
driver: bridge
(Note that I have tried with and without networks)
My index.ts:
import { Entity, Column, PrimaryGeneratedColumn, createConnection } from "typeorm";
import express from 'express';
#Entity()
class Photo {
#PrimaryGeneratedColumn()
id?: number;
#Column()
name?: string;
#Column()
description?: string;
#Column()
filename?: string;
#Column()
views?: number;
#Column()
isPublished?: boolean;
}
const createCon = async () => {
let retries = 5;
while(retries) {
try {
const connection = await createConnection({
type: 'postgres',
url: 'postgres://agoodusername:astrongpassword#db:5433/dbname',
synchronize: false,
entities: [Photo]
});
console.log(connection.isConnected);
break;
}
catch(e) {
console.log(e);
retries -= 1;
await new Promise(res => setTimeout(res, 5000));
}
}
}
const app = express();
app.listen(3333, '0.0.0.0', () => {
createCon();
console.log("Server is running at port 3333");
})
Dockerfile:
FROM node:12.18.1-alpine
WORKDIR /app
COPY . .
RUN yarn
CMD ["yarn", "start"]
EXPOSE 3333
I ran postgres on its own docker container and node on another container (without docker-compose) everything works just fine.
Also, pgadmin container can't connect to the postgres container, I have provided the correct Hostname (db in this case) and the correct Host address (got it from running docker inspect db | grep IPAddress)
Here are the logs from the nodejs container:
yarn run v1.22.4
$ ts-node index.ts
Server is running at port 3333
Error: connect ECONNREFUSED 172.20.0.2:5433
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '172.20.0.2',
port: 5433
}
in case you want a full project check this repo
you are using incorrect port, 5433 port exposed outside, so it's only open on host, when using docker ip, you should use port inside running docker, that is 5432
As #crack_iT said in the comments, the port "5433" is exposed to the host machine, not to other containers, so to interact with the other container you should use the exposed port by the image (which in this case is 5432).

How to connect NATS server to NodeJS app in Docker

I have a node app which connects to NATS server. Below is my docker-compose.yml for both the servers.
version: "3"
services:
app:
image: node:12.13.1
volumes:
- ./:/app
working_dir: /app
depends_on:
- mongo
- nats
environment:
NODE_ENV: development
ports:
- 3000:3000
command: npm run dev
mongo:
image: mongo
expose:
- 27017
volumes:
- ./data/db:/data/db
nats:
image: 'nats:2.1.2'
# entrypoint: "/gnatsd -DV"
# entrypoint: "/nats-server -p 4222 -m 8888 "
expose:
- "4222"
ports:
- "8222:8222"
hostname: nats-server
app.post('/pets', function(req, res, next) {
let nats = NATS.connect('nats://nats-server:4222');
nats.publish('foo', 'Hello World!');
res.json({ stats: 'success' });
});
The above nodejs snippet gives me:
NatsError: Could not connect to server: Error: getaddrinfo ENOTFOUND nats-server
If I use let nats = NATS.connect() it gives me:
NatsError: Could not connect to server: Error: connect ECONNREFUSED 127.0.0.1:4222
Kindly throw me some ideas on how to resolve this issue.
Thanks.
let nats = NATS.connect('nats://nats:8222');
you need to use the name of the container, and attach the internal port

redis-server is not started

I have to dockerize a node app which used redis-server. I used docker-compose and official image of redis there.
But, when I run docker compose up, after hitting the API it gives me an error like this
[ioredis] Unhandled error event: Error: connect ECONNREFUSED 127.0.0.1:6379
docker-redis | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1106:14)
I used ioredis package, I give REDIS_PORT and REDIS_HOST as the argument of new Redis()
const Redis = require('ioredis');
const { promisify } = require('util');
const publisher = new Redis({
port: process.env.REDIS_PORT,
host: process.env.REDIS_HOST,
});
here REDIS_HOST='redis' and REDIS_PORT=6379
and this is my docker-compose file
version: '3'
services:
app:
container_name: docker-redis
restart: always
build: .
ports:
- '3000:3000'
links:
- redis
# depends_on:
# - redis
redis:
container_name: redis
image: redis:latest
ports:
- '6379:6379'
command: ['redis-server', '--bind', 'redis', '--port', '6379']

Resources