使用Dockerfile制作镜像并且让容器开机自动执行脚本

一、目标
centos7.6下制作Dockerfile,用Dockerfile生成镜像,并且让生成的镜像自动自行预定义脚本。(无坑版)
本例拿nginx镜像做测试,让脚本自动实时刷新nginx的默认主页/usr/share/nginx/html/index.html内容(显示容器的主机名和时间)
二、平台
[root@kahn.xiao ~]# uname -r
3.10.0-957.el7.x86_64
[root@kahn.xiao ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
Docker版本:Docker version 19.03.5, build 633a0ea

三、前言
1.准备一个docker仓库私服harbor,私服地址https://harbor.hiibm.com。关于harbor的HTTPS私服搭建,参见另一篇帖子《Centos7笔记之Docker私有仓库Harbor安装配置》,该帖子未公开,有需要的私信。
四、开始制作
1.新建个文件夹,用于存放Dockerfile和脚本

mkdir -p /root/dockerfile/xnginx

2.制作脚本(用于自动产生默认的nginx主页)
vim /root/dockerfile/xnginx/autoCreateHtml2Nginx.sh chmod 777 /root/dockerfile/xnginx/autoCreateHtml2Nginx.sh

#!/usr/bin/env bash hostName=`hostname` nginx while true do shijian=`date "+%Y-%m-%d_%H:%M:%S"` cat > /usr/share/nginx/html/index.html <Hello Kahn,${hostName} - 锐客网 Hostname: ${hostName} Time: ${shijian} Author: Kahn.Xiao
EOF sleep 2 done

脚本解释:
获得主机名;
让容器执行命令nginx,以启动nginx程序?
while true死循环,目的是让网页不断的刷新
shijian获得容器当前时间,没特殊用途,只是想让你感觉网页有变化
持续生成主页/usr/share/nginx/html/index.html
sleep 2睡眠2秒,避免死循环造成内存溢出而导致容器崩溃
对于超级新手来讲,这里有个彩蛋,那就是nginx在循环外执行,也就是只执行一遍,为啥要开启容器执行一次nginx命令呢?最主要的原因刚才讲过了,那就是为了让nginx镜像产生的容器中的nginx程序能开机启动nginx程序,然鹅这并不是彩蛋。但仔细想想彩蛋是可以利用这种方式让容器自动自行任务,可以取代crontab的部分功能。
3.制作Dockerfile
vim /root/dockerfile/xnginx/Dockerfile

From harbor.hiibm.com/public/nginx:latest MAINTAINER The CentOS Project <37213690@qq.com>EXPOSE 80ADD autoCreateHtml2Nginx.sh /root/autoCreateHtml2Nginx.sh RUN chmod 777 /root/autoCreateHtml2Nginx.sh CMD ["/root/autoCreateHtml2Nginx.sh"]

注解:
制作镜像必须将文件名命名为Dockerfile;
From harbor.hiibm.com/public/nginx:latest 这是我事先拉取的镜像并打包放到了私服上了,完全可以写成From nginx。这样速度快。
EXPOSE 80 让容器暴露HTTP80端口
ADD autoCreateHtml2Nginx.sh /root/autoCreateHtml2Nginx.sh 生成镜像的时候把脚本丢到镜像的root目录下。
RUN chmod 777 /root/autoCreateHtml2Nginx.sh 给容器中的脚本赋权限
CMD ["/root/autoCreateHtml2Nginx.sh"] 容器开机执行命令(让容器开起来后就去执行我们预定义好的脚本)
4.使用Dockerfile生成镜像
docker build -t harbor.hiibm.com/public/xnginx:v1.5.20200306 .

注释:
harbor.hiibm.com/public/xnginx是镜像的名字,你可以随便写,并且也不一定非得带上斜线/
:v1.5.20200306 镜像的版本号,随意定,比如v1.0,再比如1.0,再比如1.0.0
特别提醒,别忘记构建命令最后有个符号点.,这代表当前目录。
顺利的话应该是在1分钟内生成镜像,就算时间稍长一点,那么屏幕也当会持续输出东西,而不是一直让你waiting,如果一直是waiting,那必定是有问题。
使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片


五、查看制作好的镜像,并推送到Harbor的Docker私有仓库上
1.查看制作的镜像
docker images |grep xnginx

使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片

2.将镜像推送到私服(可选)
docker login harbor.hiibm.com docker push harbor.hiibm.com/public/xnginx:v1.5.20200306

使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片

3.到Harbor上查看镜像
使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片


六、使用自己制作的镜像生成容器,并访问nginx主页
【使用Dockerfile制作镜像并且让容器开机自动执行脚本】1.使用镜像生成容器
docker run -d -p 37210:80 --name=xnginx15 harbor.hiibm.com/public/xnginx:v1.5.20200306

注释:
-d貌似是后台运行
-p是暴露端口
37210是主机端口
80是容器端口
--name=xnginx15是容器名字
harbor.hiibm.com/public/xnginx是镜像名
:v1.5.20200306是镜像版本号
使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片

2.查看容器是否正常运行
docker ps |grep nginx

使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片

可以看出容器已正常运行,而且端口也映射了。
如果使用docker ps没看到你的容器,那么就用docker ps -a看是否有,如果只有加参数-a才能看到,那你容器就没启动成功,很可能是镜像本身制作有问题。这时用docker logs <容器id>看详细错误信息。
3.访问容器主页,并验证最终结果。
啰嗦:前面生成容器的时候暴露的物理机端口是37210,那么我们就可以使用物理机ip+暴露端口号来访问容器的nginx。
比如我的:http://192.168.73.150:37210/
使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片

------------------------------------END----2020年3月6日15:23:50----------------------------------------------------
本帖写给刚入坑的朋友,本人也是刚玩linux不久,做这个东西废了断断续续的2天时间,网上搜的帖子到处是坑。这里总结一下分享出来。但你要知道写帖子容易,但写技术帖子+截图+注解真的耗时间。非常辛苦。
如果我的帖子能帮到你,我也希望得到你的支持,鼓励我写更多无坑的帖子,不胜感激。
使用Dockerfile制作镜像并且让容器开机自动执行脚本
文章图片

    推荐阅读