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

Systemd管理Docker容器重启失败求助(需保留容器内文件)

问题:用systemd管理Docker容器生命周期,保留容器内用户数据

需求与限制

  • 核心需求:执行docker kill或服务重启后,容器能自动恢复运行,且用户在容器内安装/复制的文件需保留
  • 限制条件:
    1. 禁止执行docker rm,避免删除容器文件系统导致数据丢失
    2. 不使用oneshot类型服务,便于追踪服务启动的真实状态
    3. 无法使用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>

已尝试方法及问题

  1. 编写容器管理脚本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
  1. 配套的新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状态的关键操作

  1. 重新加载systemd配置:
sudo systemctl daemon-reload
  1. 重启服务:
sudo systemctl restart app-container.service
  1. 验证状态:
sudo systemctl status app-container.service

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:37:31