本文目录导读:

在Shell脚本中配置容器自动重启,主要有以下几种方法:
Docker容器重启策略(推荐)
在运行容器时指定
# 总是重启 docker run --restart=always -d nginx # 除非手动停止,否则总是重启 docker run --restart=unless-stopped -d nginx # 退出码非0时重启(最多重试3次) docker run --restart=on-failure:3 -d nginx # 不自动重启(默认) docker run --restart=no -d nginx
更新已存在容器的重启策略
docker update --restart=always container_name
Shell脚本实现自动重启
基础重启脚本
#!/bin/bash
# 监控并重启容器的脚本
CONTAINER_NAME="my-app"
MAX_RETRIES=5
RETRY_INTERVAL=10
restart_container() {
echo "[$(date)] 尝试重启容器: $CONTAINER_NAME"
# 停止并删除旧容器
docker stop $CONTAINER_NAME 2>/dev/null
docker rm $CONTAINER_NAME 2>/dev/null
# 重新启动容器
docker run -d --name $CONTAINER_NAME \
--restart=unless-stopped \
-p 8080:80 \
nginx:latest
# 检查是否启动成功
if [ $? -eq 0 ]; then
echo "[$(date)] 容器重启成功"
return 0
else
echo "[$(date)] 容器重启失败"
return 1
fi
}
# 检查容器状态并重启
for ((i=1; i<=MAX_RETRIES; i++)); do
if docker ps | grep -q $CONTAINER_NAME; then
echo "[$(date)] 容器运行正常"
break
else
echo "[$(date)] 容器未运行 (尝试 $i/$MAX_RETRIES)"
restart_container
if [ $? -eq 0 ]; then
break
fi
sleep $RETRY_INTERVAL
fi
done
带健康检查的重启脚本
#!/bin/bash
# 复杂重启脚本,包含健康检查
CONTAINER_NAME="my-app"
HEALTH_URL="http://localhost:8080/health"
RETRY_COUNT=3
RETRY_INTERVAL=5
check_health() {
local response=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL)
if [ "$response" == "200" ]; then
return 0
else
return 1
fi
}
restart_with_health_check() {
echo "[$(date)] 开始重启流程..."
# 停止旧容器
docker-compose down --remove-orphans 2>/dev/null
# 重新构建并启动
docker-compose up -d --build
# 等待服务启动
sleep 10
# 健康检查
for ((i=1; i<=RETRY_COUNT; i++)); do
if check_health; then
echo "[$(date)] 服务健康检查通过"
return 0
fi
echo "[$(date)] 健康检查失败 (尝试 $i/$RETRY_COUNT)"
sleep $RETRY_INTERVAL
done
echo "[$(date)] 服务启动失败,健康检查未通过"
return 1
}
# 主循环
while true; do
if ! docker ps | grep -q $CONTAINER_NAME; then
restart_with_health_check
fi
sleep 30 # 每30秒检查一次
done
使用cron实现定时重启
创建cron任务脚本
#!/bin/bash
# /usr/local/bin/docker-auto-restart.sh
CONTAINER_NAME=$1
RESTART_TIME=$(date +%H:%M)
log_message() {
echo "[$(date)] $1" >> /var/log/docker-restart.log
}
# 重启指定容器
restart_specific_container() {
local name=$1
log_message "计划重启容器: $name"
docker restart $name
if [ $? -eq 0 ]; then
log_message "容器 $name 重启成功"
else
log_message "容器 $name 重启失败"
fi
}
# 重启所有运行中的容器
restart_all_containers() {
log_message "开始计划重启所有容器"
docker ps -q | while read container_id; do
docker restart $container_id
log_message "容器 $container_id 已重启"
done
log_message "所有容器重启完成"
}
# 根据参数执行
case "$1" in
all)
restart_all_containers
;;
*)
if [ -n "$CONTAINER_NAME" ]; then
restart_specific_container $CONTAINER_NAME
else
echo "用法: $0 {container_name|all}"
exit 1
fi
;;
esac
配置crontab
# 编辑crontab crontab -e # 添加以下规则: # 每天凌晨2点重启特定容器 0 2 * * * /usr/local/bin/docker-auto-restart.sh my-app # 每6小时重启所有容器 0 */6 * * * /usr/local/bin/docker-auto-restart.sh all # 每天早上6点和下午6点重启 0 6,18 * * * /usr/local/bin/docker-auto-restart.sh my-app
使用systemd服务管理
创建systemd服务文件
# /etc/systemd/system/docker-monitor.service [Unit] Description=Docker Container Monitor and Auto Restart After=docker.service Requires=docker.service [Service] Type=simple ExecStart=/usr/local/bin/docker-monitor.sh Restart=always RestartSec=10 User=root [Install] WantedBy=multi-user.target
创建监控脚本
#!/bin/bash
# /usr/local/bin/docker-monitor.sh
# 监控的容器列表
CONTAINERS=("nginx" "mysql" "redis")
while true; do
for container in "${CONTAINERS[@]}"; do
if ! docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
echo "[$(date)] 容器 $container 未运行,尝试重启..."
docker start $container 2>/dev/null || docker run -d --name $container $container:latest
fi
done
sleep 60
done
Docker Compose自动重启
docker-compose.yml配置
version: '3.8'
services:
web:
image: nginx:latest
restart: always # 自动重启策略
ports:
- "8080:80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
app:
build: .
restart: unless-stopped
depends_on:
- db
environment:
- DB_HOST=db
db:
image: mysql:8.0
restart: on-failure:5 # 最多重启5次
environment:
MYSQL_ROOT_PASSWORD: password
最佳实践建议
- 使用Docker原生重启策略:优先使用
--restart=unless-stopped - 添加健康检查:避免容器启动失败但进程仍在运行
- 设置重试限制:防止无限重启导致资源浪费
- 记录日志:记录重启事件便于排查问题
- 监控和告警:配置监控系统及时发现重启异常
选择哪种方法取决于你的具体需求和环境复杂度。