如何使用DATABASE_URL将Docker容器连接到localhost上运行的PostgreSQL?

时间:2018-02-05 20:01:10

标签: python django postgresql docker aptible

我正在关注Aptible Django Quickstart Tutorial,其中描述了如何创建和部署应用程序Aptible的PaaS。我还希望能够在本地运行带有Django应用程序的Docker容器并连接到本地PostgreSQL数据库,但我不清楚如何执行此操作。

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"]

其中mysite是Django应用程序的名称。其settings.py使用dj-database-url如下:

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

为了连接到PostgreSQL的本地实例,似乎我应该遵循Allow docker container to connect to a local/host postgres database上的 Docker for Mac解决方案

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

但是,如果我尝试这个,我仍然会收到以

结尾的错误
  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?

在我看来,当前配置的应用不会对DB_PORTDB_HOST环境变量做任何事情,因为它正在从{{1}一次性读取这些内容}。这是问题吗?如果是这样,我怎么能在使用DATABASE_URL时解决这个问题,因为这似乎是Aptible的“界面”?

3 个答案:

答案 0 :(得分:1)

据我了解,postgres不是在容器上运行,而是在主机操作系统上运行,对吗?

请在下面说明:

1。检查你的postgres接受所有IP地址的连接

通常postgres仅侦听localhost,这意味着拒绝与localhost以外的连接。每个docker容器都连接到虚拟网络,从容器到主机的通信通过该虚拟网络进行。

更新您的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。使用正确的IP地址/主机名

如前所述,容器通过此虚拟网络与主机通信。确保您使用的是正确的主机名或IP地址。

  • 本地主机

localhost不起作用,因为在容器上下文中,localhost引用容器

  • docker.for.mac.host.internal

至少对我来说它不起作用(在mac上使用docker-ce),看到主机解析无法正常工作

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

我使用我的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

因此,请尝试使用有效的IP地址,即docker设备的ip或物理网络接口的ip。

3。使用泊坞窗撰写文件

使用docker compose文件以compose或swarm运行,请参阅此处的示例应用程序:https://docs.docker.com/engine/swarm/stack-deploy/#create-the-example-application

答案 1 :(得分:1)

我设法通过更改beforeSend: function(settings) { settings.data = JSON.stringify({ 'search': document.getElementById('inputValue').value }); return settings; } 文件中的DATABASE_URL来解决问题

.env

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

并运行我标记为DATABASE_URL=postgres://my_app:my_password@docker.for.mac.host.internal/my_database 的容器,如下所示:

lucy_web

我的docker run -p 8000:8000 --env-file .env lucy_web 中没有必要将listen_addresses更改为'*';这仍然是默认值postgresql.conf。 (我相信这是因为localhost参数将-p 8000:8000上的端口8000映射到容器)。

答案 2 :(得分:0)

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

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