簡體   English   中英

docker-compose django 應用程序找不到 postgresql 數據庫

[英]docker-compose django app cannot find postgresql db

我正在嘗試在 docker 容器中創建一個 Django 應用程序。 該應用程序將使用帶有 postgis 擴展名的 postgres db,我在另一個數據庫中擁有它。 我正在嘗試使用 docker-compose 解決此問題,但無法使其正常工作。

我可以讓應用程序在沒有容器的情況下工作,數據庫容器化就好了。 我還可以使用 sqlite db 使應用程序在容器中工作(因此包含的文件不包含外部容器依賴項)。 無論我做什么,它都找不到數據庫。

我的 docker-compose 文件:

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

最后我在 django 應用程序的 settings.py 中:

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 中運行服務器(在構建過程中進行遷移,將 runserver 作為啟動命令),但這需要 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?

有人知道為什么這不起作用嗎?

您不能將 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}

我在 django 應用程序的settings.py中看到,您通過以下方式連接到 Postgres

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

.env您將POSTGRES_HOST的值設置為localhost 這意味着web容器正在嘗試訪問 localhost 上的 Postgres 服務器postgis ,這不應該是這種情況。

為了解決這個問題,只需將您的.env文件更新為如下所示:

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

原因是在您的情況下, postgis docker-compose帶來了 2 個容器:位於同一個 Docker 網絡內的postgisweb ,它們可以分別通過它們的 DNS 名稱(即postgisweb

至於端口, web容器可以達到postgis在端口5432 ,但不是25432 ,而你的主機可以在端口到達數據庫25432 ,但不是5432

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM