docker -композит django приложение не может найти postgresql дБ - PullRequest
0 голосов
/ 17 марта 2020

Я пытаюсь создать приложение Django в контейнере docker. Приложение будет использовать postgres дБ с расширением Postgis, которое у меня есть в другой базе данных. Я пытаюсь решить эту проблему с помощью docker -compose, но не могу заставить его работать.

Я могу заставить приложение работать без контейнера, с базой данных, которая прекрасно упакована. Я также могу заставить приложение работать в контейнере, используя базу данных sqlite (поэтому файл включен без внешних зависимостей контейнера). Что бы я ни делал, он не может найти базу данных.

Мой docker -компонентный файл:

version: '3.7'

services:
    postgis:
        image: kartoza/postgis:12.1
        volumes:
            - postgres_data:/var/lib/postgresql/data/
        ports:
            - "${POSTGRES_PORT}:5432"
        environment:
            - POSTGRES_USER=${POSTGRES_USER}
            - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
            - POSTGRES_DB=${POSTGRES_DB}
        env_file:
            - .env
    web:
        build: .
#        command: sh -c "/wait && python manage.py migrate --no-input && python /code/app/manage.py runserver 0.0.0.0:${APP_PORT}"
        command: sh -c "python manage.py migrate --no-input && python /code/app/manage.py runserver 0.0.0.0:${APP_PORT}"
#        restart: on-failure
        ports:
            - "${APP_PORT}:8000"
        volumes:
            - .:/code
        depends_on:
            - postgis
        env_file:
            - .env
        environment:
            WAIT_HOSTS: 0.0.0.0:${POSTGRES_PORT}
volumes:
    postgres_data:
        name: ${POSTGRES_VOLUME}

Мой Dockerfile (из приложения):

# Pull base image
FROM python:3.7
LABEL maintainer="yb.leeuwen@portofrotterdam.com"

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install dependencies
# RUN pip install pipenv
RUN pip install pipenv
RUN mkdir /code/
COPY . /code
WORKDIR /code/
RUN pipenv install --system
# RUN pipenv install pygdal

RUN apt-get update &&\
    apt-get install -y binutils libproj-dev gdal-bin python-gdal python3-gdal postgresql-client


## Add the wait script to the image
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.7.3/wait /wait
RUN chmod +x /wait

# set work directory
WORKDIR /code/app
# RUN python manage.py migrate --no-input
# CMD ["python", "manage.py", "migrate", "--no-input"]
# RUN cd ${WORKDIR}

# If we want to run docker by itself we need to use below
# but if we want to run from docker-compose we'll set it there
EXPOSE 8000

# CMD /wait && python manage.py migrate --no-input
# CMD ["python", "manage.py", "migrate", "--no-input"]
# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Мой файл .env:

# POSTGRES
POSTGRES_PORT=25432
POSTGRES_USER=username
POSTGRES_PASSWORD=pass
POSTGRES_DB=db
POSTGRES_VOLUME=data
POSTGRES_HOST=localhost

# GEOSERVER


# DJANGO
APP_PORT=8000

И, наконец, мой в моем файле settings.py приложения django:

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': os.getenv('POSTGRES_DBNAME'),
        'USER': os.getenv('POSTGRES_USER'),
        'PASSWORD': os.getenv('POSTGRES_PASS'),
        'HOST': os.getenv("POSTGRES_HOST", "localhost"),
        'PORT': os.getenv('POSTGRES_PORT')
    }
}

Я пробовал много вещей ( как вы видите в некоторых комментариях). Я понял, что docker -compose, кажется, не ждет, пока postgres не будет полностью запущен, вращается и принимает запросы, поэтому я попытался встроить функцию ожидания (как предложено на веб-сайте). Сначала у меня были миграции и запуск сервера внутри Dockerfile (миграции в процессе сборки и запуска сервера в качестве команды запуска), но для этого требуется postgres, и, поскольку он не ожидал, он не функционировал. Я наконец-то вынул все это в файл docker -compose.yml, но все равно не могу заставить его работать.

Я получаю ошибку:

web_1      |    Is the server running on host "localhost" (127.0.0.1) and accepting
web_1      |    TCP/IP connections on port 25432?
web_1      | could not connect to server: Cannot assign requested address
web_1      |    Is the server running on host "localhost" (::1) and accepting
web_1      |    TCP/IP connections on port 25432?

У кого-нибудь есть идеи? почему это не работает?

Ответы [ 2 ]

1 голос
/ 18 марта 2020

Я вижу, что в вашем settings.py приложения django вы подключаетесь к Postgres через

'HOST': os.getenv("POSTGRES_HOST", "localhost"),

В то время как в .env вы устанавливаете значение на POSTGRES_HOST до localhost. Это означает, что контейнер web пытается связаться с Postgres сервером postgis на локальном хосте, чего не должно быть.

Чтобы решить эту проблему, просто обновите файл .env до быть таким:

POSTGRES_PORT=5432
...
POSTGRES_HOST=postgis
...

Причина в том, что в вашем случае docker-compose вызывает 2 контейнера: postgis и web внутри одной сети Docker, и они могут достигать друг друга через их DNS-имя, т.е. postgis и web соответственно.

Что касается порта, контейнер web может достигать postgis на порту 5432, но не 25432, в то время как хост-компьютер может достичь база данных в порту 25432, но не 5432

1 голос
/ 17 марта 2020

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

, чтобы исправить проблему, измените свой env на

# POSTGRES
POSTGRES_PORT=5432
POSTGRES_USER=username
POSTGRES_PASSWORD=pass
POSTGRES_DB=db
POSTGRES_VOLUME=data
POSTGRES_HOST=postgis

# DJANGO
APP_PORT=8000

и создайте файл на

version: '3.7'

services:
    postgis:
        image: kartoza/postgis:12.1
        volumes:
            - postgres_data:/var/lib/postgresql/data/
        environment:
            - POSTGRES_USER=${POSTGRES_USER}
            - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
            - POSTGRES_DB=${POSTGRES_DB}
        env_file:
            - .env
    web:
        build: .
#        command: sh -c "/wait && python manage.py migrate --no-input && python /code/app/manage.py runserver 0.0.0.0:${APP_PORT}"
        command: sh -c "python manage.py migrate --no-input && python /code/app/manage.py runserver 0.0.0.0:${APP_PORT}"
#        restart: on-failure
        ports:
            - "${APP_PORT}:8000"
        volumes:
            - .:/code
        depends_on:
            - postgis
        env_file:
            - .env
        environment:
            WAIT_HOSTS: postgis:${POSTGRES_PORT}
volumes:
    postgres_data:
        name: ${POSTGRES_VOLUME}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...