Systemd管理Docker容器重启失败求助(需保留容器内文件)
问题:用systemd管理Docker容器生命周期,保留容器内用户数据
需求与限制
- 核心需求:执行
docker kill或服务重启后,容器能自动恢复运行,且用户在容器内安装/复制的文件需保留 - 限制条件:
- 禁止执行
docker rm,避免删除容器文件系统导致数据丢失 - 不使用oneshot类型服务,便于追踪服务启动的真实状态
- 无法使用Docker卷,容器内已有可被用户修改的库文件
- 禁止执行
原有配置与报错
原有systemd服务配置
[Unit] Description=App Docker Container After=docker.service Requires=docker.service [Service] # Start the container only if it doesn't exist ExecStart= docker run --name app-container your-image' ExecStop=/usr/bin/docker stop app-container [Install] WantedBy=multi-user.target
启动失败报错
执行docker kill或systemctl stop app-container.service && systemctl start app-container.service后,服务启动失败,日志报错:
Sep 24 02:09:21 vm docker[27856]: docker: Error response from daemon: Conflict. The container name "/app-container" is already in use by contai>
已尝试方法及问题
- 编写容器管理脚本
run_container.sh:
#!/bin/bash # Check if the container exists if docker ps -a --filter name=app-container | grep -q app-container; then # Check if the container is running if docker ps --filter name=app-container | grep -q app-container; then echo "Container app-container is already running." else echo "Restarting stopped container app-container." docker restart app-container fi else echo "Starting a new app container." docker run \ docker-image fi
- 配套的新systemd服务配置:
[Unit] Description=app container Requires=docker.service After=docker.service [Service] ExecStop=/usr/bin/docker stop app-container ExecStart=/var/lib/run_container.sh Restart=always RestartSec=1
遇到的问题
执行sudo systemctl status app-service.service时,服务始终处于deactivating状态。
解决方案建议
方案1:优化脚本与systemd配置
修复后的run_container.sh脚本
#!/bin/bash set -e CONTAINER_NAME="app-container" IMAGE_NAME="your-image" # 用docker inspect更可靠地检查容器是否存在 if docker inspect "$CONTAINER_NAME" &>/dev/null; then # 检查容器是否处于运行状态 if ! docker ps --filter "name=$CONTAINER_NAME" --filter "status=running" &>/dev/null; then echo "Restarting stopped container: $CONTAINER_NAME" docker start "$CONTAINER_NAME" fi else echo "Creating new container and starting: $CONTAINER_NAME" # 启动容器时指定名称,且保持前台运行(适配systemd监控) docker run --name "$CONTAINER_NAME" "$IMAGE_NAME" fi # 保持脚本运行,监听容器停止事件,避免systemd误判服务退出 docker wait "$CONTAINER_NAME"
优化后的systemd服务配置(/etc/systemd/system/app-container.service)
[Unit] Description=App Docker Container Requires=docker.service After=docker.service [Service] Type=exec ExecStart=/var/lib/run_container.sh ExecStop=/usr/bin/docker stop app-container # 容器或服务意外退出时自动重启 Restart=always RestartSec=3 # 确保脚本拥有执行权限 PermissionsStartOnly=true ExecStartPre=/bin/chmod +x /var/lib/run_container.sh [Install] WantedBy=multi-user.target
方案2:无需脚本,直接用systemd内置指令处理
[Unit] Description=App Docker Container Requires=docker.service After=docker.service [Service] # 启动前检查容器状态:存在则启动,不存在则创建 ExecStartPre=/bin/sh -c 'if docker inspect app-container &>/dev/null; then docker start app-container; else docker run --name app-container your-image; fi' ExecStop=/usr/bin/docker stop app-container Restart=always RestartSec=3 Type=simple [Install] WantedBy=multi-user.target
解决deactivating状态的关键操作
- 重新加载systemd配置:
sudo systemctl daemon-reload
- 重启服务:
sudo systemctl restart app-container.service
- 验证状态:
sudo systemctl status app-container.service
内容的提问来源于stack exchange,提问作者californian
相关产品推荐
相关产品推荐

