Dockerized Node App unable to connect to Dockerized Postgres Database - node.js

I have tried many possible solutions to it, Not able to make any of them work.
Here it goes:
I built a nodejs container and a postgres docker container. Used docker compose to configure them both and used Dockerfile to build the nodejs/typescript application.
docker-compose.yml
version: "3"
volumes:
pg_vol:
networks:
app-network:
driver: bridge
services:
db:
container_name: db
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_DB=db22
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=q123
volumes:
- pg_vol:/var/lib/postgresql/data
networks:
- app-network
webapp:
container_name: webapp
build:
context: ./
dockerfile: Dockerfile
environment:
- DATABASE_URL=postgres://postgres:q123#db:5432/db22
ports:
- "5000:5000"
networks:
- app-network
depends_on:
- db
Dockerfile
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY ./dist .
CMD [ "npm", "start" ]
When I do docker-compose up --build, it shows an error while connecting to the postgres db. DB starts alright.
Error STDOUT
Starting db ... done
Starting webapp ... done
Attaching to db, webapp
db |
db | PostgreSQL Database directory appears to contain a database; Skipping initialization
db |
db | 2020-11-24 16:32:25.918 UTC [1] LOG: starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db | 2020-11-24 16:32:25.918 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db | 2020-11-24 16:32:25.918 UTC [1] LOG: listening on IPv6 address "::", port 5432
db | 2020-11-24 16:32:25.923 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db | 2020-11-24 16:32:25.928 UTC [25] LOG: database system was shut down at 2020-11-24 16:32:18 UTC
db | 2020-11-24 16:32:25.933 UTC [1] LOG: database system is ready to accept connections
webapp |
webapp | > backend-postgres#1.0.0 start /usr/src/app
webapp | > node app.js
webapp |
webapp | undefined
webapp | undefined
webapp | running in-code config
webapp | Error: connect EHOSTUNREACH 172.19.0.2:5432
webapp | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) {
webapp | errno: -113,
webapp | code: 'EHOSTUNREACH',
webapp | syscall: 'connect',
webapp | address: '172.19.0.2',
webapp | port: 5432
webapp | }
webapp | npm ERR! code ELIFECYCLE
webapp | npm ERR! errno 1
webapp | npm ERR! backend-postgres#1.0.0 start: `node app.js`
webapp | npm ERR! Exit status 1
webapp | npm ERR!
webapp | npm ERR! Failed at the backend-postgres#1.0.0 start script.
webapp | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
webapp |
webapp | npm ERR! A complete log of this run can be found in:
webapp | npm ERR! /root/.npm/_logs/2020-11-24T16_32_26_955Z-debug.log
webapp exited with code 1
Please help with correcting me.
System:
Fedora 33 (Workstation Edition)
EDIT:
I restarted the docker container with command docker start webapp. Same error as above.

Judging by logs: the app exits with 1 because the host at port 5432 was unreachable,maybe the database was not ready yet (you can verify it by checking if db22 is created on db container ).What you can is : add restart policy on webapp ,using this :
webap : ..
restart_policy: condition: on-failure
then check then if the problem persists

My system is Fedora 33 (Workstation Edition). This had some issues with Docker.
Turns out:
With the release of Fedora 33, Docker is not supported by Fedora 33 officially. Oct 29, 2020
I uninstalled docker. Rebooted my laptop.
Then install Podman and Podman Compose. Everything works perfectly fine.
Thank you all for help.

Related

P1001: Can't reach database server at `localhost`:`5432` error [duplicate]

This question already has answers here:
Docker - Can't reach database server at `localhost`:`3306` with Prisma service
(2 answers)
ECONNREFUSED for Postgres on nodeJS with dockers
(7 answers)
Closed 17 days ago.
This post was edited and submitted for review 16 days ago and failed to reopen the post:
Original close reason(s) were not resolved
I am trying to build a docker image from my project and run it in a container,
The project is keystone6 project connecting to a postgres database, everything worked well when I normally run the project and it connects successfully to the database.
Here is my dockerfile:
FROM node:18.13.0-alpine3.16
ENV NODE_VERSION 18.13.0
ENV NODE_ENV=development
LABEL Name="di-wrapp" Version="1"
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . .
RUN npm install
COPY .env .
EXPOSE 9999
CMD ["npm", "run", "dev"]
I am building an image using the command docker build -t di-wrapp:1.0 .
after that I run docker-compose file which contains the following code:
version: "3.8"
services:
postgres:
image: postgres:15-alpine
container_name: localhost
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=di_wrapp
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
dashboard:
image: di-wrapp:1.0
container_name: di-wrapp-container
restart: always
environment:
- DB_CONNECTION=postgres
- DB_PORT=5432
- DB_HOST=localhost
- DB_USER=postgres
- DB_PASSWORD=postgres
- DB_NAME=di_wrapp
tty: true
depends_on:
- postgres
ports:
- 8273:9999
links:
- postgres
command: "npm run dev"
volumes:
- /usr/src/app
volumes:
postgres-data:
And this is the connection URI used to connect my project to postgres:
DATABASE_URL=postgresql://postgres:postgres#localhost:5432/di_wrapp
which I am using to configure my db setting in keystone config file like this:
export const db: DatabaseConfig<BaseKeystoneTypeInfo> = {
provider: "postgresql",
url: String(DATABASE_URL!),
};
when I run the command docker-compose -f docker-compose.yaml up
This is what I receive:
localhost | 2023-02-03 13:43:35.034 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
localhost | 2023-02-03 13:43:35.034 UTC [1] LOG: listening on IPv6 address "::", port 5432
localhost | 2023-02-03 13:43:35.067 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
localhost | 2023-02-03 13:43:35.121 UTC [24] LOG: database system was shut down at 2023-02-03 13:43:08 UTC
localhost | 2023-02-03 13:43:35.155 UTC [1] LOG: database system is ready to accept connections
di-wrapp-container | > keystone-app#1.0.2 dev
di-wrapp-container | > keystone dev
di-wrapp-container |
di-wrapp-container | ✨ Starting Keystone
di-wrapp-container | ⭐️ Server listening on :8273 (http://localhost:8273/)
di-wrapp-container | ⭐️ GraphQL API available at /api/graphql
di-wrapp-container | ✨ Generating GraphQL and Prisma schemas
di-wrapp-container | Error: P1001: Can't reach database server at `localhost`:`5432`
di-wrapp-container |
di-wrapp-container | Please make sure your database server is running at `localhost`:`5432`.
di-wrapp-container | at Object.createDatabase (/usr/src/app/node_modules/#prisma/internals/dist/migrateEngineCommands.js:115:15)
di-wrapp-container | at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
di-wrapp-container | at async ensureDatabaseExists (/usr/src/app/node_modules/#keystone-6/core/dist/migrations-e3b5740b.cjs.dev.js:262:19)
di-wrapp-container | at async Object.pushPrismaSchemaToDatabase (/usr/src/app/node_modules/#keystone-6/core/dist/migrations-e3b5740b.cjs.dev.js:68:3)
di-wrapp-container | at async Promise.all (index 1)
di-wrapp-container | at async setupInitialKeystone (/usr/src/app/node_modules/#keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js:984:3)
di-wrapp-container | at async initKeystone (/usr/src/app/node_modules/#keystone-6/core/scripts/cli/dist/keystone-6-core-scripts-cli.cjs.dev.js:762:35)di-wrapp-container exited with code 1
even though I receive that the database server is up on port 5432, my app container can't connect to it.
any help is appreciated.

How do I set up docker-compose.yml, Express and TypeORM to connect my Express server to a Postgres db inside the container?

I am new to writing my own docker-compose.yml files because I previously had coworkers around to write them for me. Not the case now.
I am trying to connect an Express server with TypeORM to a Postgres database inside of Docker containers.
I see there are two separate containers running: One for the express server and another for postgres.
I expect the port 5432 to be sufficient to direct container A to connect to container B. I am wrong. It's not.
I read somewhere that 0.0.0.0 refers to the host machine's actual network, not the internal network of the containers. Hence I am trying to change 0.0.0.0 in the Postgres output to something else.
Here's what I have so far:
docker-compose.yml
version: "3.1"
services:
app:
container_name: express_be
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- ./src:/app/src
depends_on:
- postgres_db
ports:
- "8000:8000"
networks:
- efinternal
postgres_db:
container_name: postgres_be
image: postgres:15.1
restart: always
environment:
- POSTGRES_USERNAME=postgres
- POSTGRES_PASSWORD=postgres
ports:
- "5432:5432"
volumes:
- postgresDB:/var/lib/postgresql/data
networks:
- efinternal
volumes:
postgresDB:
driver: local
networks:
efinternal:
driver: bridge
Here's my console log output
ostgres_be | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres_be |
postgres_be | 2022-12-13 04:09:51.628 UTC [1] LOG: starting PostgreSQL 15.1 (Debian 15.1-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
postgres_be | 2022-12-13 04:09:51.628 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 // look here
postgres_be | 2022-12-13 04:09:51.628 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_be | 2022-12-13 04:09:51.636 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_be | 2022-12-13 04:09:51.644 UTC [28] LOG: database system was shut down at 2022-12-13 04:09:48 UTC
postgres_be | 2022-12-13 04:09:51.650 UTC [1] LOG: database system is ready to accept connections
express_be |
express_be | > efinternal#1.0.1 dev
express_be | > nodemon ./src/server.ts
express_be |
express_be | [nodemon] 2.0.20
express_be | [nodemon] starting `ts-node ./src/server.ts`
express_be | /task ... is running
express_be | /committee ... is running
express_be | App has started on port 8000
express_be | Database connection failed Failed to create connection with database
express_be | Error: getaddrinfo ENOTFOUND efinternal // look here
express_be | at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
express_be | errno: -3008,
express_be | code: 'ENOTFOUND',
express_be | syscall: 'getaddrinfo',
express_be | hostname: 'efinternal'
express_be | }
Not sure what to say about it. What I'm trying to do is to change the line " listening on IPv4 address "0.0.0.0", port 5432" to say "listening on ... efinternal, port 5432" so that "Error: getaddrinfo ENOTFOUND efinternal" will have somewhere to point to.
This link seemed to have the answer but I couldn't decipher it.
Same story here, I can't decipher what I'm doing wrong.
A helpful person told me about "external_links" which sounds like the wrong tool for the job: "Link to containers started outside this docker-compose.yml or even outside of Compose"
I suspect this is The XY Problem where I'm trying to Y (create an "efinternal" network in my containers) so I can X (connect express to postgres) when in fact Y is the wrong solution to X.
In case it matters, here's my TypeORM Postgres connection settings:
export const AppDataSource = new DataSource({
type: "postgres",
host: "efinternal",
port: 5432,
username: "postgres",
password: "postgres",
database: "postgres",
synchronize: true,
logging: true,
entities: [User, Committee, Task, OnboardingStep, RefreshToken, PasswordToken],
subscribers: [],
migrations: [],
});
The special IPv4 address 0.0.0.0 means "all interfaces", in whichever context it's invoked in. In a Docker container you almost always want to listen to 0.0.0.0, which will listen to all "interfaces" in the isolated Docker container network environment (not the host network environment). So you don't need to change the PostgreSQL configuration here.
If you read through Networking in Compose in the Docker documentation, you'll find that each container is addressable by its Compose service name. The network name itself is not usable as a host name.
I'd strongly suggest making your database location configurable. Even in this setup, it will have a different hostname in your non-Docker development environment (localhost) vs. running in a container (postgres_db).
export const AppDataSource = new DataSource({
host: process.env.PGHOST || 'localhost',
...
});
Then in your Compose setup, you can specify that environment-variable setting.
version: '3.8'
services:
app:
build: . # and name the Dockerfile just "Dockerfile"
depends_on: [postgres_db]
ports: ['8000:8000']
environment: # add
PGHOST: postgres_db
postgres_db: {...}
Compose also provides you a network named default, and for simplicity you can delete all of the networks: blocks in the entire Compose file. You also do not need to manually specify container_name:, and I'd avoid overwriting the image's code with volumes:.
This setup also supports using Docker for your database but plain Node for ordinary development. (Also see near-daily SO questions about live reloading not working in Docker.) You can start only the database, and since the code defaults the database location to a developer-friendly localhost, you can just develop as normal.
docker-compose up -d postgres_db
yarn dev

Nodejs application not connecting Redis in docker-compose

I have a Nodejs application which connects to a Redis instance. I am using docker-compose for the setup, and running docker-compose up. Here is my docker-compose.yml file:
# Specify docker-compose version.
version: '3'
# Define the services/containers to be run.
services:
express:
build: .
container_name: node-app
ports:
- '8000:8000'
depends_on:
- redis-cache
redis-cache:
image: redis
ports:
- 6379:6379
My Dockerfile:
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN npm ci
EXPOSE 8000
CMD [ “npm”, “start” ] // Also tried CMD [ “node”, “index.js” ]
I am getting the following error:
redis-cache_1 | 1:M 19 Jan 2021 04:23:49.411 * Ready to accept connections
node-app | sh: “start”: unknown operand
node-app exited with code 2
So, I went inside the container and manually ran npm start. The Nodejs started successfully but gave the following error while connecting Redis:
Error: Redis connection to redis-cache:6379 failed - getaddrinfo ENOTFOUND redis-cache
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26) {
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'redis-cache'
}
Also tried node index.js but still got the same error. This is how I am connecting to my Redis instance in my Nodejs application:
const client = redis.createClient({host: 'redis-cache', port: 6379});
I have tried various answers on StackOverflow as well as various other sites, but none works for me. Please help !

ECONNREFUSED error in docker-compose with NodeJS and postgresql in google cloud

I have created my react app with Node.js and postgresql and I deployed in google cloud. I created a docker image of postgres and nodejs and I uploaded images to docker hub. From gcloud I accessing Those images.
This is my docker-compose-production.yml file.
version: '2.0'
services:
postgres:
image : mycompany/myapp:pglatest
restart : always
volumes:
- ./backdata/databackups:/var/lib/postgresql/backdata
ports:
- "5433:5432"
backend:
image: mycompany/myapp:nodelatest7
command: npm run start
ports:
- "5001:5000"
depends_on:
- postgres
environment:
POSTGRES_URL: postgresql://postgres:root#postgres:5432/db_mydb
DEBUG: hms-backend:*
when I run command
sudo docker-compose -f docker-compose-production.yml up --build -d
2 images are created.
after that I have run tail command
sudo docker-compose -f docker-compose-production.yml logs -t backend
I'm getting error as
backend_1 | 2018-09-15T09:12:18.926001351Z REST API listening on port 5000
backend_1 | 2018-09-15T09:12:18.937246598Z error { Error: connect ECONNREFUSED 192.168.80.2:5432
backend_1 | 2018-09-15T09:12:18.937268668Z at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14)
backend_1 | 2018-09-15T09:12:18.937280934Z errno: 'ECONNREFUSED',
backend_1 | 2018-09-15T09:12:18.937283960Z code: 'ECONNREFUSED',
backend_1 | 2018-09-15T09:12:18.937286817Z syscall: 'connect',
backend_1 | 2018-09-15T09:12:18.937289488Z address: '192.168.80.2',
backend_1 | 2018-09-15T09:12:18.937292260Z port: 5432 }
How to solve this problem
For me your postgres url is wrong : postgresql://postgres:root#postgres:5432/db_mydb
It should be postgresql://postgres:root#postgres:5433/db_mydb since the postgres "exposed" port in 5433
Hum, by i think you should add "container_name" in the docker-compose
services:
postgres:
container_name: my_postgres
and use this name for the "adress" of your postgres
postgresql://my_postgres:root#postgres:5433/db_mydb

Create Docker image for NodeJS + PostgreSQL web application

I've been reading Docker's documentation, but I can't get around creating an image that will work.
I have a NodeJS application that uses PostgreSQL as database:
var connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/db';
var pg = require('pg');
var pgp = require('pg-promise')();
var db = pgp(connectionString);
db.func('some_storedProcedure').then(//...)
//...
I first created a Dockerfile according to Node's documentation for it:
FROM node:argon
# Create app directory
RUN mkdir -p /app
WORKDIR /app
# Install app dependencies
COPY package.json /app
RUN npm install
# Bundle app source
COPY . /app
EXPOSE 5000
CMD [ "npm", "start" ]
I then followed this post regarding connecting the database to it with docker-compose. the docker-compose.yml file looks like:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
links:
- db
environment:
DATABASE_URL: postgres://myuser:mypass#db:5432/db
db:
image: postgres
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypass
This is (some) of what is returned when I run docker-compose up with these files, after creating the image.
npm info ok
---> 87dbbae35721
Removing intermediate container c73f826a0b3d
Step 6 : COPY . /app
---> ec56bfc11d3c
Removing intermediate container 745ddf82d742
Step 7 : EXPOSE 5000
---> Running in b2be5aecd9d6
---> a7d126a7ea5e
Removing intermediate container b2be5aecd9d6
Step 8 : CMD npm start
---> Running in 0379d512c688
---> 266517f47311
Removing intermediate container 0379d512c688
Successfully built 266517f47311
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Starting imagename_db_1
Creating imagename_web_1
Attaching to imagename_db_1, imagename_web_1
web_1 | npm info it worked if it ends with ok
web_1 | npm info using npm#2.15.1
web_1 | npm info using node#v4.4.3
web_1 | npm info prestart SharedServer#5.8.0
web_1 | npm info start SharedServer#5.8.0
web_1 |
web_1 | > SharedServer#5.8.0 start /app
web_1 | > node index.js
web_1 |
web_1 | Wed, 27 Apr 2016 00:41:19 GMT body-parser deprecated bodyParser: use individual json/urlencoded middlewares at index.js:13:9
web_1 | Wed, 27 Apr 2016 00:41:19 GMT body-parser deprecated undefined extended: provide extended option at node_modules/body-parser/index.js:105:29
web_1 | Node app is running on port 5000
db_1 | LOG: database system was interrupted; last known up at 2016-04-25 00:17:59 UTC
db_1 | LOG: database system was not properly shut down; automatic recovery in progress
db_1 | LOG: invalid record length at 0/17076E8
db_1 | LOG: redo is not required
db_1 | LOG: MultiXact member wraparound protections are now enabled
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
When I access http://localhost:5000, I see the web application running, but whenever I fire up something that tries to access the database, I get a HTTP 500 error with the following body
code: "28P01"
file: "auth.c"
length: 98
line: "285"
name: "error"
routine: "auth_failed"
severity: "FATAL"
What am I doing wrong? I'm not sure I understand what I'm doing with Docker, and the only thing I have for documentation are simple recipes to build specific environments (or at least, that's what I've understood)
Thanks.
Check your pg_hba.conf in $PGDATA allows connections from node.js.
By default the pg_hba.conf is like so:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
This is fine for your standard psql connectivity via the OS owner as it allows local connections trusted for localhost IP address 127.0.0.1. However if you have an IP address set on the server, which I'm guessing you do then you need to allow an entry for that because in your node.js configuration you're referring to a host of "DB". So ping "DB" and add that IP address:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
host db myuser <ip-for-db-host> md5
Once you've changed that file you will need to perform a pg_ctl reload.

Resources