Reputation: 311
I have the following error message from a Go app in Docker:
panic: failed to connect to `host=localhost user=postgres-dev database=dev`: dial error (dial tcp [::1]:5432: connect: cannot assign requested address)
which appear in the environment of the next Dockerfile
and docker-compose.yml
file:
FROM golang:latest
WORKDIR /WD
COPY go.mod go.sum ./
RUN go mod download
COPY . .
the docker-compose.yml
file:
version: '3'
services:
db:
image: postgres:latest
environment:
POSTGRES_DB: dev
POSTGRES_USER: postgres-dev
POSTGRES_PASSWORD: [~secret~]
ports: 5432:5432
app:
build: .
command: ["./wait-for-it.sh", "db:5432", "--", "go", "run", "main.go"]
volumes:
- .:/WD
ports:
- "8000:8000"
depends_on:
- db
links:
- db
here the main.go
file:
package main
import (
"context"
"fmt"
"log"
"net/http"
api "github.com/[placeholder]/[placeholder]/api"
db "github.com/[placeholder]/[placeholder]/db"
pgx "github.com/jackc/pgx/v4"
)
func main() {
fmt.Println("Init")
r := api.InitRoutes()
conn, err := pgx.Connect(context.Background(), "postgresql://postgres-dev:[~secret~]@localhost:5432/dev")
if err != nil {
panic(err) // the error appears from this line.
}
dbInstance := &db.DbService{Conn: conn}
dbInstance.Conn.Ping(context.Background())
dbInstance.Migrate("/db/db.sql")
http.ListenAndServe(":8000", r)
}
in console logs I found the next lines, which I think related to the problem:
db_1 | 2019-12-07 08:08:59.350 UTC [1] LOG: starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1 | 2019-12-07 08:08:59.351 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
# read the next line:
db_1 | 2019-12-07 08:08:59.351 UTC [1] LOG: listening on IPv6 address "::", port 5432
the address of the database is :: with port 5432
and while the program try to connect to ::1 with port 5432
, could this be the cause of the problem?
Upvotes: 19
Views: 40657
Reputation: 1
The problem becomes obvious. It’s trying to bind on an IPv6 address, not IPv4. We can force the use of IPv4 on the command line with the -4 switch. For example, check the below command.
$ ssh -4 -L 8080:127.0.0.1:80 dev.local
NB : To permanently disable IPv6, you can edit your ~/.ssh/config and add:
$ vi ~/.ssh/config
Host *
AddressFamily inet
That will make sure SSH never tries anything with IPv6.
Upvotes: 0
Reputation: 18245
Within a container attatched to a bridge network (the default) localhost
(127.0.0.1) is the container itself. So your app
container is trying to access the database at port 5432 on itself (not on the host or on the db
container). The easiest fix is to change the connection string from:
postgresql://postgres-dev:[~secret~]@localhost:5432/dev
to
postgresql://postgres-dev:[~secret~]@db:5432/dev
Note: I think you have a typo in your docker-compose.yml
- ports: 5432:5432
is setting an environmental variable rather than mapping a port (note that this is not actually needed for app
to talk to db
if they are both on the same bridged network as is the case by default).
Note2: You should not need to use links in this case (this is a legacy feature).
Upvotes: 41