Django在Docker环境中无法连接到Postgres

11

我正在使用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
Mac版Docker为v1.13.1
docker-compose版本为v1.11.1

以下是日志链接:


请检查您的Docker日志,有可能是web容器在db容器之前启动了,因此依赖关系无法解析。 - Anomitra
1
我以为 depends_on: - db 会防止 web 容器在 db 容器之前启动,不是吗? - Steven Mercatante
奇怪的是,Web容器的Docker日志中没有任何内容。它在一开始就说“已连接到web_1、db_1”,然后只有来自“db_1”的一堆日志。 - Steven Mercatante
你说得完全正确,不过我几天前遇到了这个问题 - 当时我正在使用“链接”。无论如何,最好检查一下。你能否将日志附加到问题上,以便任何查看它的人都可以更好地理解情况? - Anomitra
不知道Django是否可以实现,但你需要让你的应用程序通过TCP/IP连接到PostgreSQL,而不是通过本地套接字连接。 - user2105103
我已经添加了日志。在执行 docker-compose builddocker-compose up 后,我开始收到 web 的日志。 - Steven Mercatante
2个回答

11

事实证明问题出在启动Django应用之前Postgres没有完全启动。只需等待几秒钟再启动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文件,其中包含我从这个示例中获取的函数。

#!/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 = "" 后,进行一个小的修改,加上 conn.close()。 - acarayol
这个救了我!谢谢。不过似乎这种需要睡眠10秒的情况应该在后台处理得更好一些... - pjames

0
我曾经遇到过这个问题,原因是我使用了 VPN。如果您正在使用像 sshuttle 这样的工具,请将其关闭。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接