django - 如何从 Docker 容器中的 Django 访问本地主机的 postgres 数据库

标签 django postgresql docker ubuntu

这个问题在这里已经有了答案:





From inside of a Docker container, how do I connect to the localhost of the machine?

(37 个回答)


4个月前关闭。




我在 docker 容器中有一个 django,它必须访问我的本地主机上的 postgres 数据库。访问驻留在外部主机上的数据库时,Dockerfile 工作正常,但在我的主机上找不到数据库。
这是一个众所周知的问题,并且有很多文档,但在我的情况下它不起作用。这个问题类似于 another question但它并没有解决我的问题。正如@Zeitounator 指出的那样,我实际上描述了这个问题的正确解决方案,但它仍然不起作用。感谢@Zeitounator,我意识到必须解决问题的两个部分:docker 端和 PostgreSQL 端。我在阅读的任何答案中都没有找到该解决方案。然而,我确实读到了同样的挫败感:得到一个不起作用的解决方案。
这一切都集中在我将哪个互联网地址传输到 HOST在 django settings.py 中的数据库驱动程序字典中键入:

print('***', os.environ['POSTGRES_DB'], os.environ['POSTGRES_USER'],
        os.environ['POSTGRES_HOST'], os.environ['POSTGRES_PORT'])

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2', # os.environ['ENGINE'],
        'NAME': 'demo',
        'USER': os.environ['POSTGRES_USER'],
        'PASSWORD': os.environ['POSTGRES_PASSWORD'],
        'HOST': os.environ['POSTGRES_HOST'],
    }
}
并运行 Dockerfile:
docker build -t dd .
docker run --name demo -p 8000:8000 --rm dd
当 POSTGRES_HOST 指向我的外部服务器 192.168.178.100 时,它工作得很好。运行时python manage.py runserver它找到主机和数据库。服务器启动并等待命令。当指向 127.0.0.1 时它会失败(这实际上也很棒:容器真的隔离了)。
django.db.utils.OperationalError: 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?
但是因为我可以连接到我的服务器,所以我应该能够连接到 localhost IP 并且同样失败(我忘了告诉数据库确实在运行)。当我使用 host.docker.internal运行时它也不起作用:
docker run --name demo -p 8000:8000 --rm --add-host host.docker.internal:host-gateway dd
它取代了host.docker.internal通过 172.17.0.1。到目前为止唯一有效的解决方案是:
# set POSTGRES_HOST at 127.0.0.1
docker run --name demo -p 8000:8000 --rm --network host dd
但这似乎是我不想要的。据我了解文档,它使容器可以使用完整的主机堆栈,这首先破坏了容器的想法。但第二个:它在 docker-compose 中不起作用,虽然我指定:
extra_hosts:
  - "host.docker.internal:host-gateway"
network_mode: host导致编译错误,docker-compose 拒绝运行。
有没有办法从我的 PC 上运行的 docker 以及 Dockerfile 和 docker-compose 访问我的 PC 上运行的服务,并且也可以部署?
使用 Ubuntu 21.04(最新版本),Docker 版本 20.10.7,构建 20.10.7-0ubuntu5.1,postgresql v14。我的 Dockerfile:
FROM python:3

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

RUN mkdir /app

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "manage.py", "runserver", "127.0.0.1:8000"]

最佳答案

解决这个问题有两个部分:@Zeitounator 指出的 docker 部分和 postgresql 部分。我不知道 postgres 部分。感谢他的评论,我可以解决这个问题。它适用于 Dockerfile 以及使用此 Dockerfile 的 docker-compose。
必须更改两个 postgres 配置文件,它们都位于/etc/postgresql//main:
postgresql.conf
更改监听地址。最初它显示:

listen_addresses = 'localhost'      # what IP address(es) to listen on;
                    # comma-separated list of addresses;
                    # defaults to 'localhost'; use '*' for all
                    # (change requires restart)
我将“本地主机”更改为“*”。它可以更具体,在本例中为 docker 地址,但作为概念证明它有效。
pg_hba.conf
就我而言 host.docker.internal解析为 172.17.0.1。这似乎是我在有关此主题的大多数讨论中注意到的一些默认 docker 网关地址。
在文件的最后添加两行:
host    all             all              172.17.0.1/0                       md5
host    all             all              ::ffff:ac11:1/0                            md5

关于django - 如何从 Docker 容器中的 Django 访问本地主机的 postgres 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71099061/

相关文章:

python - 从 generic.DetailView 传递上下文数据

ruby-on-rails - Ruby on Rails - 验证和更新/创建多个对象

database - 新版本的 postgresql docker 容器没有新添加的数据

生产环境中的 Windows 上的 Docker

node.js - docker 上的 babel watch

django - Nginx+uWSGi+Django 长任务 Bad Gateway 报错

python - Django 表单提交按钮

python - 在 Django 中找不到静态文件错误

当一行包含特定数字时,SQL 对行进行计数

sql - PostgreSQL - 根据 3 列选择重复数据