Docker 容器开机自动启动的 5 种方法,总有一款适合你!
最近有小伙伴问我,服务器重启后 Docker 容器老是得手动启动,太麻烦了,有没有什么办法能让它自动起来?这问题问得好!说实话,我也踩过这个坑,服务器一重启,服务全挂了,还得半夜起来手动启动容器,那叫一个酸爽。
今天我就把常用的几种方法都整理出来,从最简单的到企业级方案都有,大家可以根据自己的实际情况选择。废话不多说,直接上干货!
最简单的方法:使用 --restart 策略
这个方法是我个人最推荐的,真的是简单粗暴又好用。你只需要在创建容器的时候加个参数就搞定了。
如果你是新建容器,直接这样:
docker run -d --name my-container --restart always nginx如果容器已经跑起来了,也没关系,一条命令就能补上:
docker update --restart always my-container这里有几个重启策略可以选:
no:不自动重启,这是默认值(所以默认情况下容器不会自动起来)on-failure[:max-retries]:只有当容器异常退出时才重启,你还能指定最多重试几次always:不管啥情况都重启,除非你手动 stop 它unless-stopped:这个也挺好用,自动重启但如果你手动停了就不动了
我个人最喜欢用 unless-stopped,平时自动启,我想停的时候就乖乖停着,不会在我重启服务器后又自己跑起来。
更稳定的选择:systemd 服务
如果是生产环境,我建议用 systemd 来管理,这样更规范也更可靠。虽然配置稍微复杂点,但好处是显而易见的。
首先创建一个服务文件:
sudo nano /etc/systemd/system/my-docker-container.service然后填入这些内容:
[Unit]
Description=My Docker Container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a my-container
ExecStop=/usr/bin/docker stop -t 2 my-container
[Install]
WantedBy=multi-user.target保存后执行这几条命令:
# 重新加载 systemd
sudo systemctl daemon-reload
# 设置开机自启
sudo systemctl enable my-docker-container.service
# 立即启动
sudo systemctl start my-docker-container.service
# 看看状态
sudo systemctl status my-docker-container.service配置好了之后,你就可以像管理其他系统服务一样管理 Docker 容器了,是不是感觉专业了很多?
如果你用 Docker Compose
很多项目用 Docker Compose 来编排多个容器,这种情况就更简单了,直接在 yaml 文件里配置就行:
version: '3'
services:
web:
image: nginx:latest
restart: always # 或者 unless-stopped
ports:
- "80:80"
db:
image: postgres:13
restart: on-failure:3 # 失败时最多重试3次
environment:
POSTGRES_PASSWORD: example然后正常启动就行:
docker-compose up -d如果还想配合 systemd(推荐),可以这样设置:
sudo systemctl enable docker-compose@your-project备选方案:crontab
这个方法说实话不太推荐,但如果前面方法都行不通,也可以拿来应急。
crontab -e加上这行:
@reboot sleep 5 && /usr/bin/docker start my-container意思就是系统重启后等 5 秒再启动容器,给 Docker 服务一点启动时间。
老派方法:update-rc.d
这是 Debian/Ubuntu 系统的古老方法,现在用的人不多了,但了解一下也没坏处。
先创建启动脚本:
sudo nano /etc/init.d/docker-my-container填入:
#!/bin/bash
case "$1" in
start)
docker start my-container
;;
stop)
docker stop my-container
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
;;
esac然后设置权限并启用:
sudo chmod +x /etc/init.d/docker-my-container
sudo update-rc.d docker-my-container defaults设置好了怎么验证?
设置完总得验证一下吧?可以用这个命令看看重启策略:
docker inspect my-container --format='{{.HostConfig.RestartPolicy.Name}}'然后测试一下重启:
# 只重启 Docker 服务
sudo systemctl restart docker
# 或者直接重启整个系统
sudo reboot
# 重启后检查容器状态
docker ps -a一些实战经验分享
根据我这几年的踩坑经验,给大家几个实用建议:
生产环境要这么配
双保险总是好的:
# Docker 层面设置重启策略
docker run -d --name app \
--restart unless-stopped \
--memory 512m \
--cpus 1.0 \
my-app:latest
# 系统层面加上监控
sudo systemctl enable docker-app-monitor.service加个监控脚本
有时候容器会莫名其妙挂掉,加个定时检查更安心:
cat > /usr/local/bin/check-docker.sh << 'EOF'
#!/bin/bash
if ! docker ps | grep -q "my-container"; then
docker start my-container
echo "$(date): Restarted my-container" >> /var/log/docker-monitor.log
fi
EOF
chmod +x /usr/local/bin/check-docker.sh
echo "* * * * * /usr/local/bin/check-docker.sh" | crontab -Docker 本身也要开机自启
别忘了 Docker 服务本身也得开机自启:
# 检查状态
sudo systemctl is-enabled docker
# 如果没启用就启用
sudo systemctl enable docker顺便优化下 Docker 配置:
sudo nano /etc/docker/daemon.加上这些配置:
{
"live-restore": true,
"log-driver": "-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}故障排查常用命令
出问题时这些命令会很有用:
# 看 Docker 日志
sudo journalctl -u docker.service
# 看容器日志
docker logs my-container
# 看启动顺序
systemd-analyze critical-chain
# 检查服务依赖
systemctl list-dependencies docker.service常见问题怎么解决
容器之间有依赖关系
如果你的容器得按顺序启动,Docker Compose 可以用 depends_on,或者写个启动脚本:
#!/bin/bash
docker start database
sleep 10
docker start webapp网络没就绪容器就启动了
可以在 systemd 服务里加个等待时间:
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/docker start my-container磁盘挂载没准备好
加上依赖配置:
[Unit]
Requires=local-fs.target
After=local-fs.target到底选哪种?
最后总结一下,不同场景用不同方案:
- 个人开发环境:直接用
--restart always或者--restart unless-stopped,简单省事 - 生产环境单容器:systemd 服务 + Docker 重启策略,双重保障
- 生产环境多容器:Docker Compose + systemd,专业规范
如果只想要最快速的解决方案,就这两条命令:
# 对现有容器
docker update --restart always 容器名
# 对新容器
docker run -d --restart always --name 容器名 镜像名搞定!以后服务器重启就不用再操心容器能不能自己起来了。希望这篇文章对你有帮助,有问题欢迎在评论区交流~