起因
系统每次打漏洞补丁都会进行服务器重启,系统重要性比较低,没有自动化自愈工具,只有纯docker的工具,因此只能通过编写脚本进行自启动docker以及docker内的应用
解决方法
- 通过shell脚本的方式,可以把脚本加到rc.local或crontab中
#启动容器
docker run -itd --env TZ="Asia/Shanghai" --env LC_ALL=en_GB.utf8 --net=host -v /var/www/web:/home test:v1.0 /bin/sh
#启动容器内的应用
docker exec -itd `docker ps |grep test:v1.0 |awk '{print $1}'` /bin/sh -c 'sh /home/startApp.sh'
--env TZ="Asia/Shanghai"
是为了解决容器默认时区的问题--env LC_ALL=en_GB.utf8
是为了解决容器默认字符集的问题--net=host
是为了解决容器端口映射的问题,如果端口固定可用-p代替-v /var/www/web:/home
是为了解决容器路径映射的问题-c 'sh /home/startApp.sh'
是启动容器内的应用,建议把容器内所有需要启动的应用写到一个脚本中-d
这个是整个方案的核心,让容器后台启动,类似shell脚本中的&,如果没有会导致容器启动后自动退出
遇到的问题
- 没加-d导致容器没起来
- 误用shell的&方式启动容器,结果输出
the input device is not a TTY EOF
,容器也没起来
- 通过保存为新的镜像
容器内修改后commit打包,一劳永逸:
- docker container commit [containerID] [REPOSITORY[:TAG]]
- docker container export [containerID] > path
- 通过dockerfile的方式,利用CMD或ENTRYPOINT
CMD /home/startApp.sh
扩展知识
CMD和ENTRYPOINT的区别:功能类似但有一些区别,CMD会被docker run的参数覆盖,而ENTRYPOINT不会
CMD三种用法
- CMD [“executable”,“param1”,“param2”] (exec方式,运行一个可执行的文件并提供参数,推荐方式)
- CMD [“param1”,“param2”] (as default parameters to ENTRYPOINT)(为ENTRYPOINT指定参数)
- CMD command param1 param2 (shell方式,是以”/bin/sh -c”的方法执行的命令)
ENTRYPOINT 两种用法
- ENTRYPOINT [“executable”, “param1”, “param2”] (exec方式,推荐方式)
- ENTRYPOINT command param1 param2 (shell方式,会屏蔽docker run后面的命令和参数)