Django 无法在 Docker 设置中连接到 Postgres

Posted

技术标签:

【中文标题】Django 无法在 Docker 设置中连接到 Postgres【英文标题】:Django can't connect to Postgres in Docker setup 【发布时间】:2017-07-07 12:22:29 【问题描述】:

我正在 Docker 中设置一个使用 Django 和 Postgres 的应用程序。我无法从应用程序连接到 Postgres。当我运行时:

docker-compose run web python manage.py runserver docker-compose run web python manage.py migrate

我收到以下错误:

django.db.utils.OperationalError: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

这是我的 Dockerfile:

FROM python:2.7

ADD requirements.txt /app/requirements.txt

WORKDIR /app/

RUN pip install -r requirements.txt

我的 docker-compose.yml:

version: '2'
services:
  db:
    image: postgres:9.4
    hostname: db
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
    ports:
      - "5432:5432"

  web:
    build:
      context: .
      dockerfile: Dockerfile
    hostname: web
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    links:
      - db
    depends_on:
      - db
    command:
      python manage.py runserver 0.0.0.0:8000

以及 Django 中的数据库设置:

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

docker ps -a 显示:

e9df7e1644ce        web             "python manage.py ..."   About a minute ago   Up About a minute          0.0.0.0:8000->8000/tcp   web_1
60801d3256e4        postgres:9.4        "docker-entrypoint..."   About a minute ago   Up About a minute          0.0.0.0:5432->5432/tcp   db_1

Django v1.10.5 Docker for Mac v1.13.1 docker-compose v 1.11.1

这里是日志:

网址:https://gist.github.com/steven-mercatante/912ca964fd05bee2c835b1ac5586c154

数据库:https://gist.github.com/steven-mercatante/4c9a03bfc4f2e90f4b9931bdc185652f

【问题讨论】:

检查您的 Docker 日志,Web 容器可能在 db 容器之前启动,因此依赖关系无法解决。 我认为depends_on: - db 会阻止 Web 容器在 db 容器之前启动,不是吗? 奇怪的是,web 容器的 docker 日志中没有任何内容。一开始说的是Attached to web_1, db_1,然后就是一堆来自db_1的日志。 你说的很对,但几天前我遇到了这个问题——不过我使用的是links。无论如何都值得一试。您能否将日志附加到问题中,以便查看它的任何人都可以更好地了解情况? 您必须以某种方式告诉您的应用程序通过 TCP/IP 而不是本地通过套接字连接到 postgress。不过不确定是否使用 django。 【参考方案1】:

原来问题在于 Postgres 在启动 Django 应用程序之前还没有完全启动。这很容易通过在启动 Web 服务器之前等待几秒钟来解决。我将我的web 服务的command 设置为./bin/boot.sh,该文件的内容是:

#!/bin/sh

# wait for Postgres to start
sleep 10

python manage.py migrate

python manage.py runserver 0.0.0.0:8000

编辑

根据您的应用程序,此方法可能不够好 - 大多数情况下,休眠 10 秒对我有用,但 postgres 可能需要 11 秒才能启动。这是一个改进的 bash 文件,其中包含我从 example 获取的函数。

#!/bin/bash

# wait for Postgres to start
function postgres_ready()
python << END
import sys
import psycopg2
try:
    conn = psycopg2.connect(dbname="postgres", user="postgres", password="postgres", host="postgres")
except psycopg2.OperationalError:
    sys.exit(-1)
sys.exit(0)
END


until postgres_ready; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

python manage.py migrate

gunicorn pft.wsgi:application -w 2 -b 0.0.0.0:8000 --reload

【讨论】:

小修改,做conn=""后,make conn.close() 这救了我!谢谢你。似乎这种 sleep 10 的情况应该在幕后处理得更好一些......【参考方案2】:

我遇到了这个问题,这只是因为我使用的是 ***。如果您使用的是 sshuttle 之类的东西,只需将其关闭即可。

【讨论】:

以上是关于Django 无法在 Docker 设置中连接到 Postgres的主要内容,如果未能解决你的问题,请参考以下文章

Delphi Firedac 在 docker 容器中连接到 MySQL

使用go webservice在docker中连接到mysql时连接被拒绝

Django无法连接到docker中的redis

在单独的 docker 容器 (AWS ECS) 中连接到 MongoDB

黑莓 MDS 模拟器 - 无法在模拟器中连接到互联网

无法使用 Node 在 iOS 模拟器中连接到 Mobile Safari