无法从Docker Compose中的其他服务解析Postgres主机名

huangapple go评论94阅读模式
英文:

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
&gt; user=devuser database=backenddev
: hostname resolving error
> (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(&quot;DB_CONN&quot;)), &amp;gorm.Config{})
		if err != nil {
			return err
		}

Here is compose file :

version: &#39;3.6&#39;
services:
  postgres:
    image: postgres:14.5
    restart: always
    environment:
      POSTGRES_PASSWORD: &lt;&gt;
      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=&lt;&gt; 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 &quot;-linkmode external -extldflags &#39;-static&#39; -s -w&quot; -o /bin/app.

FROM alpine
WORKDIR /app
COPY --from=build /bin/app .
CMD [&quot;./app&quot;]

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 &quot;-linkmode external -extldflags &#39;-static&#39; -s -w&quot; -o /bin/app.

FROM debian:buster-slim #just changed here!
WORKDIR /app
COPY --from=build /bin/app .
CMD [&quot;./app&quot;]

huangapple
  • 本文由 发表于 2022年9月1日 17:09:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/73566843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定