重启系统后Django Docker-Compose迁移未被识别,需重新执行求排查
问题根源与解决方案
你的问题核心在于systemd单元文件里的过度清理命令会彻底删除数据库持久化卷,导致手动迁移的数据在重启后完全丢失。下面详细拆解原因和修复方案:
为什么重启后迁移失效?
看你的ExecStartPre部分,这几个命令是罪魁祸首:
ExecStartPre=-/bin/bash -c 'docker volume rm $(docker volume ls -q)':这个命令会删除系统中所有Docker卷——包括你的Django数据库用来存储数据和迁移记录的卷。- 加上前面的
docker-compose down -v已经会删除当前服务关联的卷,后续的全局清理完全是画蛇添足,直接把你手动迁移后存在卷里的数据彻底清掉了。
当你手动执行迁移后,数据存在数据库卷中,但重启系统时,systemd会先执行这些清理命令,删掉卷,然后docker-compose up会创建一个全新的空卷,数据库回到初始状态,自然识别不到之前的迁移记录。
修复方案
1. 移除危险的全局清理命令(最优先)
修改你的systemd单元文件,只保留和当前服务相关的清理操作,删掉全局卷、容器、镜像的清理命令:
[Unit] Description=myservice Requires=docker.service After=docker.service [Service] Restart=always # 仅清理当前compose服务关联的旧容器(不删卷) ExecStartPre=/usr/local/bin/docker-compose -f my.yml down ExecStartPre=/usr/local/bin/docker-compose -f my.yml rm -f # 删掉下面这三个全局清理命令 # ExecStartPre=-/bin/bash -c 'docker volume rm $(docker volume ls -q)' # ExecStartPre=-/bin/bash -c 'docker rmi $(docker images | grep "<none>" | awk \'{print $3}\')' # ExecStartPre=-/bin/bash -c 'docker rm -v $(docker ps -aq)' ExecStart=/usr/local/bin/docker-compose -f my.yml up ExecStop=/usr/local/bin/docker-compose -f my.yml down [Install] WantedBy=multi-user.target
注意:我把down -v改成了down(不带-v参数),这样只会停止容器,不会删除持久化卷,你的数据库数据和迁移记录就会被保留。
2. 可选:自动执行迁移(避免手动操作)
如果你希望每次启动服务时自动执行迁移,不用手动跑命令,可以在ExecStart前添加迁移步骤,注意要等数据库就绪后再执行:
[Service] Restart=always # 先启动数据库容器 ExecStartPre=/usr/local/bin/docker-compose -f my.yml up -d db # 等待数据库就绪(这里以PostgreSQL为例,其他数据库请调整命令) ExecStartPre=/bin/bash -c 'until docker-compose -f my.yml exec -T db pg_isready -U postgres; do sleep 2; done' # 执行迁移 ExecStartPre=/usr/local/bin/docker-compose -f my.yml run --rm django python manage.py migrate # 启动所有服务 ExecStart=/usr/local/bin/docker-compose -f my.yml up # 其他配置保持不变...
重要提醒
全局清理Docker资源的命令(比如删除所有卷、所有停止的容器)非常危险,会影响系统中所有Docker服务,哪怕是和当前项目无关的服务也会被清理,绝对不要在生产环境使用,测试环境也要谨慎操作。
内容的提问来源于stack exchange,提问作者Narnik Gamarnik
相关产品推荐
相关产品推荐

