如何将Docker Web应用容器连接到Docker PostgreSQL容器?

4
我正在练习制作一个与PostgreSQL数据库交互的Golang Web应用程序,它们各自在自己的容器中运行。
我使用docker-compose up命令来运行这些容器。
但是我好像无法正确设置postgres容器。
为了简洁起见,Dockerfile和其他设置文件的链接在此处(如果您想要的话,请让我知道)。
version: '2'
services:
  web_app:
    build: dockerfiles/web_app
    ports:
      - "9000:9000"
    volumes:
      - .:/go/src/gitlab.com/repo/web_app
    # links might be replaced by depends_on.
    # links:
    #   - db
    depends_on:
      - db
    # tty and stdin_open cause docker-compose to disconnect from docker-machine after 60sec.
    # A fix is on the way.
    # tty: true
    # stdin_open: true
  db:
    build: dockerfiles/db
    volumes:
      - data:/var/lib/postgresql/data
volumes:
  data: {}

docker-compose up 工作正常。但是当应用程序尝试使用以下命令打开数据库连接时:

var pgConf string = "user=web_app dbname=web_app sslmode=verify-full password=password"

db, err := sql.Open("postgres", pgConf)

我从Docker Compose得到以下错误:

Error creating new user:  dial tcp [::1]:5432: getsockopt: connection refused

我该如何使两个容器相互通信?

提前感谢您的帮助。


原因是depends_on不能替代links。前者仅确定启动顺序,而后者还可以通过名称在容器之间进行访问。 - Xiongbing Jin
1个回答

8
使用docker-compose v2时,不需要在服务之间创建链接。Docker 1.9和1.10允许您通过名称连接到同一(自定义)网络中的其他容器。您应该能够使用服务或容器的名称作为主机名进行连接。鉴于容器的名称是由docker-compose生成的,因此这并不方便使用。出于这个原因,docker-compose还为每个容器添加了一个与服务名称相同的别名。以下是一个非常简单的示例。我使用了一个Nginx容器方便起见,但对于您的情况也应该适用。
version: '2'
services:
  web_app:
    image: nginx
  db:
    image: nginx

首先启动项目(假设;

$ docker-compose --project-name=test up -d
Creating network "test_default" with the default driver
Creating test_db_1
Creating test_web_app_1

然后在test_web_app_1容器内部ping一下"db"服务:

$ docker exec -it test_web_app_1 ping -c 2 db
PING db (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.108 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.243 ms
--- db ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.108/0.175/0.243/0.068 ms

如果您检查test_db_1容器,您会发现docker-compose自动为test_db_1容器添加了一个"db"别名;

$ docker inspect test_db_1

给出:(仅包括NetworkSettings.Networks部分)
"Networks": {
    "test_default": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": [
            "db",
            "002b1875e61f"
        ],
        "NetworkID": "0f9e2cddeca79e5a46c08294ed61dee273828607f99014f6410bda887626be70",
        "EndpointID": "a941ab95586a8fdafc5075f9c5c44d745f974e5790ef6048b9e90115a22fb31f",
        "Gateway": "172.18.0.1",
        "IPAddress": "172.18.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:12:00:02"
    }
}

非常感谢您提供的宝贵见解。根据您的回答,我将user.go第20行的连接代码更改为:var pgConf string = "user=web_app dbname=web_app sslmode=verify-full password=password host=172.18.0.2",并成功连接到了数据库。所以最终,docker-compose.yaml是正确的。我所需要的只是您提供的关于连接容器的内部IP的额外信息。 - sargas
1
你应该可以将其更改为host=db,这是Docker中嵌入式DNS的想法,也是一种更好的方法,因为IP地址可能会发生变化。 - thaJeztah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接