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

Docker Compose部署Django时迁移出现django.db.utils.OperationalError

解决Docker Compose部署Django时无法解析Postgres主机名的问题

问题根源

你遇到的django.db.utils.OperationalError: could not translate host name "postgres" to address错误,核心原因是Docker镜像构建阶段无法访问Postgres服务容器:

  • Dockerfile中的RUN python3 manage.py makemigrate指令是在镜像构建时执行的,此时Postgres容器尚未启动,且构建环境不属于Docker Compose创建的noted-network网络,根本无法解析"postgres"这个服务名。
  • 只有容器运行阶段,app容器才会加入compose网络,才能通过服务名访问Postgres。

解决方案

将数据迁移和静态文件收集的操作,从镜像构建阶段移到容器启动阶段执行,具体步骤如下:

1. 修改Dockerfile

移除构建阶段的makemigrate和collectstatic指令,改用启动命令执行这些操作:

修改后的Dockerfile:

FROM python:3.10

WORKDIR /noted

COPY . .

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 

RUN pip install -r requirements/production.txt \
    && apt-get update \
    && apt-get -y install wkhtmltopdf \
    && apt-get -y autoclean

EXPOSE 8000

WORKDIR /noted/noted

# 移除构建阶段的迁移和静态文件收集命令
# RUN python3 manage.py makemigrate --settings=core.settings.production
# RUN manage.py collectstatic --noinput --settings=core.settings.production

# 启动容器时依次执行迁移、静态文件收集、启动Gunicorn
CMD ["sh", "-c", "python3 manage.py makemigrate --settings=core.settings.production && python3 manage.py collectstatic --noinput --settings=core.settings.production && gunicorn --bind 0.0.0.0:8000 core.wsgi"]

2. (可选)使用Entrypoint脚本优化(推荐)

如果需要更清晰的启动流程,可创建一个entrypoint脚本:

创建entrypoint.sh文件(放在项目根目录):

#!/bin/sh

# 执行自定义迁移命令
python3 manage.py makemigrate --settings=core.settings.production

# 收集静态文件(跳过确认)
python3 manage.py collectstatic --noinput --settings=core.settings.production

# 启动Gunicorn服务(exec让进程成为容器PID 1,保证信号传递正常)
exec gunicorn --bind 0.0.0.0:8000 core.wsgi

然后修改Dockerfile,添加脚本执行权限并设置为entrypoint:

FROM python:3.10

WORKDIR /noted

COPY . .

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 

RUN pip install -r requirements/production.txt \
    && apt-get update \
    && apt-get -y install wkhtmltopdf \
    && apt-get -y autoclean \
    && chmod +x /noted/entrypoint.sh  # 给脚本加执行权限

EXPOSE 8000

WORKDIR /noted/noted

ENTRYPOINT ["/noted/entrypoint.sh"]

3. 保留现有Docker Compose配置

你的docker-compose.yml中已经配置了depends_on并依赖Postgres的健康检查,这个配置是正确的,它会确保Postgres完全就绪后再启动app容器,避免启动时序问题。

验证修复

执行以下命令重新构建并启动服务:

docker compose down -v  # 清理旧容器和数据卷(可选)
docker compose up --build

此时app容器启动时会先执行数据迁移,再收集静态文件,最后启动Gunicorn,且能正常通过"postgres"服务名访问数据库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:58:09