英文:
Can not resolve postgres hostname from other service on docker-compose
问题
我有一个docker-compose文件,其中运行了2个容器。
其中一个服务是postgres,另一个是我的后端服务。
当我尝试解析postgres或尝试从后端服务的cli连接时,都是成功的。
但是当我尝试使用主机名初始化数据库时,我遇到了以下错误:
> 2022/09/01 08:49:53 /src/domain/domain.go:29 [error] 初始化数据库失败,出现错误:无法连接到host=postgres user=devuser database=backenddev
:主机名解析错误(查找postgres:设备或资源忙)恐慌:无法连接到host=postgres user=devuser database=backenddev
:主机名解析错误(查找postgres:设备或资源忙)
>
> goroutine 1 [running]:
> github.com/anilkusc/backend/api.(*Api).Init(0xc00000e150)
> /src/api/api.go:34 +0x76b github.com/anilkusc/backend/api.(*Api).Start(0xc00000e150)
> /src/api/api.go:87 +0x25 main.main()
> /src/main.go:48 +0x15f
当我尝试从另一个容器的cli连接到postgresql时,我得到以下结果:
root@8a0824fca084:/# nc -vz postgres 5432
Connection to postgres (172.25.0.2) 5432 port [tcp/postgresql] succeeded!
root@8a0824fca084:/# curl postgres:5432
curl: (52) Empty reply from server
这是相关的代码块:
d.Database, err = gorm.Open(postgres.Open(os.Getenv("DB_CONN")), &gorm.Config{})
if err != nil {
return err
}
这是compose文件:
version: '3.6'
services:
postgres:
image: postgres:14.5
restart: always
environment:
POSTGRES_PASSWORD: <password>
POSTGRES_DB: backenddev
POSTGRES_USER: devuser
ports:
- 5432:5432
backend:
image: my-service:v0.0.2
restart: always
environment:
ENV: dev
STORE_KEY: 1234
DB_CONN: host=postgres user=devuser password=<password> dbname=backenddev port=5432
ports:
- 8080:8080
depends_on:
- postgres
这是后端服务的Dockerfile:
FROM golang:1.18.4 as build
WORKDIR /src
COPY go.sum go.mod ./
RUN go mod download
COPY . .
RUN go build -a -ldflags "-linkmode external -extldflags '-static' -s -w" -o /bin/app.
FROM alpine
WORKDIR /app
COPY --from=build /bin/app .
CMD ["./app"]
如果我尝试使用后端服务的外部IP和端口连接到数据库,也是成功的,但是对于内部连接到postgresql没有成功。
为什么我的应用程序无法解析postgres主机,即使它的主机容器可以解析?
英文:
I have a docker-compose file which run 2 containers.
One of the service is postgres and the other one is my backend service.
When I try to resolve postgres or try to connect it from cli of the backend service , it is successfull.
But when I try to initialize database with hostname , I got following error:
> 2022/09/01 08:49:53 /src/domain/domain.go:29 [error] failed to
> initialize database, got error failed to connect to host=postgres
: hostname resolving error
> user=devuser database=backenddev
> (lookup postgres: device or resource busy) panic: failed to connect to
> host=postgres user=devuser database=backenddev
: hostname
> resolving error (lookup postgres: device or resource busy)
>
> goroutine 1 [running]:
> github.com/anilkusc/backend/api.(*Api).Init(0xc00000e150)
> /src/api/api.go:34 +0x76b github.com/anilkusc/backend/api.(*Api).Start(0xc00000e150)
> /src/api/api.go:87 +0x25 main.main()
> /src/main.go:48 +0x15f
when I try to connect postgresql from another container cli , I got the following:
root@8a0824fca084:/# nc -vz postgres 5432
Connection to postgres (172.25.0.2) 5432 port [tcp/postgresql] succeeded!
root@8a0824fca084:/# curl postgres:5432
curl: (52) Empty reply from server
Here is related code block:
d.Database, err = gorm.Open(postgres.Open(os.Getenv("DB_CONN")), &gorm.Config{})
if err != nil {
return err
}
Here is compose file :
version: '3.6'
services:
postgres:
image: postgres:14.5
restart: always
environment:
POSTGRES_PASSWORD: <>
POSTGRES_DB: backenddev
POSTGRES_USER: devuser
ports:
- 5432:5432
backend:
image: my-service:v0.0.2
restart: always
environment:
ENV: dev
STORE_KEY: 1234
DB_CONN: host=postgres user=devuser password=<> dbname=backenddev port=5432
ports:
- 8080:8080
depends_on:
- postgres
Here is dockerfile of backend service :
FROM golang:1.18.4 as build
WORKDIR /src
COPY go.sum go.mod ./
RUN go mod download
COPY . .
RUN go build -a -ldflags "-linkmode external -extldflags '-static' -s -w" -o /bin/app.
FROM alpine
WORKDIR /app
COPY --from=build /bin/app .
CMD ["./app"]
If I try to connect to database with external ip and port on backend service it is also successfull but no luck for internal connection to postgresql.
Why my application can not resolve postgres host even though its host container can ?
答案1
得分: 2
感谢@Brits。
这可能与alpine容器和golang 1.18.4容器的DNS库不兼容有关。
我将容器镜像从alpine更改为debian,问题已解决。
FROM golang:1.18.4 as build
WORKDIR /src
COPY go.sum go.mod ./
RUN go mod download
COPY . .
RUN go build -a -ldflags "-linkmode external -extldflags '-static' -s -w" -o /bin/app.
FROM debian:buster-slim #只是在这里进行了更改!
WORKDIR /app
COPY --from=build /bin/app .
CMD ["./app"]
英文:
thanks to @Brits.
It is probably related with incompatibility between alpine container and golang 1.18.4 container dns libraries.
I changed my container image to debian from alpine and the issue has been resolved.
FROM golang:1.18.4 as build
WORKDIR /src
COPY go.sum go.mod ./
RUN go mod download
COPY . .
RUN go build -a -ldflags "-linkmode external -extldflags '-static' -s -w" -o /bin/app.
FROM debian:buster-slim #just changed here!
WORKDIR /app
COPY --from=build /bin/app .
CMD ["./app"]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论