docker-compose 与 postgres 的 Django 连接

Posted

技术标签:

【中文标题】docker-compose 与 postgres 的 Django 连接【英文标题】:Django connection to postgres by docker-compose 【发布时间】:2017-08-06 07:23:36 【问题描述】:

我的 django 项目无法连接到 postgres 数据库容器。我该怎么办?

它在命令 python manage.py collectstatic --noinput && python manage.py makemigrations blog && python manage.py migrate 上崩溃。 我知道 docker run 命令会创建一个新容器,但我有更多命令 一个是 docker-compose.yml 中的 bash。它应该有效,不是吗?

我的Dockerfile:

FROM python:3.6-alpine
MAINTAINER Name <name@domain>

ENV PYTHONUNBUFFERED 1
ENV INSTALL_PATH /heckblog
RUN mkdir -p $INSTALL_PATH

WORKDIR $INSTALL_PATH


COPY requirements.txt requirements.txt

# make available run pip install psycopg2
RUN apk update && \
    apk add --virtual build-deps gcc python3-dev musl-dev && \
    apk add postgresql-dev
RUN pip3 install -r requirements.txt

# add bash into alpine linux
RUN apk add --update bash && rm -rf /var/cache/apk/*

COPY ./heckblog .
#RUN pip install .

CMD gunicorn -b 0.0.0.0:8000 --access-logfile - "config.wsgi:application"

我的docker-compose.yml:

version: '2'


services:
    db:
        image: postgres:alpine
        environment:
            POSTGRES_USER: blogdmin
            POSTGRES_PASSWORD: password
            POSTGRES_DB: heckblog
            PGDATA: /tmp/pgdata
        volumes:
            - postgres_data:/tmp/pgdata

    web:
        build: .
        command: >
            bash -c "sleep 10 &&
            python manage.py collectstatic --noinput && 
            python manage.py makemigrations blog && 
            python manage.py migrate &&
            echo \"from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass')\" | python manage.py shell &&
            gunicorn -b 0.0.0.0:8000 --access-logfile - --reload \"config.wsgi:application\""                
        volumes:
            - ./heckblog:/heckblog
        depends_on:
            - db
        environment: 
            IN_DOCKER: 1
        ports:
            - "80:8000"


volumes:
    postgres_data:

settings.py:

...

DATABASES = 
    'default': 
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'heckblog',
        'USER': 'blogdmin',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '', # default port
    


...

docker-compose up --build的输出:

web_1  |        TCP/IP connections on port 5432?
web_1  | could not connect to server: Connection refused
web_1  |        Is the server running on host "localhost" (127.0.0.1) and accepting
web_1  |        TCP/IP connections on port 5432?
web_1  |
heckblog_web_1 exited with code 1

我使用: 视窗 10 泊坞窗 17.03.0-ce-win1-(10296) 码头工人撰写版本 1.11.2 Django==1.10.6 psycopg2==2.7.1.

感谢解答

【问题讨论】:

【参考方案1】:

默认情况下,docker 中的每个容器都有自己的主机名和 IP。当 compose 为您启动容器时,它还会默认将所有容器放在网络上,以允许基于 DNS 的发现。

这意味着在 localhost 上无法访问您的数据库,但您可以通过服务名称“db”访问它。在您的 settings.py 中更改此行:

    'HOST': 'localhost',

到:

    'HOST': 'db',

【讨论】:

是的,这就是我错过的。非常感谢。 我在主机上运行postgres,即我的MacOS。我的docker-compose.yml 中有network_mode: host,但是尽管postgres 正在运行,但我的dockerized django 应用程序仍然失败,并且出现同样的错误,即使我的HOSTlocalhost @saadi 这里的问题和答案在使用主机网络时不适用。如果可以避免的话,我也强烈建议不要使用主机网络。 @BMitch 你能建议使用network_host 的任何其他替代方案吗?就像如果在 OS 中安装了 postgres 服务,并且我想在 docker 映像中使用它,我应该在 host 而不是 localhost 旁边放什么,因为 localhost 显然无法工作,因为它安装在 OS 中不是码头工人 @saadi 首先将您的依赖项移动到 docker 中。他们使用 docker 网络。您在这里的评论似乎是一个不同的问题,而不是澄清上述问题的答案。请使用“提问”链接提出新问题或搜索有关从容器内部访问主机服务的问题。【参考方案2】:

这对我有用:

在撰写中:

version: '3.7'
services: 
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes: 
        - .:/code
    ports: 
        - 8000:8000
    environment: 
        - DB_HOST=db
        - DB_NAME=web
        - DB_USER=postgres
        - DB_PASSWORD=postgres

    depends_on: 
        - db

  db:
    image: postgres:12-alpine
    volumes: 
        - postgres_data:/var/lib/postgresql/data/
    environment: 
        - POSTGRES_DB=web
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
volumes:
   postgres_data:

在设置中:

DATABASES = 
'default': 
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': os.environ.get('DB_NAME'),
    'USER':os.environ.get('DB_USER'),
    'PASSWORD': os.environ.get('DB_PASSWORD'),
    'HOST':os.environ.get('DB_HOST'),
    'PORT':5432,
 

【讨论】:

以上是关于docker-compose 与 postgres 的 Django 连接的主要内容,如果未能解决你的问题,请参考以下文章

在 docker-compose 中运行 Django 应用程序:与 postgres db 的连接第一次拒绝但之后可以工作

docker-compose 安装postgres(设置默认用户名,密码,暴露端口)

使用 docker-compose 启动 Postgres 会立即关闭

从 docker-compose 文件连接到 Postgres docker 容器 [重复]

如何在 docker-compose 中访问 Postgres 数据库

docker springboot 仅通过 docker-compose 在 postgres 5432 上连接