You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django+Docker-Compose指定db为数据库主机却连接localhost报错

问题

连接到位于"localhost"(127.0.0.1)、端口5432的服务器失败:连接被拒绝

明明在settings.py中直接指定了HOST为"db",为什么应用仍尝试连接localhost?

docker-compose.yml 配置

services:
    web-app:
        build: .
        ports:
            - "8000:8000"
        volumes:
            - ./myapp:/myapp

        command: >
            sh -c "python manage.py runserver 0:8000"

    db:
        image: postgres:13-alpine
        volumes:
            - ./myapp_data:/var/lib/postgresql/data/
        environment:
            - POSTGRES_USER=postgres
            - POSTGRES_PASSWORD=postgres
            - POSTGRES_DB=Test_overflow_db

settings.py 数据库配置

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

另外,之前碰到过类似错误:django.db.utils.OperationalError: connection to server at db ("172.20.0.2"), port 5432 failed: Connection refused,但做了一些操作后这个错误就没再出现了。

解决方案
  • 确认配置文件是否生效:你挂载了本地./myapp到容器内的/myapp,先检查容器里的settings.py是不是你修改的版本。进入容器执行cat /myapp/settings.py,看HOST字段是不是确实设为了db。有可能本地修改没同步,或者容器内有其他配置文件被优先加载。
  • 排查环境变量覆盖:Django会优先读取环境变量里的数据库配置,比如DATABASE_URL。如果这个变量设成了指向localhost的地址,会直接覆盖settings.py的配置。在容器里执行echo $DATABASE_URL,看看有没有这个变量,有的话要么删除要么改成正确的postgres://postgres:postgres@db:5432/Test_overflow_db。
  • 检查容器网络归属:默认docker-compose会给所有服务创建一个共享网络,但如果手动指定了网络,要确保web-app和db在同一个网络里。执行docker inspect web-app和docker inspect db,对比两者的NetworkSettings里的网络名称,不一致的话调整docker-compose.yml,把两个服务放到同一个网络中。
  • 清除缓存或重启容器:如果之前用localhost启动过应用,可能有旧进程残留,或者Django的配置缓存没更新。直接重启web-app容器:docker-compose restart web-app,或者在容器内运行python manage.py clearcache清除配置缓存。
  • 等待数据库服务就绪:虽然现在错误是连localhost,但也有可能是web-app启动时db还没完全就绪,触发了某些 fallback 逻辑。可以在web-app的command里加入等待脚本,比如用wait-for-it:
    command: >
        sh -c "wait-for-it db:5432 -- python manage.py runserver 0:8000"
    
    注意要先在Dockerfile里安装wait-for-it,或者用原生shell命令循环等待:
    command: >
        sh -c "until pg_isready -h db -p 5432 -U postgres; do sleep 1; done; python manage.py runserver 0:8000"
    
    这种方式需要容器里安装postgresql-client,可以在Dockerfile里添加RUN apk add --no-cache postgresql-client(因为用的是alpine镜像)。

内容的提问来源于stack exchange,提问作者SomeRandomDude111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:22:53