Django+Docker-Compose环境下migrate执行失败的问题求助
问题解决:Docker + Django + PostgreSQL 数据库表不存在与连接失败问题
问题背景
配置了Django环境的Dockerfile和包含Django、PostgreSQL的docker-compose.yml:
- 首次执行
sudo docker-compose build(Dockerfile未加makemigrations和migrate),构建成功但运行时报错:
relation "learning_student" does not exist
LINE 1: ...t"."description", "learning_student"."image" FROM "learning_...
- 在Dockerfile中添加
makemigrations和migrate命令后,再次构建出现连接错误:
django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known
配置文件展示
settings.py 数据库配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'example name', 'USER': 'example user', 'PASSWORD': 'example password', 'HOST': 'db', 'PORT': '5432', } }
Dockerfile
FROM python:3.11 WORKDIR /app ENV PYTHONUNBUFFERED 1 ENV DJANGO_SETTINGS_MODULE=server.settings COPY requirements/prod.txt requirements/prod.txt RUN pip install --no-cache-dir -r requirements/prod.txt COPY . . EXPOSE 8000 # RUN python3 manage.py makemigrations RUN python3 manage.py migrate CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
docker-compose.yml
services: django: image: auralab-django:latest container_name: auralab-django build: context: ./auralab dockerfile: Dockerfile volumes: - ./auralab:/app ports: - "8000:8000" command: ["python3", "manage.py", "runserver", "0.0.0.0:8000"] depends_on: - db environment: - DATABASE_URL=postgres://example_user:example_password@db:5432/auralab db: image: postgres:13 container_name: auralab-db environment: POSTGRES_DB: auralab POSTGRES_USER: admin POSTGRES_PASSWORD: admin ports: - "5432:5432"
核心问题分析
- 构建阶段执行migrate错误:Docker镜像构建时,db服务还未启动,docker-compose的网络也未建立,无法解析
db主机名。 - 数据库配置不统一:settings.py里的数据库名称、用户、密码,和docker-compose中DATABASE_URL、postgres服务的环境变量完全不匹配。
- depends_on的局限性:它只保证db服务先启动,不保证postgres完全就绪可连接。
解决方案
1. 移除Dockerfile中的migrate命令
构建阶段不能访问数据库服务,删掉RUN python3 manage.py migrate:
FROM python:3.11 WORKDIR /app ENV PYTHONUNBUFFERED 1 ENV DJANGO_SETTINGS_MODULE=server.settings COPY requirements/prod.txt requirements/prod.txt RUN pip install --no-cache-dir -r requirements/prod.txt COPY . . EXPOSE 8000 CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
2. 统一所有数据库配置
确保各配置项完全一致:
- 修改settings.py:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'auralab', 'USER': 'admin', 'PASSWORD': 'admin', 'HOST': 'db', 'PORT': '5432', } }
- 修改docker-compose.yml中django服务的环境变量:
environment: - DATABASE_URL=postgres://admin:admin@db:5432/auralab
3. 容器启动时执行数据库迁移
推荐用entrypoint脚本处理,确保等待postgres就绪后再执行迁移:
- 在Django项目根目录创建
entrypoint.sh:
#!/bin/sh # 等待PostgreSQL服务完全就绪 until pg_isready -h db -p 5432 -U admin; do echo "等待PostgreSQL启动..." sleep 2 done # 执行迁移 python manage.py makemigrations python manage.py migrate # 启动Django服务 exec "$@"
- 给脚本加执行权限:
chmod +x entrypoint.sh - 修改Dockerfile添加entrypoint:
# ... 原有内容 ... COPY entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh ENTRYPOINT ["/app/entrypoint.sh"] CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
如果嫌脚本麻烦,也可以直接在docker-compose的command中执行(但不保证数据库就绪,可能偶发失败):
command: > sh -c "python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
4. 重新构建运行
sudo docker-compose down sudo docker-compose build sudo docker-compose up
内容的提问来源于stack exchange,提问作者Zura Begadze
相关产品推荐
相关产品推荐

