Reputation: 291
My docker-compose file
version: "2"
services: db:
restart: always
image: postgres:latest
ports:
- "5435:5432"
environment:
POSTGRES_PASSWORD: password
POSTGRES_USER: user
POSTGRES_DB: db adminer:
web:
image: golang:1.7
working_dir: /go/src/app
command: go run bot.go
ports:
- "3000:3000"
volumes:
- ./bot:/go/src/app
links:
- db
environment:
PORT: 3000
CONNECTION_STRING_DEV: postgres://user:password@db/db
and my bot.go, where I try connect
db, err = sql.Open("postgres", "user=user password=password host=db dbname=db port=5432 sslmode=verify-full ")
When I bring up my containers, I see errors:
panic: dial tcp 5.61.14.99:5432: getsockopt: connection refused
I changed the port on 5432 and tried connect like this:
db, err = sql.Open("postgres", "postgres://user:password@db/db")
but I get the same errors
What's wrong with my docker-compose setup?
Upvotes: 3
Views: 9657
Reputation: 136
Your docker-compose looks a little messy but that's probably from copy and pasting. It's likely that postgres is not yet up and running when Go tries to connect. To test if that's the problem, first:
docker-compose up -d db
Then wait until postgres is ready by checking:
docker-compose logs -f db
and look out for a log line like:
db_1 | LOG: database system is ready to accept connections
When that line appears, quit the log command (Ctrl+C) and run your bot:
docker-compose up web
If it is now working, that was indeed your problem.
Solution: Wait until postgres is ready. Easy ways to achieve this are:
The disadvantage of these are that you don't know when postgres is ready, so you could wait too long or not long enough. A better solution is to run your bot only after a successful connection to postgres has been made.
Example from https://docs.docker.com/compose/startup-order/:
#!/bin/bash
# wait-for-postgres.sh
set -e
host="$1"
shift
cmd="$@"
until psql -h "$host" -U "postgres" -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
Add this script as wait-for-postgres.sh
and in you docker-compose.yml change the command for web like so:
command: ["./wait-for-postgres.sh", "db", "go", "run", "bot.go"]
Upvotes: 6
Reputation: 291
I found answer, i ran container with postgres already in other app, i didn't think about this, because docker compose didn't show errors when build db container. I used docker ps
then docker stop xxxxx
and stop db container from other app, then build and up my app, and problem solved.
Upvotes: 1