Не удается подключиться к контейнеру Postgres с помощью psycopg2 - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть следующие настройки:

  • Одно простое приложение Flask в контейнере

  • Контейнер Postgres

Использование следующих файлов Docker:

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

Это мой doker-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, и я почти застрял на этом этапе.Есть идеи?

1 Ответ

0 голосов
/ 04 декабря 2018

Вы используете 2 отдельных контейнера, которые не знают друг друга и поэтому не могут общаться друг с другом.

Для того, чтобы общаться из одного контейнера в другой, они должны находиться в одной сети.,В Docker вы можете создать свою собственную подсеть:

docker network create <network-name>

Затем вы можете добавить контейнеры в сеть, добавив

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

к docker run командам контейнеров.

Затем к Docker-контейнерам может обращаться любой из других контейнеров в той же сети через <network-alias>.Для вас это означает, что

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 network для руководства о том, как сделать это в 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")

, она должна работать.

...