温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

什么是Dockerfile

发布时间:2021-10-12 10:45:36 来源:亿速云 阅读:306 作者:iii 栏目:编程语言

这篇文章主要介绍“什么是Dockerfile”,在日常操作中,相信很多人在什么是Dockerfile问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是Dockerfile”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一 DockerFile构建过程解析

1.Dockerfile内容基础知识

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数

  2. 指令按照从上到下,顺序执行

  3. #表示注释

  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

2 Docker执行Dockerfile的大致流程

  1. docker从基础镜像运行一个容器

  2. 执行一条指令并对容器作出修改

  3. 执行类似docker commit的操作提交一个新的镜像层

  4. docker再基于刚提交的镜像运行一个新容器

  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

3 小总结

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料

  • Docker镜像是软件的交付品

  • Docker容器则可以认为是软件的运行态。 Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石 什么是Dockerfile

  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;

  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;

  3. Docker容器,容器是直接提供服务的。

二 DockerFile体系结构(保留字指令)

FROM

基础镜像,当前新镜像是基于哪个镜像的

MAINTAINER

镜像维护者的姓名和邮箱地址

RUN

容器构建时需要运行的命令

EXPOSE

当前容器对外暴露出的端口

WORKDIR

指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

ENV

用来在构建镜像过程中设置环境变量

例如:ENV MY_PATH /usr/mytest 这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量, 比如:WORKDIR $MY_PATH

ADD

将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

COPY

类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

VOLUME

容器数据卷,用于数据保存和持久化工作

CMD

指定一个容器启动时要运行的命令

什么是Dockerfile

三 案例

Base镜像(scratch)

Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的

自定义镜像 mycentos

1 编写

Hub默认CentOS镜像的情况 

什么是Dockerfile
 

myCentOS内容Dockerfile

FROM centos
MAINTAINER zhl<253316343@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "success ------  ok"
CMD /bin/bash
2 构建

docker build -f DockerFile目录  -t  新镜像名字:TAG .    . 表示当前目录

docker build -f /opt/docker/mydocker/Dockerfile -t zhl/centos1.1 .

root@zhanghl:/opt/docker/mydocker# docker build -f /opt/docker/mydocker/Dockerfile -t zhl/centos1.1 .
Sending build context to Docker daemon  2.048kB
Step 1/10 : FROM centos
 ---> 300e315adb2f
Step 2/10 : MAINTAINER zhl<253316343@qq.com>
 ---> Running in 9cef0b83aa4d
Removing intermediate container 9cef0b83aa4d
 ---> e03c70aa84dd
Step 3/10 : ENV MYPATH /usr/local
 ---> Running in a06eb1e589da
Removing intermediate container a06eb1e589da
 ---> f817774de33b
Step 4/10 : WORKDIR $MYPATH
 ---> Running in 2638200252e1
Removing intermediate container 2638200252e1
 ---> e0ac249d8189
Step 5/10 : RUN yum -y install vim
 ---> Running in 23a14562d0d6
.......
 ---> 059822073508
Step 6/10 : RUN yum -y install net-tools
 ---> Running in 4a437d96a483
.....
 ---> c49737740d20
Step 7/10 : EXPOSE 80
 ---> Running in 326caf878a8e
Removing intermediate container 326caf878a8e
 ---> 6690abcca60f
Step 8/10 : CMD echo $MYPATH
 ---> Running in 47664a0e6e10
Removing intermediate container 47664a0e6e10
 ---> 8db1cff1fad3
Step 9/10 : CMD echo "success ------  ok"
 ---> Running in 7ad2234cdfbd
Removing intermediate container 7ad2234cdfbd
 ---> a08723e08f62
Step 10/10 : CMD /bin/bash
 ---> Running in e0ecfa0bf1f3
Removing intermediate container e0ecfa0bf1f3
 ---> 77c006bf4b15
Successfully built 77c006bf4b15
Successfully tagged zhl/centos1.1:latest
root@zhanghl:/opt/docker/mydocker#
3 运行

docker run -it 新镜像名字:TAG .

root@zhanghl:/opt/docker/mydocker# docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
zhl/centos1.1   latest    77c006bf4b15   3 minutes ago   291MB
zhl/centos      latest    e4998e64dece   38 hours ago    209MB
zhl/mytomcat    1.1       a636ea3caaed   4 days ago      672MB
mongo           latest    995ccc33e58f   8 days ago      449MB
tomcat          latest    c0e850d7b9bb   9 days ago      667MB
hello-world     latest    d1165f221234   8 weeks ago     13.3kB
centos          latest    300e315adb2f   4 months ago    209MB
root@zhanghl:/opt/docker/mydocker# docker run -it 77c006bf4b15
[root@01ba3472d1c3 local]# pwd
/usr/local
[root@01ba3472d1c3 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 21  bytes 2716 (2.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@01ba3472d1c3 local]# vim a.txt
[root@01ba3472d1c3 local]# cat a.txt
hello
4 列出镜像的变更历史

docker history [镜像名]

[root@01ba3472d1c3 local]# docker history 77c006bf4b15
bash: docker: command not found
[root@01ba3472d1c3 local]# exit
exit
root@zhanghl:/opt/docker/mydocker# docker history  77c006bf4b15
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
77c006bf4b15   7 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh">

CMD / ENTRYPOINT 镜像案例

都是指定一个容器启动时要运行的命令

CMD

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
案例 tomcat 的讲解演示

追加 ls -l 命令后 替代了原理运行tomcat的命令,导致docker没有启动

什么是Dockerfile

ENTRYPOINT

docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
案例

制作CMD版可以查询IP信息的容器

DockerFile: Dockerfile -myid

FROM centos
RUN yum install -y curl
CMD ["curl","www.trackip.net/ip?json"]
root@zhanghl:/opt/docker/mydocker# docker build -f Dockerfile-myid -t myid:1.1 .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM centos
 ---> 300e315adb2f
Step 2/3 : RUN yum install -y curl
 ---> Using cache
 ---> 82abeb79293f
Step 3/3 : CMD ["curl","www.trackip.net/ip?json"]
 ---> Running in bafa2c73ec55
Removing intermediate container bafa2c73ec55
 ---> a566bc415a96
Successfully built a566bc415a96
Successfully tagged myid:1.1
root@zhanghl:/opt/docker/mydocker# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
myid            1.1       a566bc415a96   5 seconds ago    243MB
myip            latest    251ed5335c1a   30 minutes ago   243MB
zhl/centos1.1   latest    77c006bf4b15   3 hours ago      291MB
zhl/centos      latest    e4998e64dece   40 hours ago     209MB
zhl/mytomcat    1.1       a636ea3caaed   4 days ago       672MB
mongo           latest    995ccc33e58f   8 days ago       449MB
tomcat          latest    c0e850d7b9bb   9 days ago       667MB
hello-world     latest    d1165f221234   8 weeks ago      13.3kB
centos          latest    300e315adb2f   4 months ago     209MB
root@zhanghl:/opt/docker/mydocker# docker run -it myid:1.1
{"IP":"175.161.93.164","Country":"CN","UA":"curl\/7.61.1","Time":1619934102}

问题 ,运行时 加参数 -i 报错

root@zhanghl:/opt/docker/mydocker# docker run -it myid:1.1 -i
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-i": executable file not found in $PATH: unknown.

WHY

我们可以看到可执行文件找不到的报错,executable file not found。
之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。
因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。
 
那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:
 
$ docker run myip curl -s http://ip.cn -i

制作ENTRYPOINT版查询IP信息的容器

DockerFile:

FROM centos
RUN yum install -y curl
ENTRYPOINT  ["curl","www.trackip.net/ip?json"]

 build

root@zhanghl:/opt/docker/mydocker# docker build -f Dockerfile-Entrypoint-myip -t myip:1.2 .
Sending build context to Docker daemon  4.096kB
Step 1/3 : FROM centos
 ---> 300e315adb2f
Step 2/3 : RUN yum install -y curl
 ---> Using cache
 ---> 82abeb79293f
Step 3/3 : ENTRYPOINT  ["curl","www.trackip.net/ip?json"]
 ---> Running in 70070b1d358c
Removing intermediate container 70070b1d358c
 ---> f1f60b285381
Successfully built f1f60b285381
Successfully tagged myip:1.2
root@zhanghl:/opt/docker/mydocker#

运行

root@zhanghl:/opt/docker/mydocker# docker run -it myip:1.2
{"IP":"175.161.93.164","Country":"CN","UA":"curl\/7.61.1","Time":1619934632}root@zhanghl:/opt/docker/mydocker# 
root@zhanghl:/opt/docker/mydocker# docker run -it myip:1.2 -i
HTTP/1.1 200 OK
Date: Sun, 02 May 2021 05:50:38 GMT
Content-Type: text/plain
Content-Length: 76
Connection: keep-alive
Set-Cookie: __cfduid=d6e71854852b8ade1b5e9d1ba03386d6a1619934638; expires=Tue, 01-Jun-21 05:50:38 GMT; path=/; domain=.trackip.net; HttpOnly; SameSite=Lax
CF-Cache-Status: DYNAMIC
cf-request-id: 09cd3a08d100000530688e1000000001
Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=aZpOakyvJEJIy5RKJSanPc6kAxlXG390nfy3ADvHSEbFkG7pzavegW8Xwt7RiF%2F6ExbnXvvp9ZiGHKJ0gD%2F%2F6fm5IyWGJPv%2FeKG1mY%2FGnWQ%3D"}]}
NEL: {"report_to":"cf-nel","max_age":604800}
Server: cloudflare
CF-RAY: 648ef9214d210530-LAX
alt-svc: h4-27=":443"; ma=86400, h4-28=":443"; ma=86400, h4-29=":443"; ma=86400

{"IP":"175.161.93.164","Country":"CN","UA":"curl\/7.61.1","Time":1619934639}root@zhanghl:/opt/docker/mydocker# 
root@zhanghl:/opt/docker/mydocker#

ONBUILD 命令案例

修改上一步的DockerFile

FROM centos
RUN yum install -y curl
ENTRYPOINT  ["curl","www.trackip.net/ip?json"]
ONBUILD RUN echo "father images onbuild------886"

build镜像

docker build -f Dockerfile-Entrypoint-myip  -t myip_father .

root@zhanghl:/opt/docker/mydocker# docker build -f Dockerfile-Entrypoint-myip  -t myip_father .
Sending build context to Docker daemon   5.12kB
Step 1/4 : FROM centos
 ---> 300e315adb2f
Step 2/4 : RUN yum install -y curl
 ---> Using cache
 ---> 82abeb79293f
Step 3/4 : ENTRYPOINT  ["curl","www.trackip.net/ip?json"]
 ---> Using cache
 ---> f1f60b285381
Step 4/4 : ONBUILD RUN echo "father images onbuild------886"
 ---> Using cache
 ---> 1d20c7ac1ee1
Successfully built 1d20c7ac1ee1
Successfully tagged myip_father:latest

显示信息:

Step 4/4 : ONBUILD RUN echo "father images onbuild------886"

以myip:1.3 为父镜像 编写子镜像DockerFile。Dockerfile-Entrypoint-myip-sub

FROM myip_father
RUN yum install -y curl
ENTRYPOINT  ["curl","www.trackip.net/ip?json"]
ONBUILD RUN echo "father images onbuild------886"
~
docker build -f Dockerfile-Entrypoint-myip-sub  -t myip_son .
Sending build context to Docker daemon   5.12kB
Step 1/4 : FROM myip_father
# Executing 1 build trigger
 ---> Running in 9b6bfe884ccd
father images onbuild------886
Removing intermediate container 9b6bfe884ccd
 ---> d45eda2663bc
Step 2/4 : RUN yum install -y curl
 ---> Running in 3f4e383eec45
Last metadata expiration check: 1:08:58 ago on Sun May  2 05:10:51 2021.
Package curl-7.61.1-14.el8_3.1.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
Removing intermediate container 3f4e383eec45
 ---> 4cdefe20ba39
Step 3/4 : ENTRYPOINT  ["curl","www.trackip.net/ip?json"]
 ---> Running in 395df3226201
Removing intermediate container 395df3226201
 ---> fc869c497482
Step 4/4 : ONBUILD RUN echo "father images onbuild------886"
 ---> Running in 36d3ac20d0fe
Removing intermediate container 36d3ac20d0fe
 ---> c3615df75130
Successfully built c3615df75130
Successfully tagged myip_son:latest

build时父类onbuild事件被触发

 ONBUILD RUN echo "father images onbuild------886"

自定义镜像TOMCAT

1 创建实验目录 /opt/docker/mydocker/tomcat9
2 创建c.txt

    touch c.txt  

3 将jdk和tomcat安装的压缩包拷贝进目录
root@zhanghl:/opt/docker/mydocker/tomcat9# ll
总用量 152772
drwxr-xr-x 2 root root      4096 5月   2 16:33 ./
drwxr-xr-x 3 root root      4096 5月   2 14:25 ../
-rw-r--r-- 1 root root  11486964 5月   2 14:30 apache-tomcat-9.0.45.tar.gz
-rw-r--r-- 1 root root         0 5月   2 14:28 c.txt
-rw-r--r-- 1 root root 144935989 5月   2 16:31 jdk-8u291-linux-x64.tar.gz
root@zhanghl:/opt/docker/mydocker/tomcat9# pwd
/opt/docker/mydocker/tomcat9
4 在目录下新建Dockerfile文件
FROM   centos
MAINTAINER    ZHL<253316343@qq.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u291-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.45.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_291
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.45
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.45
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE  8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.45/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.45/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.45/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.45/bin/logs/catalina.out

什么是Dockerfile

5 构建
docker build -f /opt/docker/mydocker/tomcat9/DockerFile -t mytomcat9 .
root@zhanghl:/opt/docker/mydocker/tomcat9# docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
mytomcat9       latest    2b12a6a03ea0   2 minutes ago   643MB
6  RUN 
docker run -d -p 9080:8080 --name myt9 -v /opt/docker/mydocker/tomcat9/test:/usr/local/apache-tomcat-9.0.45/webapps/test -v /opt/docker/mydocker/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.45/logs  mytomcat9

准备两个目录

root@zhanghl:/opt/docker/mydocker/tomcat9# mkdir test
root@zhanghl:/opt/docker/mydocker/tomcat9# mkdir tomcat9logs
root@zhanghl:/opt/docker/mydocker/tomcat9# ll
总用量 152784
drwxr-xr-x 4 root root      4096 5月   2 17:23 ./
drwxr-xr-x 3 root root      4096 5月   2 14:25 ../
-rw-r--r-- 1 root root  11486964 5月   2 14:30 apache-tomcat-9.0.45.tar.gz
-rw-r--r-- 1 root root         0 5月   2 14:28 c.txt
-rw-r--r-- 1 root root      1039 5月   2 16:40 DockerFile
-rw-r--r-- 1 root root 144935989 5月   2 16:31 jdk-8u291-linux-x64.tar.gz
drwxr-xr-x 2 root root      4096 5月   2 17:23 test/
drwxr-xr-x 2 root root      4096 5月   2 17:23 tomcat9logs/
7 验证

什么是Dockerfile

进入容器查看目录内容

root@zhanghl:/opt/docker/mydocker/tomcat9# docker exec 882930ee0ac0 ls -l
total 52
drwxr-xr-x 1 root  root  4096 May  2 09:16 apache-tomcat-9.0.45
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 bin
-rw-r--r-- 1 root  root     0 May  2 06:28 cincontainer.txt
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 etc
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 games
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 include
drwxr-xr-x 8 10143 10143 4096 Apr  7 19:26 jdk1.8.0_291
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 lib
drwxr-xr-x 3 root  root  4096 Dec  4 17:37 lib64
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 libexec
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 sbin
drwxr-xr-x 5 root  root  4096 Dec  4 17:37 share
drwxr-xr-x 2 root  root  4096 Nov  3 15:22 src
8 结合前述的容器卷将测试的web服务test发布

在宿主机中共享文件夹中创建Web服务

root@zhanghl:/opt/docker/mydocker/tomcat9/test# mkdir WEB-INF
root@zhanghl:/opt/docker/mydocker/tomcat9/test# cd WEB-INF/
root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# vim web.xml
root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# vim a.jsp

创建 WEB-INFO目录,并在其下创建 web.xml 

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  id="WebApp_ID" version="2.5">
  
  <display-name>test</display-name>
 
</web-app>

在 test目录中创建 a.jsp:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
  </head>
  <body>
    -----------welcome------------
    <%="i am in docker tomcat self "%>
    <br>
    <br>
    <% System.out.println("=============docker tomcat self");%>
  </body>

重启 容器  

docker restart [container id]

root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                       NAMES
882930ee0ac0   mytomcat9   "/bin/sh -c '/usr/lo…"   17 minutes ago   Up 17 minutes   0.0.0.0:9080->8080/tcp, :::9080->8080/tcp   myt9
root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# docker restart 882930ee0ac0

查看网页

什么是Dockerfile

查看日志

root@zhanghl:/opt/docker/mydocker/tomcat9/tomcat9logs# cat catalina.out

小总结

什么是Dockerfile

到此,关于“什么是Dockerfile”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI