Docker容器数据存储与恢复问题:Flask/Django应用重启后数据丢失
解决Docker Compose部署Flask/Django时重启后数据丢失的问题
嘿,我刚好碰到过一模一样的问题,来帮你捋清楚问题出在哪以及怎么解决。
你现在的核心问题是配置的Volume路径和应用实际存储数据的路径不匹配,虽然你加了Volume,但容器里真正存数据的地方根本没被挂载到持久化卷上,所以重启容器后,这些数据自然就跟着旧容器一起消失了。
问题分析
先拆解下你的配置:
- 你的
docker-compose.yml里挂载了db:/var/lib/tarkov_bot/data,但你的Dockerfile把代码都放到了/app目录,而且Flask/Django默认会把数据库、生成的静态文件存在当前工作目录(也就是/app)下,根本没用到/var/lib/tarkov_bot/data这个路径。这就相当于你给冰箱装了保鲜盒,但食物都放在餐桌上,冰箱完全起不到保鲜作用! - 另外,如果你的Dockerfile在构建时把本地的
database.db也打包进镜像了,就算后来挂载了卷,容器启动时镜像里的旧数据库文件也会覆盖卷里的内容,这也是个容易踩的坑。
解决方案
第一步:确认应用的数据存储路径
先搞清楚你的Flask应用里,SQLite数据库和静态文件到底存在哪里:
- 比如你的数据库文件可能是
/app/database.db,静态文件生成在/app/static目录下(这是Flask的默认路径)。
第二步:调整Volume配置,挂载正确的路径
根据你的实际路径,修改docker-compose.yml的volumes部分,这里给你两种常用方案:
方案1:使用命名卷(推荐,Docker会帮你管理存储)
把应用的实际数据目录挂载到命名卷:
version: '3.5' services: flask_app: container_name: flask_app build: context: . dockerfile: Dockerfile environment: - TBOT_SECRET_KEY='youwillneverguess' - TBOT_ADMIN_PASSWORD='qwerty' - TBOT_ADMIN_USERNAME='admin' ports: - "80:5000" restart: always volumes: # 挂载应用的数据库存储目录到命名卷db - db:/app/data # 如果有静态文件需要持久化,添加这一行 - static:/app/static volumes: db: static:
⚠️ 注意:如果你的数据库直接存在/app根目录(比如/app/database.db),那需要把挂载路径改成- db:/app,但这样会把整个/app目录挂载,可能会覆盖掉镜像里的代码,所以更推荐你在Flask代码里把数据库路径配置到/app/data这类子目录下,比如:
# Flask代码里的数据库配置示例 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////app/data/database.db'
方案2:使用宿主机目录挂载(方便直接查看和修改文件)
如果你想在宿主机上直接看到数据文件,可以用宿主机本地目录代替命名卷:
volumes: # 宿主机当前目录下的data文件夹映射到容器内的/app/data - ./data:/app/data # 宿主机当前目录下的static文件夹映射到容器内的/app/static - ./static:/app/static
然后在宿主机提前创建目录并设置权限(避免容器内进程没有写入权限):
mkdir -p ./data ./static chmod -R 775 ./data ./static
第三步:避免构建镜像时打包数据文件
创建一个.dockerignore文件,把数据目录、数据库文件排除在镜像构建之外,防止镜像里的旧文件覆盖卷里的新数据:
# .dockerignore 内容 data/ static/ database.db __pycache__/ *.pyc
第四步:验证修复效果
- 先清理旧的容器和卷(确保旧的错误配置被清除):
docker-compose down -v
- 重新构建并启动容器:
docker-compose up --build -d
- 往数据库里写点数据,上传几个静态文件,然后重启容器:
docker-compose restart
- 再检查数据和静态文件,应该就不会丢失了。
内容的提问来源于stack exchange,提问作者Paper Kid




