将 Django 和 Postgresql 与 Docker 连接起来

Posted

技术标签:

【中文标题】将 Django 和 Postgresql 与 Docker 连接起来【英文标题】:Linking Django and Postgresql with Docker 【发布时间】:2014-12-05 08:46:59 【问题描述】:

我有两个 Docker 容器。第一个是 Postgresql 容器,我使用以下命令运行它。

sudo docker run -v /home/mpmsp/project/ezdict/postgresql/data:/var/lib/postgresql/data -p 127.0.0.1:5432:5432  -name my-postgres -d postgres

它基于official image 并且运行良好,我可以从主机连接到 Postgresql。

第二个容器是我的 Django 应用程序的容器。该镜像是使用以下 Dockerfile 构建的(基于this image):

FROM python:3-onbuild
EXPOSE 8000 5432
CMD ["/bin/bash"]

我使用以下命令运行这个容器

sudo docker run --link my-postgres:my-postgres -v /home/mpmsp/project/ezdict/ezbkend:/usr/src/app -name my-app -i -t my-app

docker ps 输出显示容器已链接

NAMES
my-app/my-postgres, my-postgres

但是,当我转到 localhost:8000 时,我看到来自 Django 的错误页面,输出如下

OperationalError at /api-auth/login/
could not connect to server: Connection refused
    Is the server running on host "127.0.0.1" and accepting
    TCP/IP connections on port 5432?
Request Method: GET
Request URL:    http://127.0.0.1:8000/api-auth/login/
Django Version: 1.6.4
Exception Type: OperationalError
Exception Value:    
could not connect to server: Connection refused
    Is the server running on host "127.0.0.1" and accepting
    TCP/IP connections on port 5432?
Exception Location: /usr/local/lib/python3.4/site-packages/psycopg2/__init__.py in     connect, line 164
Python Executable:  /usr/local/bin/python
Python Version: 3.4.1
Python Path:    
['/usr/src/app',
 '/usr/local/lib/python34.zip',
 '/usr/local/lib/python3.4',
 '/usr/local/lib/python3.4/plat-linux',
 '/usr/local/lib/python3.4/lib-dynload',
 '/root/.local/lib/python3.4/site-packages',
 '/usr/local/lib/python3.4/site-packages']
Server time:    Птн, 10 Окт 2014 12:07:07 +0400

应用程序的settings.py

  DATABASES = 
   'default': 
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'NAME': 'mydb',                      
       'USER': 'postgres',
       'PASSWORD': '',
       'HOST': '127.0.0.1',                      
       'PORT': '5432',                      
    
  

如何使链接工作?提前致谢

【问题讨论】:

【参考方案1】:

您的 Django 映像的 Dockerfile 不应暴露端口 5432,因为从该映像创建的任何容器中都不会运行 Postgresql 服务器:

FROM python:3-onbuild
EXPOSE 8000
CMD ["/bin/bash"]

然后,当您运行 Django 容器时,将其与

链接

--link my-postgres:my-postgres

您的数据库设置不正确。

在 Django 容器中:127.0.0.1 指的是 Django 容器,它没有在端口 5432 上运行任何侦听服务。

所以你的 settings.py 文件应该是:

  DATABASES = 
   'default': 
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'NAME': 'mydb',                      
       'USER': 'postgres',
       'PASSWORD': '',
       'HOST': 'my-postgres',                      
       'PORT': '5432',                      
    
  

当你运行你的 Django 容器时:

sudo docker run --link my-postgres:db -v /home/mpmsp/project/ezdict/ezbkend:/usr/src/app -name my-app -i -t my-app

那么您的 settings.py 文件必须是:

  DATABASES = 
   'default': 
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'NAME': 'mydb',                      
       'USER': 'postgres',
       'PASSWORD': '',
       'HOST': 'db',                      
       'PORT': '5432',                      
    
  

【讨论】:

数据库同步/迁移是什么?我意识到我无法在构建时链接 postgres 容器,但我需要在运行 django 服务器之前执行 syncdb 并以某种方式迁移。 所以--link my-postgres:[2nd arg] 中的第二个参数(冒号之后)变成了default 设置中关于django 的DATABASESHOST 键的值? 是的,语法是--link <a container name>:<alias>【参考方案2】:

只有在构建并启动 db 和 django 容器后才能使用 syncdb,然后您可以使用 fig/docker-compose/docker 手动运行 syncdb 命令。 我正在考虑创建一个 AT 作业并让容器自己运行 syncdb(并在 syncdb 之后创建一个管理员用户 - 用于创建必要的表)

【讨论】:

以上是关于将 Django 和 Postgresql 与 Docker 连接起来的主要内容,如果未能解决你的问题,请参考以下文章

Heroku 和 Django 组合中的 Postgresql 更改与共享数据库

使用Django和PostgreSQL进行事务(@atomic)的默认隔离级别

将 Django/South/PostgreSQL 从按需要计算的汇总值迁移到数据库中维护的汇总值的正确方法是啥?

避免在 django 1.4 和 postgresql 8.1 中使用与 bug #10467 相关的 RETURN postgresql 语句

Django / PostgresQL jsonb (JSONField) - 将选择和更新转换为一个查询

Django 与 Postgresql,列必须出现在 GROUP BY 子句中或在聚合函数中使用