В одной папке у меня 3 файла: base.py, Dockerfile и docker-compose.yml.
base.py:
import psycopg2
conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")
Dockerfile:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary
COPY base.py base.py
RUN python base.py
docker-compose.yml:
version: '3'
services:
db:
image: 'postgres:latest'
expose:
- "5432"
environment:
POSTGRES_PASSWORD: pw1234
POSTGRES_DB: base123
aprrka:
build: .
depends_on:
- db
После запуска docker-compose up я получил следующую ошибку:
Traceback (most recent call last):
File "base.py", line 5, in <module>
conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")
File "/usr/local/lib/python2.7/dist-packages/psycopg2/__init__.py", line 130, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known
ERROR: Service 'aprrka' failed to build: The command '/bin/sh -c python base.py' returned a non-zero code: 1
Я не знаю, почему у меня такая ошибка. Я открыл порт 5432. По умолчанию Compose настраивает единую сеть для приложения. Каждая служба подключается к сети по умолчанию, я думаю, что мое приложение с postgres должно работать вместе. Я написал неверный docker-compose.yml?






Проблема в том, что вы не должны запускать python base.py как часть директивы RUN.
Директива RUN выполняется только при построении образа. Контейнер postgres на данный момент не запущен, и сеть не создана. Вместо этого вы хотите использовать директиву CMD.
Измените Dockerfile на это:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary
COPY base.py base.py
CMD ["python", "base.py"]
Вышеупомянутое должно привести к разрешению имени хоста db. Однако, если в вашем коде Python нет логики повторного подключения для подключения к базе данных, контейнер, скорее всего, все равно выйдет из строя. Это связано с тем, что контейнер postgres будет работать, но база данных не будет готова принимать соединения.
Это можно временно исправить, добавив restart: always к вашему docker-compose.yml.
version: '3'
services:
db:
image: 'postgres:latest'
expose:
- "5432"
environment:
POSTGRES_PASSWORD: pw1234
POSTGRES_DB: base123
aprrka:
restart: always
build: .
depends_on:
- db
Надеюсь, это поможет вам начать работу.
Спасибо! Как это ни печально, но я до сих пор не знаю, как исправить следующую ошибку. aprrka_1 | Отслеживание (последний вызов последним): файл «base.py», строка 5, в <module> conn = psycopg2.connect («dbname = 'base123' user = 'postgres' host = 'db' password = 'pw1234'» ) Файл "/usr/local/lib/python2.7/dist-packages/psycopg2/__init__.py", строка 130, в connect conn = _connect (dsn, connection_factory = connection_factory, ** kwasync) psycopg2.OperationalError: может не подключается к серверу: в соединении отказано. Сервер работает на хосте «db» (172.20.0.2) и принимает соединения TCP / IP на порту 5432?
Эту ошибку пыталась исправить вторая часть моего ответа. Вам нужно либо добавить логику переподключения в свой код, либо добавить restart: always в свой файл compose. Вы пробовали это?
Да. Это работает, но первые попытки подключения к базе данных не увенчались успехом. Нужно ли мне вводить в моем файле base.py некоторое «время ожидания», чтобы правильно установить соединение без ошибок? Я полагаю, что это не будет «лучше» для всего моего образа Docker, но будет лучше посмотреть, как он работает. Мое решение правильное?
Да, это отдельный вопрос, но вы хотите реализовать в своем коде какой-то механизм ожидания.
если вы добавите это в свой контейнер db в свой docker-compose.yml, это должно решить проблему
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
Это также сделает вашу базу данных небезопасной.
Добавьте базу данных и веб-сервис на та же сеть в файл docker compose. Также служба базы данных ссылка на сайт и запуск веб-службы после запуска службы базы данных.
После правильного добавления конфигурации сеть, ссылка и зависит_он в файл docker compose проблема будет исправлена.
Пример конфигурации:
services:
db:
container_name: db
networks:
- djangonetwork
web:
depends_on:
- db
links:
- db:db
networks:
- djangonetwork
networks:
djangonetwork:
driver: bridge
В моем файле создания докеров я использовал имя сети как «djangonetwork», вы можете использовать любое другое имя.
Приведенная выше конфигурация помогла мне решить проблему «Не удалось перевести имя хоста db».
Ну стреляйте. Это просто прошло для меня. Спасибо.
Другой возможный сценарий,
Проверьте, использовались ли порты другим докер-контейнером. Используйте команду:
$ docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a
Затем измените свои порты / выставьте в файле docker-compose
Если вы используете docker-compose, сначала добавьте эту строку в свой .yml:
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
После этого вы запускаете только докер db:
docker-compose up db
Обычно он должен начинаться с такого сообщения:
Recreating db... done
Attaching to db
db_1 | ********************************************************************************
db_1 | WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow
db_1 | anyone with access to the Postgres port to access your database without
db_1 | a password, even if POSTGRES_PASSWORD is set. See PostgreSQL
db_1 | documentation about "trust":
db_1 | https://www.postgresql.org/docs/current/auth-trust.html
db_1 | In Docker's default configuration, this is effectively any other
db_1 | container on the same system.
db_1 |
db_1 | It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace
db_1 | it with "-e POSTGRES_PASSWORD=password" instead to set a password in
db_1 | "docker run".
db_1 | ********************************************************************************
Ответ Джека Гора отвечает на ваш вопрос. Один из подходов к диагностике мог заключаться в использовании известного исправного второго контейнера для доступа к
db. См. Документацию к образу на docs.docker.com и использование образаadminer(docs.docker.com/samples/library/postgres/…). Во-вторых, Dockerfile выиграет от уменьшения количества создаваемых слоев за счет уменьшения количества командRUN. НапримерRUN apt-get update && apt-get -y install python-pip(финальныйapt-get updateвам не нужен).