Проблема, когда Python в сценарии Docker подключается к серверу SQL в стеке
У меня есть стек в рой, который хорошо работает сам по себе (по крайней мере, я думаю, что это делает...). Он имеет postgresql, работающий на порту 5432, и веб-сервер на порту 80. К веб-серверу можно получить доступ извне.
Для модульных тестов я запускаю только сторону базы данных в режиме стека:
version: "3"
services:
sql:
image: sql
networks:
- service_network
ports:
- 5432:5432
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- ./local_storage_sql:/var/lib/postgresql/data
environment:
# provide your credentials here
- POSTGRES_USER=xxxx
- POSTGRES_PASSWORD=xxxx
networks:
service_network:
Затем модульные тесты начинаются с подключения к БД в другом простом контейнере Python:
FROM python:latest
LABEL version="0.1.0"
LABEL org.sgnn7.name="unittest"
# Make sure we are fully up to date
RUN apt-get update -q && \
apt-get dist-upgrade -y && \
apt-get clean && \
apt-get autoclean
RUN python -m pip install psycopg2-binary
RUN mkdir /testing
COPY ./*.py /testing/
Сбой тестового скрипта при подключении:
conn = connect(dbname=database, user=user, host=host, password=password)
с:
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: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
Но он не работает, только когда я запускаю его внутри контейнера. Снаружи это работает как шарм. Я также попытался настроить внешнюю сеть и использовать ее (тот же самый док-узел):
docker run --rm --net service_network -t UnitTest-image py.test /testing
Очевидно, я бы ожидал, что будет сложнее получить доступ к базе данных извне сети, чем изнутри, поэтому, очевидно, я что-то здесь упустил, но я не знаю, что...
1 ответ
При развертывании стека с помощью файла Compose полное имя сети создается путем объединения имени стека с базовым сетевым именем. Итак, скажем, вы развернули свой стек с именем foo
вот так.
docker stack deploy -c compose-file.yml foo
Тогда полное имя сети будет foo_service_network
,
Когда вы запускаете контейнер Python, вам необходимо подключить его к foo_service_network
не service_network
,
docker container run --rm --net foo_service_network -t UnitTest-image py.test /testing
Вы также можете настроить имя сети, указав свойство name в своем файле Compose (версия 3.5 и выше).
networks:
service_network:
name: service_network
В этом случае вы должны подключить свой контейнер к сети с этим пользовательским именем.
docker container run --rm --net service_network -t UnitTest-image py.test /testing
Редактировать 1/28: добавлен пример создания файла.
version: "3.7"
services:
sql:
image: sql
networks:
- service_network
ports:
- 5432:5432
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- ./local_storage_sql:/var/lib/postgresql/data
environment:
# provide your credentials here
- POSTGRES_USER=xxxx
- POSTGRES_PASSWORD=xxxx
networks:
service_network:
name: service_network
attachable: true