Docker изображение не запущено, ошибка базы данных: django .db.utils.OperationalError не удалось преобразовать имя хоста «postgres» в адрес: имя или служба неизвестны - PullRequest
0 голосов
/ 02 августа 2020

Итак, мне удалось создать свой образ Docker локально, используя docker-compose build, и я отправил образ в свой репозиторий Docker Hub.

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

root@my-droplet:~# docker run --rm -it -p 8000:8000/tcp mycommand/myapp:1.1 (да, 1.1)

Однако вскоре я столкнулся с этими двумя ошибками :

...
File "/usr/local/lib/python3.8/dist-packages/django/db/backends/postgresql/base.py",
line 185, in get_new_connection
    connection = Database.connect(**conn_params)   File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line
127, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync) 
psycopg2.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
... 
File "/usr/local/lib/python3.8/dist-packages/django/db/backends/base/base.py",
line 197, in connect
    self.connection = self.get_new_connection(conn_params)   File "/usr/local/lib/python3.8/dist-packages/django/utils/asyncio.py", line
26, in inner
    return func(*args, **kwargs)   File "/usr/local/lib/python3.8/dist-packages/django/db/backends/postgresql/base.py",
line 185, in get_new_connection
    connection = Database.connect(**conn_params)   File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line
127, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync) 
django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```

Это может быть связано с тем, что я разделил свое приложение (используя docker-compose,yml) на две службы и только нажал изображение приложения с момента моего предыдущего сообщения . Вот мой docker-compose.yml файл:

Вот мой docker -compose.yml файл:

version: '3'

services:
  db:
    image: postgres
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=(adminname)
      - POSTGRES_PASSWORD=(adminpassword)
      - CLOUDINARY_URL=(cloudinarykey)
  app:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db

Вот мой Dockerfile:

FROM (MY FRIENDS ACCOUNT)/django-npm:latest

RUN mkdir usr/src/mprova

WORKDIR /usr/src/mprova

COPY frontend ./frontend
COPY backend ./backend

WORKDIR /usr/src/mprova/frontend

RUN npm install
RUN npm run build

WORKDIR /usr/src/mprova/backend

ENV DJANGO_PRODUCTION=True
RUN pip3 install -r requirements.txt

EXPOSE 8000

CMD python3 manage.py collectstatic && \
    python3 manage.py makemigrations && \
    python3 manage.py migrate && \
    gunicorn mellon.wsgi --bind 0.0.0.0:8000

и вот фрагмент моего файла settings.py:

...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'admin',
        'PASSWORD': '[THE PASSWORD]',
        'HOST': 'db',
        'PORT': 5432,
    }
}
...

Как я могу исправить эту проблему? Я огляделась, но не вижу, что делаю не так.

Из того, что я видел в Интернете, я добавил в свой проект следующее, но оно тоже не работает:

Вот мой base.py (новый файл):

import psycopg2

conn = psycopg2.connect("dbname='postgres' user='admin' host='db' password='[THE PASSWORD]'")

Дополнения к Dockerfile:

FROM (MY FRIENDS ACCOUNT)/django-npm:latest

RUN pip3 install psycopg2-binary

COPY base.py base.py

RUN python3 base.py

...

Однако сборка не выполняется из-за этой ошибки:

Traceback (most recent call last):   File "base.py", line 3, in
<module>
    conn = psycopg2.connect("dbname='postgres' user='admin' host='db' password='[THE PASSWORD]'")   
File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line
127, 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 "db" ([SOME-IP-ADDRESS]) and accepting
        TCP/IP connections on port 5432?

ERROR: Service 'app' failed to build: The command '/bin/sh -c python3 base.py' returned a non-zero code: 1 
me@My-MacBook-Pro-5 mellon % 

Я не уверен, что попробовать дальше но я чувствую, что делаю простую ошибку. Почему сейчас отказывают в соединении?

Ответы [ 2 ]

2 голосов
/ 02 августа 2020

Когда вы запускаете файл docker-compose.yml, Compose автоматически создает для вас сеть Docker и присоединяет к ней контейнеры. При отсутствии каких-либо объявлений c networks: в файле, Compose назовет сеть default, а затем большинство вещей, создаваемых Compose, будут иметь префикс с именем текущего каталога. Эта настройка более подробно описана в Сеть в Compose .

docker run вообще не смотрит на настройки Compose, поэтому все, что вы делаете вручную с docker run, необходимо реплицировать настройки docker-compose.yml есть или будут генерироваться автоматически. Чтобы контейнер docker run подключился к сети Compose, вам нужно сделать что-то вроде:

docker network ls              # looking for somename_default
docker run \
  --rm -it -p 8000:8000/tcp \
  --net somename_default \     # <-- add this option
  mycommand/myapp:1.1

(сообщение об ошибке c could not translate host name "postgres" to address намекает на проблему настройки сети Docker: контейнер клиента базы данных не находится в той же сети, что и сервер базы данных, поэтому разрешение имени хоста не удается. В отличие от ошибки типа «в соединении отказано», которая предполагает, что один контейнер находит другой, но либо база данных еще не запущена или номер порта неверен.)

В вашем примере docker build код в Dockerfile никогда не может подключиться к базе данных. На механическом уровне нет возможности подключить его к сети Docker, как мы это сделали с docker run. На концептуальном уровне создание изображения дает артефакт многократного использования; если я docker push образ в реестр, а docker run - на другом хосте, на котором не будет настройки базы данных, или аналогично, если я удалю и воссоздаю контейнер базы данных локально.

1 голос
/ 02 августа 2020

Я пытаюсь запустить его с помощью следующей команды: root@my-droplet: ~ #

docker run --rm -it -p 8000: 8000 / tcp mycommand / myapp: 1.1 (да, 1.1)

Docker -compose позволяет создать композицию из нескольких контейнеров. Запуск контейнера django с docker run нарушает его цель.

Выполняется то, что вы хотите:

docker-compose build

docker-compose up

или одной командой:

docker-compose up --build                    

Почему сейчас отказывают в соединении?

Может потому, что это сделано не в нужный момент.

Я не специалист Django, а ваш второй try выглядит нормально, в то время как ваша служба django пропускает атрибут Dockerfile в объявлении compose (я предполагаю, что это ошибка ввода).

Для вашей первой попытки эта ошибка:

django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```

означает, что django использует «postgres» в качестве хоста базы данных. Но согласно вашему сочинению, база данных может быть достигнута с хоста с именем «db». Они не совпадают.

Что касается вашей второй попытки, которая определяет свойства базы данных, она выглядит нормально и также соответствует тому, что официально c утверждает :

В этом разделе вы настраиваете соединение с базой данных для Django.

В каталоге проекта отредактируйте файл composeexample / settings.py.

Замените DATABASES = .. . со следующим:

settings.py

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': 'postgres',
    'USER': 'postgres',
    'PASSWORD': 'postgres',
    'HOST': 'db',
    'PORT': 5432,
} } These settings are determined by the postgres Docker image specified in docker-compose.yml.

Для второй попытки эта ошибка:

 conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not connect to server: Connection refused
        Is the server running on host "db" ([SOME-IP-ADDRESS]) and accepting
        TCP/IP connections on port 5432?

может означать, что Postgres Прослушиватель БД еще не готов, когда Django пытается инициировать соединение с.

Эти атрибуты вашей композиции: depends_on: определяют порядок запуска контейнера, но не ждут, пока приложение за контейнером будет «готово».

Вот два способа адресовать такой сценарий:

  • либо добавить несколько секунд сна перед запуском django службы
  • или установите конфигурацию django compose для перезапуска в случае сбоя.
* 106 0 * Для первого способа настройте службу django с помощью CMD, например (не пробовал):
   app:
     build: .
     ports:
       - "8000:8000"
     depends_on:
       - db
     command: /bin/bash -c "sleep 30; python3 manage.py collectstatic && python3 manage.py makemigrations && python3 manage.py migrate && gunicorn mellon.wsgi --bind 0.0.0.0:8000 "

Для второго способа попробуйте что-то вроде этого:

  app:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
    restart: on-failure
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...