简体   繁体   中英

How do you connect to the postgres from a node server while both is started inside a docker environment

I'm currently having some some problems with docker and connecting a node project with postgres when running inside it. I use docker toolbox by the way since I don't have windows pro.

my docker-compose file looks like this

version: '3'
 services:
  db:
    image: postgres:latest
    ports:
     - "5432:5432"
  environment:
    POSTGRES_PASSWORD: 123456
    POSTGRES_USER: postgres
    POSTGRES_DB: dockerdb
  network_mode: bridge
  container_name: postgres
  volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql

 web:
  build: .
  ports:
   - "5000:5000"
   - "3000:3000"
  depends_on:
   - db
  environment:
   DB_HOST: db

and my express server is just this, it's alittle bit of a mess at this time.

 const { Pool } = require('pg') var express = require('express'); var app = express; const pool = new Pool({ user: 'postgres', host: process.env.DB_HOST || 'localhost', database: 'dockerdb', password: '123456', port: 5432 }) // the pool with emit an error on behalf of any idle clients // it contains if a backend error or network partition happens pool.on('error', (err, client) => { console.error('Unexpected error on idle client', err) process.exit(-1) }) // callback - checkout a client pool.connect((err, client, done) => { if (err) throw err client.query('SELECT * FROM users WHERE id = $1', [1], (err, res) => { done() if (err) { console.log(err.stack) } else { console.log(res.rows[0]) } }) }) 

When I run it in docker, the containers run, I can access postgress db through the terminal and interact with with like creating and inserting things like that, but my node program doesn't seem to connect with it since I don't get any of the console log, I don't know if that is because of a connection problem or just because of some noobie mistakes, can some please help me. By the way I have created a table called users in my init.sql file and given it data, data I been able to access from the docker terminal using the psql command.

here is a picture of what's happening inside docker. enter image description here

That happens because the db takes some time to start and with your docker compose your server and db start at the same time. So you need some delay on the server to let the DB starts. I have an example in github that you can download and test https://github.com/PedroS11/node-postgres-redis-docker . Check my docker-compose file where you can see I have a script wait-for-it. This script has a sleep so that the server only starts 15s after the database.

To clean up your Express API, I would refactor like so:

// Express App Setup
const express = require(‘.express’);
const bodyParser = require(‘body-parser’);
const cors = require(‘cors’);

const app = express();
app.use(cors());
app.use(bodyParser.json());

// Postgres Client Setup
const { Pool } = require(‘pg’);
const pgClient = new Pool({
   user: keys.pgUser,
   host: keys.pgHost,
   database: keys.pgDatabase,
   password: keys.pgPassword,
   port: keys.pgPort
});
pgClient.on(‘error’, () => console.log(‘Lost PG Connection’));

pgClient.query(‘CREATE TABLE IF NOT EXISTS values (number INT)’)

And this is assuming you have yet to create a successful connection which means you have not created a table yet, which you need to do in order to connect.

So the name of the table here is going to be values and store a single column of information that will be referred to as number and thats the index of the submitted value from a frontend application I had wired up to my Express API, so you will have to tweak that table query to the specifications of your project, but you will use CREATE TABLE IF NOT EXISTS .

Then I add on a catch statement so that if anything goes wrong with creating that table then you will console log an error like so:

// Express App Setup
const express = require(‘.express’);
const bodyParser = require(‘body-parser’);
const cors = require(‘cors’);

const app = express();
app.use(cors());
app.use(bodyParser.json());

// Postgres Client Setup
const { Pool } = require(‘pg’);
const pgClient = new Pool({
   user: keys.pgUser,
   host: keys.pgHost,
   database: keys.pgDatabase,
   password: keys.pgPassword,
   port: keys.pgPort
});
pgClient.on(‘error’, () => console.log(‘Lost PG Connection’));

pgClient.query(‘CREATE TABLE IF NOT EXISTS values (number INT)’).catch(err => console.log(err));

For your docker-compose.yml I would just refactor it to this:

version: "3"
services:
  postgres:
    image: "postgres:latest"

and run docker-compose up and see how it goes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM