您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
08-Dockerfile详解
发布时间:2020-09-19 19:15:55编辑:雪饮阅读()
CMD的第一种用法
制作一个镜像
[root@localhost ~]# mkdir img2
[root@localhost ~]# cd img2
[root@localhost img2]# vi Dockerfile
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
这里有几点需要说明下:
LABEL这里也类似之前标记作者信息的,只是新版本后主推这个,以前那个author会被废弃的。而这里CMD则指定了默认容器运行在httpd上而不是shell上,这里的RUN则在镜像build过程中就创建httpd服务所需要的目录及文件。
然后我们就执行build命令build成功后我们可以不用运行容器也能直接查看镜像inspect的一些信息。
[root@localhost img2]# docker image inspect tinyhttpd:v0.2-1
[
{
"Id": "sha256:06b6922a8b6cd981bfc6c0724bd2e406bc71d9d4e62a304b084ce023d0688b3e",
"RepoTags": [
"tinyhttpd:v0.2-1"
],
"RepoDigests": [],
"Parent": "sha256:a2d0704a06f8fbc071218c31d6c352ae97ddb211d73e4f846873cb0b626bcf1f",
"Comment": "",
"Created": "2020-09-19T07:33:05.055926581Z",
"Container": "5d1322564bd5015cce43962b33916417e8f39af742a90763087adbbcd2df2e77",
"ContainerConfig": {
"Hostname": "c8379f2b8ef0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"WEB_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/sh\" \"-c\" \"/bin/httpd -f -h ${WEB_DOC_ROOT}\"]"
],
"ArgsEscaped": true,
"Image": "sha256:a2d0704a06f8fbc071218c31d6c352ae97ddb211d73e4f846873cb0b626bcf1f",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {
"app": "httpd",
"maintainer": "MageEdu <mage@magedu.com>"
}
},
"DockerVersion": "1.13.1",
"Author": "",
"Config": {
"Hostname": "c8379f2b8ef0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"WEB_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/sh",
"-c",
"/bin/httpd -f -h ${WEB_DOC_ROOT}"
],
"ArgsEscaped": true,
"Image": "sha256:a2d0704a06f8fbc071218c31d6c352ae97ddb211d73e4f846873cb0b626bcf1f",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {
"app": "httpd",
"maintainer": "MageEdu <mage@magedu.com>"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 1223564,
"VirtualSize": 1223564,
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/c85fc5ddc2b05c93c6b2682475a635ef62a7d615bafe9b740e81b969d6e6167d/diff",
"MergedDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/merged",
"UpperDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/diff",
"WorkDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:514c3a3e64d4ebf15f482c9e8909d130bcd53bcc452f0225b0a04744de7b8c43",
"sha256:8c9b7be899eed8473728ff3f0fa24e5dda21c5467d074bc5f9409deb82fb1efd"
]
}
}
]
我们可以看到inpect中的CMD已经成功被我们弄上了。
我们尝试在该镜像下运行容器
[root@localhost img2]# docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-1
会发现一直卡在这里,既使我们使用了-it,但因为刚才我们CMD默认指定的命令是httpd而不是默认的bash,所以这里是没有交互可言的,所以就卡咯。
但我们仍旧可以看到该容器的进程是存在的
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3eaf01be54d0 tinyhttpd:v0.2-1 "/bin/sh -c '/bin/..." 2 minutes ago Up 2 minutes tinyweb2
但我们仍然可以这样
[root@localhost ~]# docker exec -it tinyweb2 /bin/sh
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/httpd -f -h /data/web/html/
6 root 0:00 /bin/sh
11 root 0:00 ps
/ #
但是这里你会发现httpd的pid竟然是1,在Linux中除了init进程以外其它进程的pid不可能为1的。。。
CMD的第二种用法
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
CMD "/bin/httpd" "-f" "-h ${WEB_DOC_ROOT}"
然后经过build后,我们尝试运行会发现下面的错误
[root@localhost img2]# docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-2
httpd: can't change directory to ' /data/web/html/': No such file or directory
这是因为该种方式不会做为shell的子进程运行,所以才会报错。
但如果手动指定运行shell
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
然后再次经过build后,尝试运行就成功了
[root@localhost img2]# docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-3
但我们查看进程中并没有我们刚才运行的这个容器
[root@localhost img2]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
54f1552ac4db busybox "sh" 6 days ago Exited (137) 6 days ago nginx
1eee1a72a5da busybox "sh" 6 days ago Exited (137) 6 days ago infracon
cde2576aca13 busybox:latest "sh" 12 days ago Exited (0) 12 days ago t1
54430c82f146 foe/httpd:v0.1-1 "sh" 13 days ago Exited (137) 13 days ago t3
1b767a128e0b towards/httpd:v0.2 "/bin/httpd -f -h ..." 13 days ago Exited (137) 13 days ago towards3
a77522172c4a foe/httpd:v0.2 "/bin/httpd -f -h ..." 2 weeks ago Exited (137) 2 weeks ago foe1
8bf289b6017f towards/httpd:v0.2 "/bin/httpd -f -h ..." 2 weeks ago Exited (137) 2 weeks ago towards1
44fd298d3df4 foe/httpd:v0.2 "/bin/httpd -f -h ..." 2 weeks ago Exited (137) 2 weeks ago t2
6e2f3d9d2545 redis:4-alpine "docker-entrypoint..." 2 weeks ago Exited (0) 2 weeks ago kvstorl
9f1ed90b19a9 nginx:1.14-alpine "nginx -g 'daemon ..." 2 weeks ago Exited (0) 2 weeks ago web1
36374b410be3 busybox:latest "sh" 2 weeks ago Exited (130) 2 weeks ago bl6
05f9881a6708 busybox:latest "sh" 2 weeks ago Exited (130) 2 weeks ago bl5
b3e2e29e598b busybox:latest "sh" 2 weeks ago Exited (127) 2 weeks ago bl4
58a64a5fd709 busybox:latest "sh" 2 weeks ago Created bl3
但如果没有rm参数则能在docker ps中查到运行的进程,但是可以看到状态竟然是退出状态
[root@localhost img2]# docker run --name tinyweb2 -it -P tinyhttpd:v0.2-3
[root@localhost img2]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d5f00d088b3 tinyhttpd:v0.2-3 "/bin/sh -c /bin/h..." 3 seconds ago Exited (0) 2 seconds ago tinyweb2
54f1552ac4db busybox "sh" 6 days ago Exited (137) 6 days ago nginx
1eee1a72a5da busybox "sh" 6 days ago Exited (137) 6 days ago infracon
cde2576aca13 busybox:latest "sh" 12 days ago Exited (0) 12 days ago t1
54430c82f146 foe/httpd:v0.1-1 "sh" 13 days ago Exited (137) 13 days ago t3
1b767a128e0b towards/httpd:v0.2 "/bin/httpd -f -h ..." 13 days ago Exited (137) 13 days ago towards3
a77522172c4a foe/httpd:v0.2 "/bin/httpd -f -h ..." 2 weeks ago Exited (137) 2 weeks ago foe1
8bf289b6017f towards/httpd:v0.2 "/bin/httpd -f -h ..." 2 weeks ago Exited (137) 2 weeks ago towards1
44fd298d3df4 foe/httpd:v0.2 "/bin/httpd -f -h ..." 2 weeks ago Exited (137) 2 weeks ago t2
6e2f3d9d2545 redis:4-alpine "docker-entrypoint..." 2 weeks ago Exited (0) 2 weeks ago kvstorl
9f1ed90b19a9 nginx:1.14-alpine "nginx -g 'daemon ..." 2 weeks ago Exited (0) 2 weeks ago web1
36374b410be3 busybox:latest "sh" 2 weeks ago Exited (130) 2 weeks ago bl6
05f9881a6708 busybox:latest "sh" 2 weeks ago Exited (130) 2 weeks ago bl5
b3e2e29e598b busybox:latest "sh" 2 weeks ago Exited (127) 2 weeks ago bl4
58a64a5fd709 busybox:latest "sh" 2 weeks ago Created
并且日志也看不到
[root@localhost img2]# docker logs tinyweb2
然后我们弄成固定值
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
CMD ["/bin/sh","-c","/bin/httpd","-f","-h /data/web/html"]
然后我们再来看看,貌似也不行哦
[root@localhost img2]# docker run --name tinyweb2 -it -P tinyhttpd:v0.2-4
但我们这样运行
[root@localhost img2]# docker run --name tinyweb2 -it -P tinyhttpd:v0.2-4 ls /data/web/html/
index.html
或者这样,发现都是可行的
[root@localhost img2]# docker run --name tinyweb2 -it -P tinyhttpd:v0.2-4 /bin/httpd -f -h /data/web/html
向上个刚才这两种运行方式,我个人把他称为指令覆盖。
ENTRYPOINT
ENTRYPOINT也可以实现默认运行httpd
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
#CMD ["/bin/sh","-c","/bin/httpd","-f","-h /data/web/html"]
ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
同样是卡在这里
[root@localhost img2]# docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-5
那么此时我们再尝试下上面我所命名的参数覆盖的情况,会发现同样是卡住的状态
[root@localhost img2]# docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-5 ls /data/web/html/
但这并不能就说明不能被覆盖,只是此时参数覆盖的方式变更了,已经变更为—entrypoint了
[root@localhost img2]# docker run --name tinyweb2 -it --rm -P --entrypoint "ls /data" tinyhttpd:v0.2-5
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "exec: \"ls /data\": stat ls /data: no such file or directory".
这里报错了是因为命令格式不对,但我们知道它其实也是可以被覆盖的就行了
CMD为ENYRTPOINT提供默认参数
首先我们同样是编辑Dockerfile
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
ENTRYPOINT /bin/sh -c
然后产生镜像后
[root@localhost img2]# docker image inspect tinyhttpd:v0.2-6
[
{
"Id": "sha256:56f8e491dc4b70850ea0a82614876ec100078db87bf044c6d882f12779087841",
"RepoTags": [
"tinyhttpd:v0.2-6"
],
"RepoDigests": [],
"Parent": "sha256:34e5be40d6274c9d52930d0c553efd46625100bfb812aa8096c14b8702b0ad73",
"Comment": "",
"Created": "2020-09-19T08:52:17.22090003Z",
"Container": "a67f758f4669ab3447b38a8aec3a1c4e97c29e765a9c9047e4340fb04982ec40",
"ContainerConfig": {
"Hostname": "7f8a4a435507",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"WEB_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/bin/sh\" \"-c\" \"/bin/sh -c\"]"
],
"ArgsEscaped": true,
"Image": "sha256:34e5be40d6274c9d52930d0c553efd46625100bfb812aa8096c14b8702b0ad73",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh",
"-c",
"/bin/sh -c"
],
"OnBuild": [],
"Labels": {
"app": "httpd",
"maintainer": "MageEdu <mage@magedu.com>"
}
},
"DockerVersion": "1.13.1",
"Author": "",
"Config": {
"Hostname": "7f8a4a435507",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"WEB_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/httpd",
"-f",
"-h ${WEB_DOC_ROOT}"
],
"ArgsEscaped": true,
"Image": "sha256:34e5be40d6274c9d52930d0c553efd46625100bfb812aa8096c14b8702b0ad73",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh",
"-c",
"/bin/sh -c"
],
"OnBuild": [],
"Labels": {
"app": "httpd",
"maintainer": "MageEdu <mage@magedu.com>"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 1223564,
"VirtualSize": 1223564,
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/c85fc5ddc2b05c93c6b2682475a635ef62a7d615bafe9b740e81b969d6e6167d/diff",
"MergedDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/merged",
"UpperDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/diff",
"WorkDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:514c3a3e64d4ebf15f482c9e8909d130bcd53bcc452f0225b0a04744de7b8c43",
"sha256:8c9b7be899eed8473728ff3f0fa24e5dda21c5467d074bc5f9409deb82fb1efd"
]
}
}
]
那么我们再来看看另外一种ENTRYPOINT定义
[root@localhost img2]# cat Dockerfile
FROM busybox
LABEL maintainer="MageEdu <mage@magedu.com>" app="httpd"
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
echo '<h1>busybox httpd server</h1>' > ${WEB_DOC_ROOT}/index.html
CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
ENTRYPOINT ["/bin/sh","-c"]
同样的看下inspect信息,可见上面第一种会把我们的bin/sh -c整体视为额外参数一样
[root@localhost img2]# docker image inspect tinyhttpd:v0.2-7
[
{
"Id": "sha256:2a347f96227b126fdde9159597b62e05b8b5d904c1d9bb717315d7352b0584f8",
"RepoTags": [
"tinyhttpd:v0.2-7"
],
"RepoDigests": [],
"Parent": "sha256:34e5be40d6274c9d52930d0c553efd46625100bfb812aa8096c14b8702b0ad73",
"Comment": "",
"Created": "2020-09-19T08:55:51.107699686Z",
"Container": "b7aa469112d16a4f2c4ba781672aec04d14b63b60783d25282b2ae0eb51c5a1f",
"ContainerConfig": {
"Hostname": "b7aa469112d1",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"WEB_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/bin/sh\" \"-c\"]"
],
"ArgsEscaped": true,
"Image": "sha256:34e5be40d6274c9d52930d0c553efd46625100bfb812aa8096c14b8702b0ad73",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh",
"-c"
],
"OnBuild": [],
"Labels": {
"app": "httpd",
"maintainer": "MageEdu <mage@magedu.com>"
}
},
"DockerVersion": "1.13.1",
"Author": "",
"Config": {
"Hostname": "b7aa469112d1",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"WEB_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/httpd",
"-f",
"-h ${WEB_DOC_ROOT}"
],
"ArgsEscaped": true,
"Image": "sha256:34e5be40d6274c9d52930d0c553efd46625100bfb812aa8096c14b8702b0ad73",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh",
"-c"
],
"OnBuild": [],
"Labels": {
"app": "httpd",
"maintainer": "MageEdu <mage@magedu.com>"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 1223564,
"VirtualSize": 1223564,
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/c85fc5ddc2b05c93c6b2682475a635ef62a7d615bafe9b740e81b969d6e6167d/diff",
"MergedDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/merged",
"UpperDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/diff",
"WorkDir": "/var/lib/docker/overlay2/e218b55fe2bc01eab0daed3e1d57c3ab6bb1514770daa4773561981adb13e3ce/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:514c3a3e64d4ebf15f482c9e8909d130bcd53bcc452f0225b0a04744de7b8c43",
"sha256:8c9b7be899eed8473728ff3f0fa24e5dda21c5467d074bc5f9409deb82fb1efd"
]
}
}
]
那么此时会发现docker ps中也能看到了
此时变量又可以覆盖了,因为这里覆盖的参数就是给entrypoint的,而cmd是传递给entrypoint默认的,既然有了参数所以不用默认参数了,是覆盖了cmd
。
而且有两种不同的,覆盖效果也不同
[root@localhost img2]# docker run --name tinyweb2 -it -P tinyhttpd:v0.2-7 ls /data
bin data dev etc home proc root run sys tmp usr var
这tmd正确方式竟然是这样
[root@localhost img2]# docker run --name tinyweb2 -it -P tinyhttpd:v0.2-7 "ls /data"
Web
动态创建web服务器
首先同样是建立Dockerfile
我们这里参考nginx:1.14-alpine
[root@localhost ~]# docker run --name nginx1 -it nginx:1.14-alpine /bin/sh
/ # which nginx
/usr/sbin/nginx
/ # ls /etc/nginx/
conf.d koi-utf nginx.conf uwsgi_params.default
fastcgi.conf koi-win nginx.conf.default win-utf
fastcgi.conf.default mime.types scgi_params
fastcgi_params mime.types.default scgi_params.default
fastcgi_params.default modules uwsgi_params
/ # exit
则Docker file
[root@localhost img2]# cat Dockerfile
FROM nginx:1.14-alpine
LABEL maintainer="mageEdu <mage@magedu.com>"
ENV NGX_DOC_ROOT='/data/web/html/'
ADD entrypoint.sh /bin/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
我们可以看到上面这里我们ADD了一个entrypoint.sh,所以我们在当前目录自然还需要entrypoint.sh脚本,这个脚本中其它参数不多说,就是最后这个exec是指将引入本脚本的那个环境直接切换为当前脚本所处环境(进程)
[root@localhost img2]# cat entrypoint.sh
#!/bin/sh
#
cat > /etc/nginx/conf.d/www.conf << EOF
server {
server_name ${HOSTNAME};
listen ${IP:-0.0.0.0}:${PORT:-80};
root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
}
EOF
exec "$@"
那么该脚本的执行权限自是不必少
[root@localhost img2]# chmod +x entrypoint.sh
则万事大吉?
[root@localhost img2]# docker run --name myweb1 --rm -P myweb:v0.3-5
这里输出是空的,所以我们还需要建立index.html
[root@localhost img2]# cat index.html
this is index
则Dockerfile文件又要改动。。。
[root@localhost img2]# cat Dockerfile
FROM nginx:1.14-alpine
LABEL maintainer="mageEdu <mage@magedu.com>"
ENV NGX_DOC_ROOT='/data/web/html/'
ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
然后我们重新build后运行仍旧卡住
[root@localhost img2]# docker run --name myweb1 --rm -P myweb:v0.3-6
但此时我们另外一个会话,发现一切都没有问题。。。
[root@localhost img2]# docker exec -it myweb1 /bin/sh
/ # ls /etc/nginx/conf.d/www.conf
/etc/nginx/conf.d/www.conf
/ # cat /etc/nginx/conf.d/www.conf
server {
server_name 6c8ba22b6235;
listen 0.0.0.0:80;
root /data/web/html/;
}
/ # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
/ # wget -O - -q localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ # wget -O - -q 6c8ba22b6235
this is index
/ #
那么我们就可以动态创建服务器了
[root@localhost img2]# docker run --name myweb1 --rm -P myweb:v0.3-6
然后另外一个会话可以查看到
[root@localhost img2]# docker exec -it myweb1 /bin/sh
/ # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
/ # ps
PID USER TIME COMMAND
1 root 0:00 nginx: master process /usr/sbin/nginx -g daemon off;
8 nginx 0:00 nginx: worker process
9 root 0:00 /bin/sh
14 root 0:00 ps
/ #
pid为1的,是因为刚才那个脚本sh里面的exec切断了之前的shell
目前看到运行用户是root,这个就不演示了哈。
Docker容器内部指定服务的健康状态检查
建立Dockerfile,这里HEALTHCHECK就是健康检查,其中—start-period就是指定检查周期的,然后CMD就是指定检查脚本命令的。
[root@localhost img2]# cat Dockerfile
FROM nginx:1.14-alpine
LABEL maintainer="mageEdu <mage@magedu.com>"
ENV NGX_DOC_ROOT='/data/web/html/'
ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/
EXPOSE 80/tcp
HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
ARG的使用
ARG可以在Dockerfile文件中用于定义变量,如
[root@localhost img2]# cat Dockerfile
FROM nginx:1.14-alpine
ARG author="mageedu <mage@mageedu.com>"
LABEL maintainer="${author}"
ENV NGX_DOC_ROOT='/data/web/html/'
ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/
EXPOSE 80/tcp
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
然后可以看到labels在inspect中就有我们ARG所定义的信息了
[root@localhost img2]# docker image inspect myweb:v0.3-9
[
{
"Id": "sha256:8758871fea600cba06ff99d4e6ef87f04dd9454f9cc4404c28bc7ba48f7c65f1",
"RepoTags": [
"myweb:v0.3-9"
],
"RepoDigests": [],
"Parent": "sha256:493d22f6d18b5e9214106f4b7d9e67c79f8a8673c517d993bd9771b0a24584b2",
"Comment": "",
"Created": "2020-09-19T10:52:59.0108916Z",
"Container": "2c93210c8bbeda6f5cee049bacc15c234d401c6ace27b50c9b31d7baf5819a49",
"ContainerConfig": {
"Hostname": "a9d95213b17e",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.14.2",
"NGX_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/bin/entrypoint.sh\"]"
],
"ArgsEscaped": true,
"Image": "sha256:493d22f6d18b5e9214106f4b7d9e67c79f8a8673c517d993bd9771b0a24584b2",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/entrypoint.sh"
],
"OnBuild": [],
"Labels": {
"maintainer": "mageedu <mage@mageedu.com>"
},
"StopSignal": "SIGTERM"
},
"DockerVersion": "1.13.1",
"Author": "",
"Config": {
"Hostname": "a9d95213b17e",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.14.2",
"NGX_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/usr/sbin/nginx",
"-g",
"daemon off;"
],
"ArgsEscaped": true,
"Image": "sha256:493d22f6d18b5e9214106f4b7d9e67c79f8a8673c517d993bd9771b0a24584b2",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/entrypoint.sh"
],
"OnBuild": [],
"Labels": {
"maintainer": "mageedu <mage@mageedu.com>"
},
"StopSignal": "SIGTERM"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 16033013,
"VirtualSize": 16033013,
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/af7d426e00087104622aff09215309d8986deab57343794de4cfe707ac0 35436/diff:/var/lib/docker/overlay2/81c4f089b7d12a8ec14bf134b37e540370f1926736fc60e2d3778f6be79cb150/diff:/var/li b/docker/overlay2/b606ea7f67dbb293b58cfb36a0fd311ffc997cb48530649a6c0113df1c63d234/diff:/var/lib/docker/overlay2/ 47f077089b67bc0f3c17239c17614f8278e1d700557846c4bcf74922a479ca28/diff:/var/lib/docker/overlay2/f7d49a2f6e35bd44a4 171c18981eba7a254f0d60c2bed7974feb35fb8a70895f/diff",
"MergedDir": "/var/lib/docker/overlay2/2ab87bc4b037e6067984571b36e8f5b484db53ba5ce89d97f360042710 ca8d80/merged",
"UpperDir": "/var/lib/docker/overlay2/2ab87bc4b037e6067984571b36e8f5b484db53ba5ce89d97f360042710c a8d80/diff",
"WorkDir": "/var/lib/docker/overlay2/2ab87bc4b037e6067984571b36e8f5b484db53ba5ce89d97f360042710ca 8d80/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:a464c54f93a9e88fc1d33df1e0e39cca427d60145a360962e8f19a1dbf900da9",
"sha256:5ac9a5170bf254da6d1b54edbfde4da4070e5c43a85a0402ec7defdcec5c3657",
"sha256:b2cbae4b8c158c49c6590cc69a305c36dfb133321c3ab1e9c3b764f54c27158a",
"sha256:076c58d2644f0d4c4a80d460bc2dfb21469f4fdb5c3d259438e0a4a1b182fa87",
"sha256:7536d1bb83682ccf0ecb721f75166e75d22b5cf4e9c33e0f602ce01900702a4c",
"sha256:ccd8634ab31467183894ff8bda4a7e8e01bb1a1112c3613bdf53c07f3211cb50"
]
}
}
]
ARG可不仅仅只是这样,ARG还支持在build时进行注入,如
[root@localhost img2]# docker build --build-arg author="pony <pony@qq.com>" -t myweb:v0.3-10 ./
Sending build context to Docker daemon 4.096 kB
Step 1/9 : FROM nginx:1.14-alpine
---> 8a2fb25a19f5
Step 2/9 : ARG author="mageedu <mage@mageedu.com>"
---> Using cache
---> 1ff8eeddb6f5
Step 3/9 : LABEL maintainer "${author}"
---> Running in fcb568faac4f
---> 3191eaba5e77
Removing intermediate container fcb568faac4f
Step 4/9 : ENV NGX_DOC_ROOT '/data/web/html/'
---> Running in 0e286f177235
---> 0cf77e013345
Removing intermediate container 0e286f177235
Step 5/9 : ADD index.html ${NGX_DOC_ROOT}
---> 22092e938c33
Removing intermediate container 3f9dd688cf6a
Step 6/9 : ADD entrypoint.sh /bin/
---> fcf27b683f52
Removing intermediate container 48f252e12e37
Step 7/9 : EXPOSE 80/tcp
---> Running in 410aea62e4c5
---> e933578f9036
Removing intermediate container 410aea62e4c5
Step 8/9 : CMD /usr/sbin/nginx -g daemon off;
---> Running in 0d1977626c62
---> 2ec4e66f496a
Removing intermediate container 0d1977626c62
Step 9/9 : ENTRYPOINT /bin/entrypoint.sh
---> Running in bee97d3e3cb1
---> 3b3b86ef9fb8
Removing intermediate container bee97d3e3cb1
Successfully built 3b3b86ef9fb8
[root@localhost img2]# docker image inspect myweb:v0.3-10
[
{
"Id": "sha256:3b3b86ef9fb8e3f407231979d67b5a88b5492f47bc99de636f06c05423135cfc",
"RepoTags": [
"myweb:v0.3-10"
],
"RepoDigests": [],
"Parent": "sha256:2ec4e66f496a2ae52d1abdda151b9ae485bd783cef9151dc3501a172ea250d14",
"Comment": "",
"Created": "2020-09-19T10:59:49.48483869Z",
"Container": "bee97d3e3cb1e235232864e3a46d621012ebe2527ba59f1884508bcd4bfb9169",
"ContainerConfig": {
"Hostname": "fcb568faac4f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.14.2",
"NGX_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/bin/entrypoint.sh\"]"
],
"ArgsEscaped": true,
"Image": "sha256:2ec4e66f496a2ae52d1abdda151b9ae485bd783cef9151dc3501a172ea250d14",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/entrypoint.sh"
],
"OnBuild": [],
"Labels": {
"maintainer": "pony <pony@qq.com>"
},
"StopSignal": "SIGTERM"
},
"DockerVersion": "1.13.1",
"Author": "",
"Config": {
"Hostname": "fcb568faac4f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.14.2",
"NGX_DOC_ROOT=/data/web/html/"
],
"Cmd": [
"/usr/sbin/nginx",
"-g",
"daemon off;"
],
"ArgsEscaped": true,
"Image": "sha256:2ec4e66f496a2ae52d1abdda151b9ae485bd783cef9151dc3501a172ea250d14",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/entrypoint.sh"
],
"OnBuild": [],
"Labels": {
"maintainer": "pony <pony@qq.com>"
},
"StopSignal": "SIGTERM"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 16033013,
"VirtualSize": 16033013,
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/4660bb74b08309e59ad55da7560152d2544a1af00e480f5c6af1605cebb 22c72/diff:/var/lib/docker/overlay2/81c4f089b7d12a8ec14bf134b37e540370f1926736fc60e2d3778f6be79cb150/diff:/var/li b/docker/overlay2/b606ea7f67dbb293b58cfb36a0fd311ffc997cb48530649a6c0113df1c63d234/diff:/var/lib/docker/overlay2/ 47f077089b67bc0f3c17239c17614f8278e1d700557846c4bcf74922a479ca28/diff:/var/lib/docker/overlay2/f7d49a2f6e35bd44a4 171c18981eba7a254f0d60c2bed7974feb35fb8a70895f/diff",
"MergedDir": "/var/lib/docker/overlay2/e896155e9cf17251c50613f101255a45224e8d1ad9b50a7d0d7b780a7f 2fa521/merged",
"UpperDir": "/var/lib/docker/overlay2/e896155e9cf17251c50613f101255a45224e8d1ad9b50a7d0d7b780a7f2 fa521/diff",
"WorkDir": "/var/lib/docker/overlay2/e896155e9cf17251c50613f101255a45224e8d1ad9b50a7d0d7b780a7f2f a521/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:a464c54f93a9e88fc1d33df1e0e39cca427d60145a360962e8f19a1dbf900da9",
"sha256:5ac9a5170bf254da6d1b54edbfde4da4070e5c43a85a0402ec7defdcec5c3657",
"sha256:b2cbae4b8c158c49c6590cc69a305c36dfb133321c3ab1e9c3b764f54c27158a",
"sha256:076c58d2644f0d4c4a80d460bc2dfb21469f4fdb5c3d259438e0a4a1b182fa87",
"sha256:6febd9a00365484fa4e9f542dd9ddfc5ed0927ce86b8c301caad46c41bd73ff7",
"sha256:6f7d5ddcc55d499fdfe8277747180f328319040cf847c90043e72d21d94d36f4"
]
}
}
]
ONNUILD的使用
ONBUILD可以指定在build时触发一个指定的类似触发器行为,和JavaScript的on事件一样。ONBUILD事件定义在Dockerfile中,而该事件触发于该Dockerfile进行build之后的镜像被另外一个Dockerfile进行FROM后并将另外一个Dockerfile进行build的时候。
那么我这里先创建一个Dockerfile并定义ONBUILD事件、并build该Dockerfile创建一个镜像如。
[root@localhost img2]# cat Dockerfile
FROM nginx:1.14-alpine
ARG author="mageedu <mage@mageedu.com>"
LABEL maintainer="${author}"
ENV NGX_DOC_ROOT='/data/web/html/'
ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/
EXPOSE 80/tcp
ONBUILD ADD http://172.20.0.1/centos/7/Packages/PackageKit-gstreamer-plugin-1.1.5-1.el7.centos.x86_64.rpm /usr/local/src/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
[root@localhost img2]# docker build -t myweb:v0.3-11 ./
Sending build context to Docker daemon 4.096 kB
Step 1/10 : FROM nginx:1.14-alpine
---> 8a2fb25a19f5
Step 2/10 : ARG author="mageedu <mage@mageedu.com>"
---> Using cache
---> 1ff8eeddb6f5
Step 3/10 : LABEL maintainer "${author}"
---> Using cache
---> 6ba100815a8e
Step 4/10 : ENV NGX_DOC_ROOT '/data/web/html/'
---> Using cache
---> c564abeb9257
Step 5/10 : ADD index.html ${NGX_DOC_ROOT}
---> Using cache
---> 8bb17c76461a
Step 6/10 : ADD entrypoint.sh /bin/
---> Using cache
---> 5d91d7480171
Step 7/10 : EXPOSE 80/tcp
---> Using cache
---> bb07cbc3a8e0
Step 8/10 : ONBUILD add http://172.20.0.1/centos/7/Packages/PackageKit-gstreamer-plugin-1.1.5-1.el7.centos.x86_64.rpm /usr/local/src/
---> Running in 707a8848bf8e
---> 2e7557776e27
Removing intermediate container 707a8848bf8e
Step 9/10 : CMD /usr/sbin/nginx -g daemon off;
---> Running in c874af44b28c
---> 9acaf78e43b3
Removing intermediate container c874af44b28c
Step 10/10 : ENTRYPOINT /bin/entrypoint.sh
---> Running in 477065af9bd1
---> 07c2b67f8735
Removing intermediate container 477065af9bd1
Successfully built 07c2b67f8735
然后建立另外一个Dockerfile并FROM上面建立的这个镜像然后build如
[root@localhost ~]# cat Dockerfile
FROM myweb:v0.3-11
RUN mkdir /tmp/test
[root@localhost ~]# docker build -t test:v0.1-1 ./
Sending build context to Docker daemon 4.043 MB
Step 1/2 : FROM myweb:v0.3-11
# Executing 1 build trigger...
Step 1/1 : ADD http://172.20.0.1/centos/7/Packages/PackageKit-gstreamer-plugin-1.1.5-1.el7.centos.x86_64.rpm /usr/local/src/
Get http://172.20.0.1/centos/7/Packages/PackageKit-gstreamer-plugin-1.1.5-1.el7.centos.x86_64.rpm: dial tcp 172.20.0.1:80: connect: connection refused
虽然上面这里下载失败了,这是因为该地址是一个相对于我这个环境不存在的地址,但足可以证明事件的确是触发了。所以说人还是要灵活动脑的,不能一根筋哈。
关键字词:Dockerfile,动态创建服务器,触发器,ONBUILD,ARG,一根筋
上一篇:07-Dockerfile详解