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

Docker Compose部署Django+PostgreSQL环境:如何实现仅首次启动时自动初始化虚拟数据

自动完成Django首次启动初始化的方案

我来帮你搞定这个自动初始化的需求——要让服务首次启动时自动执行migrate和虚拟数据导入,后续启动跳过这些步骤,我们可以用自定义Docker Entrypoint脚本来实现,同时还能解决PostgreSQL服务就绪的问题(毕竟depends_on只保证容器启动,不代表数据库服务已经可用)。

第一步:写一个自定义Entrypoint脚本

在你的Django项目根目录下建个scripts文件夹,新建entrypoint.sh脚本,内容如下:

#!/bin/sh

# 先等PostgreSQL服务完全就绪,不然Django连不上数据库
echo "等着PostgreSQL启动好..."
while ! pg_isready -h postgresql -U postgres; do
  sleep 1
done
echo "PostgreSQL搞定了,可以继续了"

# 检查数据库里有没有迁移记录(判断是不是首次启动)
echo "看看要不要初始化..."
python -c "
import sys
from django.db import connection

try:
    # 查django_migrations表,存在的话说明已经迁移过了
    with connection.cursor() as cursor:
        cursor.execute('SELECT 1 FROM django_migrations LIMIT 1;')
    sys.exit(0)
except Exception:
    sys.exit(1)
"

if [ $? -ne 0 ]; then
    echo "第一次启动,先跑数据库迁移..."
    python manage.py migrate

    echo "导入虚拟数据..."
    python manage.py shell < useful_scripts/intialize_dummy_data.py

    echo "初始化全部搞定!"
else
    echo "不是第一次启动,跳过初始化步骤"
fi

# 最后启动Django服务,这里换成你实际用的启动命令就行
exec "$@"

然后给脚本加执行权限:

chmod +x scripts/entrypoint.sh

要是你的Django容器里没装pg_isready,可以用netcat替代(把pg_isready那行换成nc -z postgresql 5432),不过pg_isready更准确,要装的话就在Dockerfile里加一句RUN apt-get update && apt-get install -y postgresql-client(基于Debian/Ubuntu镜像的话)。

第二步:更新你的Django镜像Dockerfile

你需要修改构建django_image的Dockerfile,把这个entrypoint脚本加进去:

# 假设你用的是Python基础镜像
FROM python:3.9-slim

# 复制项目文件到容器里,路径自己调整
COPY . /app
WORKDIR /app

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 复制entrypoint脚本并加权限
COPY scripts/entrypoint.sh /app/scripts/entrypoint.sh
RUN chmod +x /app/scripts/entrypoint.sh

# 设置Entrypoint,这是关键
ENTRYPOINT ["/app/scripts/entrypoint.sh"]

# 默认启动命令,比如用runserver或者gunicorn,根据你的实际情况改
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

然后重新构建镜像:

docker build -t django_image .

第三步:调整docker-compose.yml

确保你的webapp服务用的是更新后的镜像,其他配置不用改太多:

version: "3.7"
services:
  postgresql:
    image: "postgres:13-alpine"
    restart: always
    volumes:
      - type: bind
        source: ./DO_NOT_DELETE_postgres_data
        target: /var/lib/postgresql/data
    environment:
      POSTGRES_DB: project
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: abc123
      PGDATA: "/var/lib/postgresql/data/pgdata"
    networks:
      - postgresql_network
  webapp:
    image: "django_image"
    depends_on:
      - postgresql
    ports:
      - 8000:8000
    networks:
      - postgresql_network
    # 这里不需要额外加command,因为Entrypoint和CMD已经帮你处理了
networks:
  postgresql_network:
    driver: bridge

第四步:测试一下

现在执行你的启动命令:

docker-compose -p torsha-single -f ./github/docker-compose.yml --project-directory ./FINAL up --build --force-recreate --remove-orphans

首次启动时,你会在日志里看到初始化的过程;之后再启动服务,就会自动跳过初始化,直接启动Django啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:42:47