When I run docker-compose up
postgres service start successful. However my Golang API can not connect to my postgres service. I tried manually without docker and it works. Golang Connection string looks like this host=db port=5432 user=%s dbname=%s password=%s sslmode=disable
. But when I restart my container, it works.
docker-compose
FROM golang:1.22
WORKDIR /app
COPY . .
RUN go install
Dockerfile
version: "3.7"
services:
gobank:
build: .
container_name: gobank
env_file:
- .env
ports:
- 3000:3000
command: make run
extra_hosts:
- "host.docker.internal:host-gateway"
db:
image: postgres:16
container_name: postgres
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=gobank
ports:
- 5432:5432
extra_hosts:
- "host.docker.internal:host-gateway"
PostgresLog
postgres | 2024-07-12 22:51:24.133 UTC [1] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres | 2024-07-12 22:51:24.133 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres | 2024-07-12 22:51:24.133 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres | 2024-07-12 22:51:24.135 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres | 2024-07-12 22:51:24.138 UTC [64] LOG: database system was shut down at 2024-07-12 22:51:24 UTC
GolangLog
gobank | 2024/07/12 22:51:23 there was an error: dial tcp 172.18.0.2:5432: connect: connection refused
gobank | make: *** [Makefile:14: run] Error 1
postgres | performing post-bootstrap initialization ... ok
gobank exited with code 2
postgres | syncing data to disk ... ok
2
Answers
Your Go program tried to connect to the database before it was ready. To make Docker wait until Postgres is ready before starting your Go program, you need to add a healthcheck to the db container, like this:
Then, you need to make the Go program depend on the healthcheck like so:
You can add:
and as a measure add a health check inside golang in the form of a endless for loop which basically pings the DB.