简体   繁体   English

如何使用 DATABASE_URL 将 Docker 容器连接到在本地主机上运行的 PostgreSQL?

[英]How to connect a Docker container to PostgreSQL running on the localhost using a DATABASE_URL?

I'm following the Aptible Django Quickstart Tutorial which described how to create and deploy an app Aptible's PaaS.我正在关注Aptible Django 快速入门教程,该教程描述了如何创建和部署应用程序 Aptible 的 PaaS。 I would also like to be able to run the Docker container with the Django app locally and connect to a local PostgreSQL database, however, and it is unclear to me how to do this.我还希望能够在本地运行带有 Django 应用程序的 Docker 容器并连接到本地 PostgreSQL 数据库,但是,我不清楚如何做到这一点。

The Dockerfile for the Django app is: Django 应用程序的Dockerfile是:

FROM python:3.6

# System prerequisites
RUN apt-get update \
 && apt-get -y install build-essential libpq-dev \
 && rm -rf /var/lib/apt/lists/*

# If you require additional OS dependencies, install them here:
# RUN apt-get update \
#  && apt-get -y install imagemagick nodejs \
#  && rm -rf /var/lib/apt/lists/*

# Install Gunicorn. If Gunicorn is already present in your requirements.txt,
# you don't need that (but if won't hurt).
RUN pip install gunicorn

ADD requirements.txt /app/
WORKDIR /app
RUN pip install -r requirements.txt

ADD . /app

EXPOSE 8000

CMD ["gunicorn", "--access-logfile=-", "--error-logfile=-", "--bind=0.0.0.0:8000", "--workers=3", "mysite.wsgi"]

where mysite is the name of the Django app.其中mysite是 Django 应用程序的名称。 Its settings.py uses dj-database-url as follows:它的settings.py使用dj-database-url如下:

import dj_database_url
DATABASES = {'default': dj_database_url.config()}

In order to connect to a local instance of PostgreSQL, it would seem I should follow the Docker for Mac Solution on Allow docker container to connect to a local/host postgres database :为了连接到 PostgreSQL 的本地实例,我似乎应该遵循Docker for Mac 解决方案上的Allow docker container to connect to a local/host postgres database

docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.host.internal

However, if I try this I still get an error ending with但是,如果我尝试此操作,我仍然会收到以结尾的错误

  File "/usr/local/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?

It would seem to me that the app as currently configured is not 'doing anything' with the DB_PORT and DB_HOST environment variables, because it is reading these in one go from the DATABASE_URL .在我看来,当前配置的应用程序没有对DB_PORTDB_HOST环境变量“做任何事情”,因为它正在从DATABASE_URL一次性读取这些。 Is this the problem?这是问题吗? If so, how could I fix this while still using DATABASE_URL as this appears to be the 'interface' to Aptible?如果是这样,我如何在仍然使用DATABASE_URL同时解决这个问题,因为这似乎是 Aptible 的“接口”?

I managed to fix the problem by changing the DATABASE_URL in the .env file from我设法通过更改.env文件中的DATABASE_URL

DATABASE_URL=postgres://my_app:my_password@localhost/my_database

to

DATABASE_URL=postgres://my_app:my_password@docker.for.mac.host.internal/my_database

and running the container, which I tagged lucy_web , like so:并运行我标记为lucy_web的容器,如下所示:

docker run -p 8000:8000 --env-file .env lucy_web

It was not necessary to change listen_addresses to '*' in my postgresql.conf ;没有必要在我的postgresql.conf中将listen_addresses更改为'*' this was still at its default, localhost .这仍然是它的默认值, localhost (I believe this is because the -p 8000:8000 argument maps port 8000 on localhost to the container). (我相信这是因为-p 8000:8000参数将localhost上的端口 8000 映射到容器)。

As I understand, postgres is not running on a container but as a service on your host os, right?据我了解,postgres 不是在容器上运行,而是作为主机操作系统上的服务运行,对吗?

Please theck below:请点击以下:

1. Check your postgres accepts connections on all ip addresses 1. 检查您的 postgres 是否接受所有 ip 地址上的连接

Usually postgres listens to localhost only, that means, connections to other than localhost are refused.通常 postgres 只侦听 localhost,这意味着拒绝与localhost以外的连接。 Each docker container is attached to a virtual network and communication from container to host happens through that virtual network.每个 docker 容器都连接到一个虚拟网络,从容器到主机的通信通过该虚拟网络发生。

Update your postgresql.conf file and add:更新您的postgresql.conf文件并添加:

listen_addresses = '*'          # what IP address(es) to listen on;
                                    # comma-separated list of addresses;
                                    # defaults to 'localhost'; use '*' for all
                                    # (change requires restart)

2. Use correct ip address/hostname 2.使用正确的IP地址/主机名

As stated before, container communicates to host through this virtual network.如前所述,容器通过这个虚拟网络与主机通信。 Make sure your are using the correct hostname or ip address.确保您使用的是正确的主机名或 IP 地址。

  • localhost本地主机

localhost is not going to work because from within the container context, localhost refers to the container localhost不会工作,因为在容器上下文中, localhost 指的是容器

  • docker.for.mac.host.internal docker.for.mac.host.internal

At least for me it doesn't work (docker-ce on a mac), see that host resolution is not working至少对我来说它不起作用(mac上的docker-ce),看到主机分辨率不起作用

docker run --rm -it postgres:10 ping docker.for.mac.host.internal
ping: unknown host
  • use your ip address使用您的 IP 地址

I'm using my the ip address given by my dhcp server, ping works我正在使用我的 dhcp 服务器提供的 IP 地址,ping 工作正常

docker run --rm -it postgres:10 ping 192.168.0.* -c 1
PING 192.168.0.* (192.168.0.*): 56 data bytes
64 bytes from 192.168.0.*: icmp_seq=0 ttl=37 time=0.455 ms

So try using a valid ip address, either the ip of the docker device or the ip from your physical network interface.因此,请尝试使用有效的 ip 地址,无论是 docker 设备的 ip 还是来自物理网络接口的 ip。

3. Use a docker compose file 3. 使用 docker compose 文件

Use a docker compose file to run with either compose or swarm, see sample application here: https://docs.docker.com/engine/swarm/stack-deploy/#create-the-example-application使用 docker compose 文件与 compose 或 swarm 一起运行,请参阅此处的示例应用程序: https : //docs.docker.com/engine/swarm/stack-deploy/#create-the-example-application

Windows 用户配置他们的 env 以使用:

DATABASE_URL=postgres://my_app:my_password@docker.host.internal/my_database

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 连接到Docker容器上的PostgreSQL数据库 - Connect to a PostgreSQL database on a Docker container 如何通过运行带有URL的docker容器来连接docker容器中的python应用 - how to connect python app in docker container with running docker container with url 如何从Docker容器中的python脚本连接到localhost上的mysql数据库 - How to connect to a mysql database on localhost from a python script in a docker container 无法连接到 Docker 容器中的 PostgreSQL 数据库 - Can't connect to PostgreSQL database in Docker container 如何从 database_url 解析 mysql 数据库名称 - how to parse mysql database name from database_url 如何为 Postgres Mac 终端设置 DATABASE_URL 环境变量? - How to set DATABASE_URL environment variable for Postgres Mac terminal? 我应该如何设置我的 DATABASE_URL? - How should I set my DATABASE_URL? 如何将 google colab 与运行 docker 图像的本地主机连接? - How to connect google colab with localhost running docker image? 如何使用 pymsql 连接到 docker 容器上的 mariadb - How to connect to mariadb on a docker container using pymsql 无法从我在 docker 容器下运行的应用程序连接到 localhost:8000 的快速 api 服务器 - Cannot connect to fast api server at localhost:8000 from my application which is running under a docker container
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM