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

Docker部署Django+PostgreSQL:迁移失败及表不存在问题解决

解决Docker环境下Django数据库迁移问题

问题原因

  • Dockerfile中直接添加makemigrations/migrate命令时,web容器启动阶段PostgreSQL服务(db容器)尚未就绪或网络未连通,导致无法解析db主机名。
  • 不添加迁移命令时,数据库未执行迁移操作,Django找不到对应的数据表,抛出ProgrammingError。

解决方案

方法1:通过docker-compose exec手动执行迁移(推荐)

无需修改现有配置,灵活可控:

  1. 启动所有服务并后台运行:
    docker-compose up -d
    
  2. 等待PostgreSQL完全就绪(查看日志确认状态):
    docker-compose logs db
    
    当日志出现database system is ready to accept connections时,说明数据库已准备完毕。
  3. 执行迁移命令:
    docker-compose exec web python manage.py makemigrations
    docker-compose exec web python manage.py migrate
    

方法2:在Dockerfile中添加等待脚本,自动执行迁移

适合需要容器启动时自动完成迁移的场景:

  1. 在项目根目录创建wait_for_db.sh脚本:
    #!/bin/bash
    set -e
    
    host="$1"
    shift
    cmd="$@"
    
    # 轮询等待PostgreSQL端口就绪
    until pg_isready -h "$host" -p 5432 -U "$POSTGRES_USER"; do
      >&2 echo "Postgres 未就绪,等待2秒..."
      sleep 2
    done
    
    >&2 echo "Postgres 已就绪,执行命令"
    exec $cmd
    
  2. 修改Dockerfile,集成脚本并更新启动命令:
    # 复制等待脚本到容器内
    COPY wait_for_db.sh /wait_for_db.sh
    RUN chmod +x /wait_for_db.sh
    
    # 等待db服务就绪后,依次执行迁移和启动服务
    CMD ["/wait_for_db.sh", "db", "--", "sh", "-c", "python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"]
    
  3. 确保docker-compose.yml配置匹配:
    services:
      db:
        image: postgres:15
        environment:
          POSTGRES_DB: your_db_name
          POSTGRES_USER: your_db_user
          POSTGRES_PASSWORD: your_db_pass
        volumes:
          - postgres_data:/var/lib/postgresql/data/
      web:
        build: .
        volumes:
          - .:/code
        ports:
          - "8000:8000"
        depends_on:
          - db
        environment:
          POSTGRES_NAME: your_db_name
          POSTGRES_USER: your_db_user
          POSTGRES_PASSWORD: your_db_pass
    volumes:
      postgres_data:
    

方法3:本地连接Docker中的数据库执行迁移

适合习惯在本地开发环境操作的场景:

  1. 在docker-compose.yml的db服务中添加端口映射:
    ports:
      - "5432:5432"
    
  2. 临时修改Django的settings.py数据库配置:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('POSTGRES_NAME'),
            'USER': os.environ.get('POSTGRES_USER'),
            'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
            'HOST': 'localhost',  # 临时改为本地地址
            'PORT': 5432,
        }
    }
    
  3. 本地执行迁移命令:
    python manage.py makemigrations
    python manage.py migrate
    
  4. 将settings.py中的HOST改回db,重启web容器:
    docker-compose restart web
    

关键配置检查

  • 确认Django的settings.py中数据库HOST与docker-compose.yml中db服务名(db)一致。
  • 确保web和db服务的数据库环境变量(名称、用户、密码)完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:57:30