Unable to use Postgres DB in docker-compose - ECONNREFUSED - node.js

I have a Node.js app and have set up docker-compose. I'm trying to use Postgres DB in the container.
Here is docker-compose
version: "3"
services:
web:
build: .
ports:
- "3000:3000"
links:
- redis
- db
angular: # image of nginx
image: "qp-angular-nginx"
ports:
- "4200:80" # specify port forewarding
redis:
image: "redis:3"
ports:
- "6379:6379"
db:
image: "postgres:9.6"
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- pgdata:/var/lib/postgresql/data
dbadmin:
image: "myimage/phppgadmin"
ports:
- "8085:80"
environment:
POSTGRES_HOST: db
POSTGRES_PORT: 5432
volumes:
pgdata:
I have the containers running successfully and even database connected, but I get this error when making a DB request
"stack": {
"code": "ECONNREFUSED",
"errno": "ECONNREFUSED",
"syscall": "connect",
"address": "127.0.0.1",
"port": 5432
}

If you connect to the database from another docker container, use the service name in the connection string(db in your case). From the error message it seems that there is something wrong with your configuration. It tries to connect to localhost (127.0.0.1)

For those, you use more recent structure project with a config file like below:
require('dotenv').config();
module.exports = {
development: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.APP_URL_DOCKER,
dialect: 'postgres'
},
test: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.APP_URL_DOCKER,
dialect: 'postgres'
},
production: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.APP_URL_DOCKER,
dialect: 'postgres'
}
};
You can specify the service name of your postgres database in your .envfile. And it should be good for you.
// .env file
APP_URL_LOCAL=127.0.0.1
APP_URL_DOCKER=db # database service name
APP_PORT=8000
APP_KEY=6dd63668dab9a309c7c59a2982126a43b064816925a40b9680d16e2665f41b676a87dae4d506712e6332479c82827993059ddefb607b65caa3534b66b20253ed
DB_USER=postgres
DB_PASSWORD=db_password
DB_NAME=db_name
DB_PORT_CONTAINER=5432
DB_PORT_LOCAL=5433

Related

PG Pool is not working inside Docker container

I am running a PERN application and currently trying to dockerize it. When I run the database as a container and the server and client locally I have no issues. However, when I containerize the server, client, and database respectively, I am unable to make requests. It results in 404 errors. This is the same behavior that occurs when I pass pool the wrong port or host. So I'm wondering if somehow I am giving the wrong host and/or port to pool or if I should change it when I containerize it.
This is the Pool Instance
const Pool = require('pg').Pool
const pool = new Pool({
user: 'docker',
password: 'docker',
host: "localhost",
port: 4000,
database: "docker"
})
This is part of the rest api in the server:
const express = require("express")
const router = express.Router()
const pool = require('../database/database.js')
router.get("/:login", async (req, res) => {
try {
let loginReq = JSON.parse(decodeURIComponent(req.params.login))
const user = await pool.query(
"SELECT user_id,first_name,last_name,email FROM \"user\" where email = $1 and password = $2",
[loginReq.email, loginReq.password]
)
if(user.rows.length) {
res.json(user.rows[0])
} else {
throw new Error('User Not Found')
}
} catch (err) {
res.status(404).json(err.message)
}
})
This is each of my dockerfiles for my client, server, and database
Client:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["npm","start"]
EXPOSE 3000
Server:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["node","index.js"]
EXPOSE 5000
Database;
FROM postgres:15.1-alpine
COPY init.sql /docker-entrypoint-initdb.d/
This is my docker-compose.yml
version: "3.8"
services:
client:
build: ./client
ports:
- "3000:3000"
restart: unless-stopped
server:
build: ./server
ports:
- "5000:5000"
restart: unless-stopped
database:
build: ./database
ports:
- "4000:4000"
environment:
- POSTGRES_USER=docker
- POSTGRES_PASSWORD=docker
- POSTGRES_DB=docker
- PGPORT=4000
volumes:
- kurva:/var/lib/postgresql/data
restart: unless-stopped
volumes:
kurva:
I don't understand why the behavior would be different between containerizing the server and running it locally when they all use the same ports. I have tried messing with the host and changing it to 0.0.0.0 but that did not help. Any help would be appreciated!
I found that it was a host issue and I needed to change the host accessed in the pool to the service name. Additionally, I needed to add that the server depends on the database service.
This is the updated pg pool:
const pool = new Pool({
user: 'docker',
password: 'docker',
host: "database",
port: 4000,
database: "docker"
})
This is the updated docker-compose.yml
version: "3.8"
services:
client:
build: ./client
ports:
- "3000:3000"
restart: unless-stopped
server:
build: ./server
ports:
- "5000:5000"
depends_on:
- database
restart: unless-stopped
database:
build: ./database
ports:
- "4000:4000"
environment:
- POSTGRES_USER=docker
- POSTGRES_PASSWORD=docker
- POSTGRES_DB=docker
- PGPORT=4000
volumes:
- kurva:/var/lib/postgresql/data
restart: unless-stopped
volumes:
kurva:

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).

mongoose couldn't connect to mongodb in docker

mongoose couldn't authenticate with docker mongodb container.
Note: mongo is in docker and my API app out of the docker.
docker-compose:
version: "3.7"
services:
db:
image: mongo:latest
environment:
MONGO_INITDB_ROOT_USERNAME: "${MONGO_USERNAME}"
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_PASSWORD}"
MONGO_INITDB_DB: "${MONGO_DB}"
ports:
- 27017:27017
volumes:
- mongo_data:/data/db
volumes:
mongo_data:
.env:
MONGO_USERNAME=root
MONGO_PASSWORD=123456
MONGO_DB=nodeApp
db.js (database connection file):
(async () => {
try {
const uri = `mongodb://127.0.0.1:27017/${process.env.MONGO_DB}`;
await mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
user: process.env.MONGO_USERNAME,
pass: process.env.MONGO_PASSWORD,
});
console.log("Database connection completed successfully");
} catch (error) {
console.error(error);
}
})();
and finally this is what I got from console:
I can connect to mongo with mongoose with username and password.
Docker only supports using default environment variables to be used like what you did in your code.
https://docs.docker.com/compose/env-file/
Docker added support to env filed since version 1.3 (as I remember). The soloution is to use env_file key in your yml file.
services:
db:
image: mongo:latest
environment:
MONGO_INITDB_ROOT_USERNAME: "${MONGO_USERNAME}"
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_PASSWORD}"
MONGO_INITDB_DB: "${MONGO_DB}"
ports:
- 27017:27017
volumes:
- mongo_data:/data/db
env_file:
- mongo_variables.env
Instead of localhost use your ip on database configuration.
Replace this DBurl=mongodb://localhost:27017/
to this one DBurl=mongodb://X.X.X.X:27017/ ( X.X.X.X means your ip address )on your database configuration file.
On your docker-compose.yml file
Inside of services of api add CONNECTIONSTRING.
version: "3.7"
services:
api:
build: node-server ## as i am using node
ports:
- 3000:3000
environment:
- CONNECTIONSTRING=mongodb://X.X.X.X:27017/ ##X.X.X.X means your ip address
db:
image: mongo:latest
environment:
MONGO_INITDB_ROOT_USERNAME: "${MONGO_USERNAME}"
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_PASSWORD}"
MONGO_INITDB_DB: "${MONGO_DB}"
ports:
- 27017:27017
volumes:
- mongo_data:/data/db
volumes:
mongo_data:
you see that in the inspector docker -> port of your container -> (0.0.0.0:27017)
mongodb://0.0.0.0:27017/
;)

Running redis with docker compose

version: '3'
services:
postgres:
image: postgres
environment:
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_DATABASE}
ports:
- "5674:5432"
volumes:
- ./data/db_data:/var/lib/postgresql/data
redis_cache:
image: bitnami/redis
ports:
- "6379:6379"
environment:
- ALLOW_EMPTY_PASSWORD=yes
app:
image: asobooks-api
ports:
- 3000:3000
environment:
PORT: 3000
NODE_ENV: prod
DB_CONNECTION: postgres
DB_HOST: postgres
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_DATABASE: ${DB_DATABASE}
DB_PORT: 5432
REDIS_PORT: 6379
depends_on:
- postgres
- redis_cache
command:
[
'node',
'dist/src/main.js'
]
I have been trying this for about 2 days now and unfortunately, the app container fails to connect to Redis.
Unhandled error event: Error: connect ECONNREFUSED 127.0.0.1:6379
Here is the connection.
BullModule.registerQueue({
name: Queues.EMAIL,
redis: {
port: 6379,
host: 'redis_cache',
},
})
Please help me with this thing it works without using docker. But fails when I run in containers. Thanks.

Sequelize docker connection refused

I'm building an app running on NodeJS using postgresql. I'm using SequelizeJS as ORM. I have been trying to dockerize my app but get this error message:
SequelizeConnectionRefusedError: connect ECONNREFUSED 172.21.0.2:5432
My docker-compose:
version: '3'
services:
db:
image: postgres
restart: always
volumes:
- ./pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: sAjs21312ls
POSTGRES_DB: dev-player
ports:
- "5432:5432"
app:
build: .
environment:
DB_USER: postgres
DB_PASSWORD: sAjs21312ls
DB_NAME: dev-player
depends_on:
- db
ports:
- "8090:8090"
My sequelize connection:
const connection = new sequelize(
'dev-player',
'postgres',
'sAjs21312ls',
{
host: 'db',
port: 5432,
dialect: 'postgres'
}
);

Resources