[英]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 網絡內的postgis
和web
,它們可以分別通過它們的 DNS 名稱(即postgis
和web
。
至於端口, web
容器可以達到postgis
在端口5432
,但不是25432
,而你的主機可以在端口到達數據庫25432
,但不是5432
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.