如何设置Docker container自动重启
Contents
零 问题痛点
之前运行好好的容器,因为意外情况如断电导致服务器重启之后,容器不会像我们期望的那样自动启动,导致容器提供的服务不可用,这时候需要人为介入去排查分析并手工启动容器。
那么,有没有比较优雅一点儿的方式,即使Docker服务需要被重启、服务器断电重启之后,Docker container可以自动启动,而不需要人为接管呢?
答案是:有。
一 问题原因
原因是我们的container在启动时,没有被加上—restart=always|unless-stopped等选项。也就意味着,容器一旦停止运行,无论什么原因造成它停止运行的,它就保持停止状态,不会自动重启。这是container的默认启动规则。
反之,如果container在启动时,有加上—restart=重启规则的选项的话,容器就会根据该重启规则来执行重启。
二 解决方案
具体处理起来得分两种情况:
- 如果container是通过docker命令创建并启动的,我们可以通过执行 docker update —restart=always|unless-stopped container_id|container_name,来修改容器的重启策略;
- 如果container是通过docker-compose创建并启动,除了要通过执行 docker update —restart=always|unless-stopped container_id|container_name,来修改容器的重启策略,还需要修改对应的docker-compose.yaml文件,并且执行docker-compose up -d来重启container;
💡 为什么需要执行docker-compose up -d来重启container? 因为,Docker compose的运行机制,是通过yaml文件的声明式配置来实现的。我们虽然手工修改了运行中的container,给它加上了—restart=always。为了防止,将来有人通过docker-compose up -d来更新发布启动该容器,导致重启策略被覆盖。所以,我们才执行这一步修改yaml文件,并重启容器。这在生产环境下需要斟酌考虑容器重启对业务的影响。
三 动手实践Docker容器置为自动重启
前两天周末,因为隔壁公司装修原因,导致机房线路被意外断电了。服务器断电重新启动之后,当前服务器上,Docker服务自动启动了,可是container没有启动:
[root@server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ee762685009 portainer/portainer-ce:latest "/portainer" 2 years ago Up 18 hours 0.0.0.0:8000->8000/tcp, 0.0.0.0:9443->9443/tcp, 9000/tcp portainer
7b91f981cd5c nginx "/docker-entrypoint.…" 2 years ago Exited (255) 18 hours ago 0.0.0.0:80->80/tcp, 0.0.0.0:2222->2222/tcp nginx-80
0990ea726eb7 redis "docker-entrypoint.s…" 3 years ago Exited (255) 18 hours ago 0.0.0.0:6379->6379/tcp redis-test
9488060c69b7 jira-agent-sso "/tini -- /entrypoin…" 4 years ago Exited (255) 18 hours ago 0.0.0.0:8080->8080/tcp celoan-jira
[root@server ~]# docker start celoan-jira
celoan-jira
[root@server ~]# docker start nginx-80
nginx-80
[root@server ~]# docker inspect nginx-80 --format='{{.HostConfig.RestartPolicy.Name}}'
[root@server ~]# docker inspect celoan-jira --format='{{.HostConfig.RestartPolicy.Name}}'
[root@server ~]# docker update --restart=always celoan-jira
celoan-jira
[root@server ~]# docker update --restart=always nginx-80
nginx-80
[root@server ~]# docker inspect celoan-jira --format='{{.HostConfig.RestartPolicy.Name}}'
always
[root@server ~]# docker inspect nginx-80 --format='{{.HostConfig.RestartPolicy.Name}}'
always
[root@server ~]# hostname -I
10.0.9.33 192.168.103.1 192.168.107.1 192.168.102.1 172.17.0.1
[root@server ~]#
需要手工执行,docker start xxxx;
有没有更优雅一点儿的方法呢?当服务器掉电重启之后,Docker服务自动启动之前,之前运行的container也会自动启动?
答案是有的。我们可以通过docker update —restart=always container-name|container-id
如上:docker update –restart=always celoan-jira
当然,在设置container自动重启之前,我们可以通过docker inspect container-name|container-id来查看该容器是否设置了自动重启。或者一步到位,通过执行
docker inspect container-name|container-id –format='{{.HostConfig.RestartPolicy.Name}}’
设置了container自动启动之后,我们可以再次通过该命令来校验设置是否生效。
此时,由于nginx-80和celoan-jira这2个container是通过docker-compose来启动并运行的,我们除了通过docker update —restart=always container-name|container-id修改了该container的重启策略之外,我们还得修改它的docker-compose.yaml文件,并且要执行docker-compose up -d;命令。
1 修改NGINX容器的docker-compose.yaml配置文件restart=always
修改之前:
[root@server nginx]# pwd
/root/docker/nginx
[root@server nginx]# ll
total 12
drwxr-xr-x. 2 root root 4096 Jan 12 09:44 conf.d
-rw-r--r--. 1 root root 557 May 29 2023 docker-compose.yaml
-rw-r--r--. 1 root root 1080 Oct 31 2023 nginx.conf
[root@server nginx]# cat docker-compose.yaml
version: '2'
services:
mysql:
image: nginx
container_name: nginx-80
ports:
- "80:80"
- "2222:2222"
volumes:
- /root/docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- /root/docker/nginx/conf.d:/etc/nginx/conf.d
- /root/prototype:/home/nginx/prototype
- /data/prototype/web:/home/nginx/prototype-web
- /home/nginx/web:/home/nginx/web
networks:
- nginx-network
networks:
nginx-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.102.0/24
[root@server nginx]#
修改之后:
[root@server nginx]# cat docker-compose.yaml
version: '2'
services:
mysql:
image: nginx
container_name: nginx-80
ports:
- "80:80"
- "2222:2222"
restart: always
volumes:
- /root/docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- /root/docker/nginx/conf.d:/etc/nginx/conf.d
- /root/prototype:/home/nginx/prototype
- /data/prototype/web:/home/nginx/prototype-web
- /home/nginx/web:/home/nginx/web
networks:
- nginx-network
networks:
nginx-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.102.0/24
[root@server nginx]#
执行docker compose up -d 使之生效
[root@server nginx]# ll
total 12
drwxr-xr-x. 2 root root 4096 Jan 12 09:44 conf.d
-rw-r--r--. 1 root root 577 Jan 30 05:57 docker-compose.yaml
-rw-r--r--. 1 root root 1080 Oct 31 2023 nginx.conf
[root@server nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ee762685009 portainer/portainer-ce:latest "/portainer" 2 years ago Up 4 days 0.0.0.0:8000->8000/tcp, 0.0.0.0:9443->9443/tcp, 9000/tcp portainer
7b91f981cd5c nginx "/docker-entrypoint.…" 2 years ago Up 3 days 0.0.0.0:80->80/tcp, 0.0.0.0:2222->2222/tcp nginx-80
9488060c69b7 jira-agent-sso "/tini -- /entrypoin…" 4 years ago Up 3 days 0.0.0.0:8080->8080/tcp celoan-jira
[root@server nginx]# docker-compose up -d
Recreating nginx-80 ... done
[root@server nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d7384708862 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:2222->2222/tcp nginx-80
7ee762685009 portainer/portainer-ce:latest "/portainer" 2 years ago Up 4 days 0.0.0.0:8000->8000/tcp, 0.0.0.0:9443->9443/tcp, 9000/tcp portainer
9488060c69b7 jira-agent-sso "/tini -- /entrypoin…" 4 years ago Up 3 days 0.0.0.0:8080->8080/tcp celoan-jira
[root@server nginx]#
2 处理celoan-jira容器的restart=always
修改之前:
[root@server jira]# pwd
/root/docker/jira
[root@server jira]# ll
total 16
-rw-r--r--. 1 root root 624 May 18 2021 crowd.properties
-rw-r--r--. 1 root root 700 May 18 2021 docker-compose.yml
-rw-r--r--. 1 root root 1940 Mar 22 2021 docker-compose.yml.bak
-rw-r--r--. 1 root root 255 May 18 2021 Dockerfile
[root@server jira]# cat docker-compose.yml
version: '2'
services:
jira:
image: jira-agent-sso
container_name: celoan-jira
environment:
- JVM_MINIMUM_MEMORY=4096m
- JVM_MAXIMUM_MEMORY=6144m
- ATL_PROXY_NAME=jira.celoan.opt
- ATL_PROXY_PORT=80
ports:
- "8080:8080"
volumes:
- /etc/localtime:/etc/localtime
- /data/atlassian/jira-data:/var/atlassian/application-data/jira
extra_hosts:
- "jira.celoan.opt:10.0.9.33"
- "wiki.celoan.opt:10.0.9.33"
- "crowd.celoan.opt:10.0.9.33"
networks:
- celoan-atlassian-network
networks:
celoan-atlassian-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.107.0/24
[root@server jira]#
修改之后,并docker-compose up -d使之生效:
如果docker-compose.yml配置文件,语法错误,导致不生效,docker-compose up -d会提示,并且不会重启容器:
[root@server jira]# ll
total 16
-rw-r--r--. 1 root root 624 May 18 2021 crowd.properties
-rw-r--r--. 1 root root 719 Jan 30 06:01 docker-compose.yml
-rw-r--r--. 1 root root 1940 Mar 22 2021 docker-compose.yml.bak
-rw-r--r--. 1 root root 255 May 18 2021 Dockerfile
[root@server jira]# cat docker-compose.yml
version: '2'
services:
jira:
image: jira-agent-sso
container_name: celoan-jira
environment:
- JVM_MINIMUM_MEMORY=4096m
- JVM_MAXIMUM_MEMORY=6144m
- ATL_PROXY_NAME=jira.celoan.opt
- ATL_PROXY_PORT=80
ports:
- "8080:8080"
retart: always
volumes:
- /etc/localtime:/etc/localtime
- /data/atlassian/jira-data:/var/atlassian/application-data/jira
extra_hosts:
- "jira.celoan.opt:10.0.9.33"
- "wiki.celoan.opt:10.0.9.33"
- "crowd.celoan.opt:10.0.9.33"
networks:
- celoan-atlassian-network
networks:
celoan-atlassian-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.107.0/24
[root@server jira]# docker-compose up -d
ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for services.jira: 'retart'
[root@server jira]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d7384708862 nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:2222->2222/tcp nginx-80
7ee762685009 portainer/portainer-ce:latest "/portainer" 2 years ago Up 4 days 0.0.0.0:8000->8000/tcp, 0.0.0.0:9443->9443/tcp, 9000/tcp portainer
9488060c69b7 jira-agent-sso "/tini -- /entrypoin…" 4 years ago Up 3 days 0.0.0.0:8080->8080/tcp celoan-jira
[root@server jira]#
再次修改,并使之生效:
[root@server jira]# cat docker-compose.yml
version: '2'
services:
jira:
image: jira-agent-sso
container_name: celoan-jira
environment:
- JVM_MINIMUM_MEMORY=4096m
- JVM_MAXIMUM_MEMORY=6144m
- ATL_PROXY_NAME=jira.celoan.opt
- ATL_PROXY_PORT=80
ports:
- "8080:8080"
restart: always
volumes:
- /etc/localtime:/etc/localtime
- /data/atlassian/jira-data:/var/atlassian/application-data/jira
extra_hosts:
- "jira.celoan.opt:10.0.9.33"
- "wiki.celoan.opt:10.0.9.33"
- "crowd.celoan.opt:10.0.9.33"
networks:
- celoan-atlassian-network
networks:
celoan-atlassian-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.107.0/24
[root@server jira]# docker-compose up -d
Recreating celoan-jira ... done
[root@server jira]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
270b38034909 jira-agent-sso "/tini -- /entrypoin…" 25 seconds ago Up 24 seconds 0.0.0.0:8080->8080/tcp celoan-jira
7d7384708862 nginx "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:2222->2222/tcp nginx-80
7ee762685009 portainer/portainer-ce:latest "/portainer" 2 years ago Up 4 days 0.0.0.0:8000->8000/tcp, 0.0.0.0:9443->9443/tcp, 9000/tcp portainer
[root@server jira]#
四 补充说明
1 常见的重启策略说明
我们可以根据实际需求选择不同的参数:
| 参数 | 说明 |
| no | 默认值。容器退出后不重启。 |
| always | 只要容器退出(无论是因为进程崩溃还是 Docker 服务重启),就总是重启。 |
| unless-stopped | 类似于 always,但如果容器是被你手动停止的,那么在 Docker 服务重启后,它不会自动启动。 |
| on-failure | 仅在容器由于非零退出代码(即运行出错)而退出时才重启。 |
2 如何检查是否设置成功?
你可以通过以下命令查看容器的详细状态,确认 RestartPolicy 部分:
docker inspect <容器ID或容器名> --format='{{.HostConfig.RestartPolicy.Name}}'
温馨提示:
如果你的容器是使用 Docker Compose 管理的,你需要在 yaml 文件中的服务节点下添加 restart: always,然后重新执行 docker-compose up -d 即可生效。