在docker-compose中运行Django应用程序:连接到postgres数据库拒绝了第一次,但后来工作
我有这个奇怪的问题,可以从Docker的简单教程中复制。
如果我完全按照教程,一切都会正常工作,即在docker-compose up
命令后,Web容器将运行并很好地连接到数据库容器。
但是,如果我select在主机上创build相同的Django项目,请更改postgres数据库的设置,并将其复制到Dockerfile中的Web图像中,而不是将主机目录挂载到容器,然后在那里执行这些操作(使用命令docker-compose run web django-admin.py startproject composeexample .
,然后更改生成的设置文件并位于主机上挂载的目录中),第一次运行docker-compose up
, Web容器将有问题连接到数据库,错误如下
web_1 | psycopg2.OperationalError:无法连接到服务器:连接拒绝web_1 | 服务器是否在主机“db”(172.18.0.2)上运行并接受web_1 | 端口5432上的TCP / IP连接?
但是,如果我停止与docker-compose合成,然后再用docker-compose再次运行,Web容器将成功连接到db而不会出现问题。
'拒绝连接'似乎不是一个不常见的问题,但我已经检查和validation了所有的设置是正确的,像通常的原因,例如错误的端口号,端口没有暴露或设置主机为'本地'而不是'数据库'等在这种情况下不是问题。
注意:FWIW,我使用CNTLM作为主机的系统代理,必须设置网页图片的环境variables,并且对于其他场景也能正常工作。
编辑:请find更多的信息如下。
在主机目录中,我有以下文件和目录
- 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, } } .........
Dockerfile(大部分是相同的,添加了envvariables):
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/
docker-compose(我删除了已安装的卷。:/代码,因为项目文件在构build时已经被复制到了Web映像中,我将它作为原始文件进行了testing,结果没有区别):
version: '3' services: db: image: postgres web: build: . command: python3 manage.py runserver 0.0.0.0:8000 ports: - "8000:8000" depends_on: - db
正如文档所述, depends_on depends_on
expression了容器之间的依赖关系,但这并不意味着容器将等待其他人准备好,一个可能的解决scheme就是在docker-compose
添加一些东西,比如:
command: /bin/bash -c "sleep 7; python3 manage.py runserver -h 0.0.0.0 -p 9000 -r -d"
使用wait-for-it.sh
等待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
它会等待正义的时间,不会浪费任何时间。