在docker-compose中运行Django应用程序:连接到postgres db第一次拒绝但后续工作

ptr*_*een 2 django postgresql docker docker-compose

我有这个奇怪的问题,可以通过Docker 的简单教程重现.

如果我完全按照教程,一切都会正常工作,即在docker-compose up命令之后,Web容器将运行并很好地连接到db容器.

但是,如果我选择在主机上创建相同的Django项目,更改其设置在为Postgres数据库,并且将其复制到它的Dockerfile网页图像,而不是安装在主机目录的容器,做这些事情有作为在教程中显示(使用命令docker-compose run web django-admin.py startproject composeexample .然后更改生成的设置文件并位于主机上的安装目录中),第一次运行时docker-compose up,Web容器连接到db时会出现问题,错误如下

web_1 | psycopg2.OperationalError:无法连接到服务器:连接拒绝web_1 | 服务器是否在主机"db"(172.18.0.2)上运行并接受web_1 | 端口5432上的TCP/IP连接?

但是,如果我停止使用docker-compose进行组合,然后使用docker-compose再次运行它,则Web容器将成功连接到db,没有任何问题.

"拒绝连接"似乎不是一个不常见的问题,但我已经检查并验证所有设置都是正确的并且通常的原因如错误的端口号,端口未暴露或将主机设置为"本地"而不是"db"等在这种情况下不是问题.

注意:FWIW,我使用CNTLM作为主机中的系统代理,并且必须为Web图像设置环境变量,并且它适用于其他场景.

编辑:请在下面找到更多信息.

在主机目录中,我有以下文件和目录

  • composeexample(由另一个容器生成,遵循相同的教程并复制到此处)
  • manage.py(由另一个容器生成并复制到此处)
  • requirements.txt(与教程中的完全相同)
  • Dockerfile(稍微修改一下教程中的那个)
  • docker-compose.yml(稍微修改过教程中的那个)

composeexample/settings.py:

.........
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}
.........
Run Code Online (Sandbox Code Playgroud)

Dockerfile(大致相同,添加了env变量):

FROM python:3.5
ENV PYTHONUNBUFFERED 1
ENV http_proxy "http://172.17.0.1:3128"
ENV https_proxy "http://172.17.0.1:3128"
ENV HTTP_PROXY "http://172.17.0.1:3128"
ENV HTTPS_PROXY "http://172.17.0.1:3128"

RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
Run Code Online (Sandbox Code Playgroud)

docker-compose(我删除了已安装的卷.:/ code,因为项目文件在构建时已经被复制到Web图像.我测试时将它保留在原始文件中并且没有区别):

version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    depends_on:
      - db
Run Code Online (Sandbox Code Playgroud)

Rob*_*ert 6

使用__CODE__等待的Postgres做好准备:

下载这个众所周知的脚本:https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh

version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    command: /wait-for-it.sh db:5432 -- python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - ./wait-for-it.sh:/wait-for-it.sh
    ports:
      - "8000:8000"
    depends_on:
      - db
Run Code Online (Sandbox Code Playgroud)

它将等待正义的时间,不会浪费任何进一步的时间.


jul*_*las 5

正如文档所说的depends_on depends_on表示容器之间的依赖关系,但这并不意味着容器将等待其他容器准备就绪,可能的解决方案是在docker-compose 睡眠中添加一点,如下所示:

command: /bin/bash -c "sleep 7; python3 manage.py runserver -h 0.0.0.0 -p 9000 -r -d"
Run Code Online (Sandbox Code Playgroud)