1

I run my Golang API and PostgreSQL with docker-compose.

My log with error connection refused:

db_1   | 
db_1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1   | 
api_1  | Unable to connect to database: dial tcp 0.0.0.0:5432: connect: connection refusedartpaper_api_1 exited with code 1
db_1   | 2021-12-26 15:18:35.152 UTC [1] LOG:  starting PostgreSQL 14.1 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit
db_1   | 2021-12-26 15:18:35.152 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2021-12-26 15:18:35.152 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2021-12-26 15:18:35.216 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2021-12-26 15:18:35.329 UTC [22] LOG:  database system was shut down at 2021-12-26 15:05:11 UTC
db_1   | 2021-12-26 15:18:35.515 UTC [1] LOG:  database system is ready to accept connections

My config:

config := pgx.ConnConfig{
        Host:     "0.0.0.0",
        Port:     5432,
        Database: "artpaper",
        User:     "admin",
        Password: "admin1",
    }

I think mistake in docker-compose.yml or Dockerfile for API, because on correct ports docker ps:

0.0.0.0:5432->5432/tcp    artpaper_db_1

Dockerfile for API:

FROM golang:1.17.5-alpine3.15

WORKDIR /artpaper

COPY ./ ./

RUN go mod download // download dependencies

RUN go build ./cmd/main/main.go // compile code to one binary file

EXPOSE 8080

CMD [ "./main" ] // run binary file

docker-compose.yml:

version: "3.3"

services:
  db:
    image: postgres:14.1-alpine3.15
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=artpaper
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin1
    ports:
      - 5432:5432
  api:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - db

Password and user in API config like in docker-compose.yml

Hostname from container with api is 0.0.0.0:5432

gelerum
  • 156
  • 2
  • 11
  • What hostname are you using to connect? – Mark Rotteveel Dec 26 '21 at 13:45
  • From container with api `0.0.0.0:5432` – gelerum Dec 26 '21 at 14:00
  • In your application logs you can see your application is trying to connect before the database is fully ready. [Connection Refused: Accessing Postgres container from app container with docker-compose](https://stackoverflow.com/questions/56191203/connection-refused-accessing-postgres-container-from-app-container-with-docker) has a long discussion of this specific Go/PostgreSQL setup; [Docker Compose wait for container X before starting Y](https://stackoverflow.com/questions/31746182/docker-compose-wait-for-container-x-before-starting-y) discusses the more general case. – David Maze Dec 26 '21 at 21:41

3 Answers3

6

In your Golang application try using: db:5432, not 0.0.0.0:5432.

version: '3.8'
services:
  db:
    image: postgres:14.1-alpine3.15
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=artpaper
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin1
    ports:
      - 5432:5432

  api:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - db

  debug:
    image: postgres:14.1-alpine3.15
    command: sleep 1d

Try connect to the database within:

docker-compose up -d

docker-compose exec debug ash -c 'psql -h db -U admin --dbname artpaper'

gohm'c
  • 13,492
  • 1
  • 9
  • 16
  • Now this `Unable to connect to database: dial tcp 172.18.0.2:5432: connect: connection refused` – gelerum Dec 26 '21 at 15:04
  • Can you update the log `docker-compose logs db` in your question and show the connection string that your app uses? – gohm'c Dec 26 '21 at 15:16
  • @gohmc Done. I add new compose output and connection config from my code – gelerum Dec 26 '21 at 15:22
  • Do you have psql on your host where you can try connect to the database like: `psql -h localhost -U admin --dbname artpaper` – gohm'c Dec 26 '21 at 15:28
  • `psql -h localhost -U admin --dbname artpaper Password for user admin: psql (11.14 (Debian 11.14-0+deb10u1), server 14.1) WARNING: psql major version 11, server major version 14. Some psql features might not work. Type "help" for help. artpaper=# ` It works – gelerum Dec 26 '21 at 15:43
  • So something wrong with your app? Try the updated answer and see if you can connect to the database within. – gohm'c Dec 26 '21 at 15:58
1

I had the similar issue and find the reason, and would like to share it for future readers.

  • docker-compose file:
version: "3.8"

services:
  web:
    container_name: web
    image: web
    ports:
      - "80:80"
    environment:
      - REACT_APP_ACCOUNT_SERVICE=http://account:5010
      - REACT_APP_CONTENT_SERVICE=http://content:5000
      - REACT_APP_GROUP_SERVICE=http://group:5009
    networks:
      - app-network
    restart: always

  account:
    container_name: account
    image: account
    ports:
      - "5010:5000"
    environment:
      - DB_HOST=account-db
      - DB_PORT=5432
      - DB_USERNAME=user
      - DB_PASSWORD=password
      - DB_NAME=account
      - DB_TYPE=postgres
      - ACCOUNT_SERVICE=http://account:5010
      - GROUP_SERVICE=http://group:5009
      - CONTENT_SERVICE=http://content:5000
    depends_on:
      - account-db
    networks:
      - app-network
    restart: always

  account-db:
    container_name: account-db
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=account
    ports:
      - "5432:5432"
    volumes:
      - account-db-data:/var/lib/postgresql/data/
    networks:
      - app-network
    restart: always

  content:
    container_name: content
    image: content
    ports:
      - "5000:5000"
    environment:
      - DB_HOST=content-db
      - DB_PORT=5433
      - DB_USERNAME=user
      - DB_PASSWORD=password
      - DB_NAME=content
      - DB_TYPE=postgres
    depends_on:
      - content-db
    networks:
      - app-network
    restart: always

  content-db:
    container_name: content-db
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=content
    ports:
      - "5433:5432"
    volumes:
      - content-db-data:/var/lib/postgresql/data/
    networks:
      - app-network
    restart: always

  group:
    container_name: group
    image: group
    ports:
      - "5009:5000"
    environment:
      - DB_HOST=group-db
      - DB_PORT=5434
      - DB_USERNAME=user
      - DB_PASSWORD=password
      - DB_NAME=group
      - DB_TYPE=postgres
    depends_on:
      - group-db
    networks:
      - app-network
    restart: always

  group-db:
    container_name: group-db
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=group
    ports:
      - "5434:5432"
    volumes:
      - group-db-data:/var/lib/postgresql/data/
    networks:
      - app-network
    restart: always

networks:
  app-network:

volumes:
  account-db-data:
  content-db-data:
  group-db-data:
  • issue after running docker compose up
content     | Error: connect ECONNREFUSED 172.29.0.2:5433
content     |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16) {
content     |   errno: -111,
content     |   code: 'ECONNREFUSED',
content     |   syscall: 'connect',
content     |   address: '172.29.0.2',
content     |   port: 5433
content     | }
  • root cause:

The internal communication between containers happens within the Docker network and not through the host machine's ports. When the content service tries to connect to the content-db container, it does so through the Docker network, where the database is still listening on its default port 5432.

  • solution:
    • change all service's env DB_PORT=5432
version: "3.8"

services:
  web:
    container_name: web
    image: web
    ports:
      - "80:80"
    environment:
      - REACT_APP_ACCOUNT_SERVICE=http://account:5010
      - REACT_APP_CONTENT_SERVICE=http://content:5000
      - REACT_APP_GROUP_SERVICE=http://group:5009
    networks:
      - app-network
    restart: always

  account:
    container_name: account
    image: account
    ports:
      - "5010:5000"
    environment:
      - DB_HOST=account-db
      - DB_PORT=5432
      - DB_USERNAME=user
      - DB_PASSWORD=password
      - DB_NAME=account
      - DB_TYPE=postgres
      - ACCOUNT_SERVICE=http://account:5010
      - GROUP_SERVICE=http://group:5009
      - CONTENT_SERVICE=http://content:5000
    depends_on:
      - account-db
    networks:
      - app-network
    restart: always

  account-db:
    container_name: account-db
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=account
    ports:
      - "5432:5432"
    volumes:
      - account-db-data:/var/lib/postgresql/data/
    networks:
      - app-network
    restart: always

  content:
    container_name: content
    image: content
    ports:
      - "5000:5000"
    environment:
      - DB_HOST=content-db
      - DB_PORT=5432
      - DB_USERNAME=user
      - DB_PASSWORD=password
      - DB_NAME=content
      - DB_TYPE=postgres
    depends_on:
      - content-db
    networks:
      - app-network
    restart: always

  content-db:
    container_name: content-db
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=content
    ports:
      - "5433:5432"
    volumes:
      - content-db-data:/var/lib/postgresql/data/
    networks:
      - app-network
    restart: always

  group:
    container_name: group
    image: group
    ports:
      - "5009:5000"
    environment:
      - DB_HOST=group-db
      - DB_PORT=5432
      - DB_USERNAME=user
      - DB_PASSWORD=password
      - DB_NAME=group
      - DB_TYPE=postgres
    depends_on:
      - group-db
    networks:
      - app-network
    restart: always

  group-db:
    container_name: group-db
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=group
    ports:
      - "5434:5432"
    volumes:
      - group-db-data:/var/lib/postgresql/data/
    networks:
      - app-network
    restart: always

networks:
  app-network:

volumes:
  account-db-data:
  content-db-data:
  group-db-data:
  • how or when to use the exposed port such as 5433, 5432?
    • if we want to connect the db from outside the docker container network.
0

First: In config database host should be a db like in docker-compose.yml

Second: Postgres as a program does not have time to turn on inside the container. I added in api code delay before connection to database.

gelerum
  • 156
  • 2
  • 11