无法使用psycopg2连接到Postgres容器

5
我有以下设置:
  • 一个简单的 Flask 应用程序在容器中

  • 一个 Postgres 容器

使用以下 Dockerfiles:
FROM python:alpine3.7

COPY . /app
WORKDIR /app

RUN apk update
RUN apk add --virtual build-deps gcc python3-dev musl-dev
RUN apk add postgresql-dev
RUN pip install -r requirements.txt
RUN apk del build-deps

EXPOSE 5006

CMD ["python", "./app.py"]

对于数据库:

FROM postgres:11.1-alpine

COPY create_db.sql /docker-entrypoint-initdb.d/

EXPOSE 5432

这是我的Docker Compose YAML文件(将端口映射到主机以检查容器是否正常工作):
version: '3'
services:
    postgres:
        image: ccdb
        build: ccDb
        restart: always
        environment:
            POSTGRES_PASSWORD: password
        ports:
            - "5432:5432"

    top:
        image: ccpytop
        build: ccPyTop
        ports:
            - "5006:5006"

我可以成功地从我的主机连接到数据库,并且可以导航到Flask应用程序提供的应用程序页面。当我导航到某个页面时,应用程序会连接到数据库,因此postgres容器有足够的时间启动。
当我运行docker-compose up时,我得到以下信息:
postgres_1  | 2018-12-04 09:45:13.371 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres_1  | 2018-12-04 09:45:13.371 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres_1  | 2018-12-04 09:45:13.377 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1  | 2018-12-04 09:45:13.398 UTC [19] LOG:  database system was interrupted; last known up at 2018-12-04 09:42:23 UTC
postgres_1  | 2018-12-04 09:45:13.521 UTC [19] LOG:  database system was not properly shut down; automatic recovery in progress
postgres_1  | 2018-12-04 09:45:13.524 UTC [19] LOG:  redo starts at 0/1680BC8
postgres_1  | 2018-12-04 09:45:13.524 UTC [19] LOG:  invalid record length at 0/1680CA8: wanted 24, got 0
postgres_1  | 2018-12-04 09:45:13.524 UTC [19] LOG:  redo done at 0/1680C70
postgres_1  | 2018-12-04 09:45:13.536 UTC [1] LOG:  database system is ready to accept connections

但是当我在 Python 容器中执行以下操作时:
>>> import psycopg2
>>> conn = psycopg2.connect("host=/var/run/postgresql dbname=postgres user=postgres password=password")

我理解为:“我得到了这个:”
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

我尝试在没有主机的情况下运行,但是我收到了相同的消息,只不过是 /tmp/ 而不是 /var/run/。我还尝试链接容器,但我注意到这是一个遗留功能,而且它也没有起作用。
这是我第一次使用 docker-compose,我现在基本上被卡住了。有什么想法吗?

为什么host=/var/run/postgresql??据我所了解,Flask应用程序在不同的容器中... - Gioachino Bartolotta
因为我认为它必须与postgres容器的输出匹配,所以我@GioachinoBartolotta。这是我的新手错误 :) - Xzenon
1个回答

4

您正在运行两个独立的容器,它们互相不知道,因此不能相互通信。

要从一个容器通信到另一个容器,它们必须在同一个网络上。在Docker中,您可以创建自己的子网络:

docker network create <network-name>

然后,您可以通过添加命令将容器添加到网络中

--network=<network-name> --network-alias=<network-alias>

对于容器的 docker run 命令,可以添加网络别名。

这样,同一网络中的任何其他容器都可以通过它的 <network-alias> 访问 Docker 容器。对您来说,这意味着

conn = psycopg2.connect("host=/var/run/postgresql dbname=postgres user=postgres password=password")

更改为

conn = psycopg2.connect("host=<network-alias> dbname=postgres user=postgres password=password")

network-alias是您为postgres容器分配的别名。

编辑

如果要在docker-compose中执行此操作,请查看docker-compose网络设置手册。 显然,在启动时,docker-compose会设置自己的网络。如果您的docker-compose位于directory中,则docker-compose将创建一个名为directory_default的网络,可以通过docker-compose文件中给定的名称发现不同的容器。因此,如果您更改python命令为

conn = psycopg2.connect("host=postgres dbname=postgres user=postgres password=password")

应该可以正常工作。


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