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
相关产品推荐
相关产品推荐

