一、什么是DockerFile

  • Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。Docker通过读取Dockerfile中的指令自动生成映像。
  • **docker build**命令用于从Dockerfile构建映像。可以在docker build命令中使用**-f**标志指向文件系统中任何位置的Dockerfile。例如**docker build -f /path/to/a/Dockerfile**
  • 可以理解为:DockerFile是代码,镜像是代码写好的类,容器是类创建出来的对象

    二、Dockerfile的基本结构

  • DockerFile 一般分为四部分:

    • 基础镜像信息
    • 维护者信息
    • 镜像操作指令
    • 容器启动时执行指令
    • 为 DockerFile 中的注释。

      三、DockerFile构建过程

      (1)每个保留关键字(指令)都必须是大写字母
      (2)指令从上到下顺序执行
      (3)# 表示注释
      (4)每一个指令都会创建提交一个新的镜像层,并提交!
      image.png
  • DockerFile是面向开发的,我们以后要发布项目,做镜像,就需要编写DockerFile文件,这个文件十分简单

  • Docker镜像逐渐成为企业交付的标准,必须要掌握,构建步骤
    • 1、编写一个DockerFile文件
    • 2、docker build 构建成为一个镜像
    • 3、docker run 运行镜像
    • 4、docker push 发布镜像
  • 步骤:开发,部署,运维……缺一不可
  • DockerFile:构建文件,定义了一切的步骤,源代码
  • DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
  • Docker容器:容器就是镜像运行起来提供服务

    四、DockerFile文件说明

  • Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。

    1、 一些指令

    (1)FROM

  • 指定基础镜像,必须为第一个命令 ```dockerfile 格式:   FROM DockerFile文件 - 图2   FROM DockerFile文件 - 图3:   FROM DockerFile文件 - 图4@

示例:   FROM mysql:5.6 注:   tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像

  1. <a name="zaTeM"></a>
  2. ### (2)MAINTAINER
  3. - **维护者信息**
  4. ```dockerfile
  5. 格式:
  6. MAINTAINER <name>
  7. 示例:
  8. MAINTAINER Jasper Xu
  9. MAINTAINER sorex@163.com
  10. MAINTAINER Jasper Xu <sorex@163.com>

(3)RUN

  • 构建镜像时执行的命令
  • 注意:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定—no-cache参数,如:**docker build --no-cache** ```dockerfile RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:

shell执行 格式: RUN

exec执行 格式: RUN [“executable”, “param1”, “param2”]

示例: RUN [“executable”, “param1”, “param2”] RUN apk update RUN [“/etc/execfile”, “arg1”, “arg1”] 

  1. <a name="cjNGt"></a>
  2. ### (4)ADD
  3. - **将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget**
  4. ```dockerfile
  5. 格式:
  6. ADD <src>... <dest>
  7. ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
  8. 示例:
  9. ADD hom* /mydir/ # 添加所有以"hom"开头的文件
  10. ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
  11. ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
  12. ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/

(5)COPY

  • 功能类似ADD,但是不会自动解压文件,也不能访问网络资源

    (6)CMD

  • 构建容器后调用,也就是在容器启动时才进行调用

  • 注意:
    • CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
    • 每个Dockfile只能有一条CMD命令,如果指定了多条,只有最后一条会执行。
    • 如果用户启动容器时指定了运行命令,则会覆盖CMD指定命令。下面的实战部分会分析这部分内容 ```dockerfile 格式: CMD [“executable”,”param1”,”param2”] (执行可执行文件,优先) CMD [“param1”,”param2”] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数) CMD command param1 param2 (执行shell内部命令)

示例: CMD echo “This is a test.” | wc - CMD [“/usr/bin/wc”,”—help”]

  1. <a name="G3fkp"></a>
  2. ### (7)ENTRYPOINT
  3. - **配置容器,使其可执行化。配合CMD可省去"application",只使用参数。**
  4. - **注意:ENTRYPOINT与CMD非常类似,不同的是通过**`**docker run**`**执行的命令不会覆盖ENTRYPOINT,而**`**docker run**`**命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。**
  5. ```dockerfile
  6. 格式:
  7. ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
  8. ENTRYPOINT command param1 param2 (shell内部命令)
  9. 示例:
  10. FROM ubuntu
  11. ENTRYPOINT ["top", "-b"]
  12. CMD ["-c"]

(8)LABEL

  • 用于为镜像添加元数据
  • 注意:使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。 ```dockerfile 格式: LABEL = = =

示例:   LABEL version=”1.0” description=”这是一个Web服务器” by=”IT笔录”

  1. <a name="KQnu1"></a>
  2. ### (9)ENV
  3. - **设置环境变量**
  4. ```dockerfile
  5. 格式:
  6. ENV <key> <value> #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
  7. ENV <key>=<value> ... #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
  8. 示例:
  9. ENV myName John Doe
  10. ENV myDog Rex The Dog
  11. ENV myCat=fluffy

(10)EXPOSE

  • 指定于外界交互的端口
  • 注意:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在**docker run**运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口 ```dockerfile 格式: EXPOSE […]

示例: EXPOSE 80 443 EXPOSE 8080
EXPOSE 11211/tcp 11211/udp

  1. <a name="TfHF7"></a>
  2. ### (11)VOLUME
  3. - **用于指定持久化目录**
  4. - **注意:一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:**
  5. - **1、卷可以容器间共享和重用**
  6. - **2、容器并不一定要和其它容器共享卷**
  7. - **3、修改卷后会立即生效**
  8. - **4、对卷的修改不会对镜像产生影响**
  9. - **5、卷会一直存在,直到没有任何容器在使用它**
  10. ```dockerfile
  11. 格式:
  12. VOLUME ["/path/to/dir"]
  13. 示例:
  14. VOLUME ["/data"]
  15. VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"

(12)WORKDIR

  • 工作目录,类似于cd命令
  • 注意:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用**docker run**运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。 ```dockerfile 格式: WORKDIR /path/to/workdir

示例: WORKDIR /a (这时工作目录为/a) WORKDIR b (这时工作目录为/a/b) WORKDIR c (这时工作目录为/a/b/c)

  1. <a name="an0ef"></a>
  2. ### (13)USER
  3. - **指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户**
  4. - **注意:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过**`**docker run**`**运行容器时,可以通过-u参数来覆盖所指定的用户。**
  5. ```dockerfile
  6. 格式:  
  7. USER user  
  8. USER user:group  
  9. USER uid  
  10. USER uid:gid  
  11. USER user:gid  
  12. USER uid:group
  13. 示例:   
  14. USER www

(14)ARG

  • 用于指定传递给构建运行时的变量 ```dockerfile 格式: ARG [=]

示例: ARG site ARG build_user=www

  1. <a name="HeLq8"></a>
  2. ### (15)ONBUILD
  3. - **用于设置镜像触发器**
  4. - **注意:当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被触发**
  5. ```dockerfile
  6. 格式:  
  7. ONBUILD [INSTRUCTION]
  8. 示例:
  9.   ONBUILD ADD . /app/src
  10.   ONBUILD RUN /usr/local/bin/python-build --dir /app/src

2、例子

  1. # This my first nginx Dockerfile
  2. # Version 1.0
  3. # Base images 基础镜像
  4. FROM centos
  5. #MAINTAINER 维护者信息
  6. MAINTAINER tianfeiyu
  7. #ENV 设置环境变量
  8. ENV PATH /usr/local/nginx/sbin:$PATH
  9. #ADD 文件放在当前目录下,拷过去会自动解压
  10. ADD nginx-1.8.0.tar.gz /usr/local/
  11. ADD epel-release-latest-7.noarch.rpm /usr/local/
  12. #RUN 执行以下命令
  13. RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
  14. RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
  15. RUN useradd -s /sbin/nologin -M www
  16. #WORKDIR 相当于cd
  17. WORKDIR /usr/local/nginx-1.8.0
  18. RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install
  19. RUN echo "daemon off;" >> /etc/nginx.conf
  20. #EXPOSE 映射端口
  21. EXPOSE 80
  22. #CMD 运行以下命令
  23. CMD ["nginx"]

3、总结

DockerFile文件 - 图5

五、实战:构建自己的CentOS

1、编写DockerFile配置文件

  1. FROM centos #指定centos为基础镜像
  2. MAINTAINER xdd<123456@qq.com> #维护者信息
  3. ENV MYPATH /usr/local # $MYPATH="/usr/local"
  4. WORKDIR $MYPATH #将工作目录设置为/usr/local
  5. RUN yum -y install vim #构建镜像时下载安装vim
  6. RUN yum -y install net-tools #构建镜像时下载安装net-tools
  7. EXPOSE 80 #暴露80端口
  8. CMD echo $MYPATH #容器启动时输出$MYPATH
  9. CMD echo "----end----" #覆盖上一个CMD,容器启动时输出----end----
  10. CMD /bin/bash #覆盖上一个CMD,容器启动时进入/bin/bash

image.png

2、通过编写的DockerFile文件构建镜像

  • 命令说明:**docker build -f mydockerfile-centos -t mycentos:0.1 .**
  • **docker build -f DockerFile文件路径 -t 镜像名[:TAG]**.指定从当前目录出发寻找DockerFile ```shell [root@VM-0-15-centos dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 . Sending build context to Docker daemon 2.048kB Step 1/10 : FROM centos —-> 300e315adb2f Step 2/10 : MAINTAINER xdd123456@qq.com —-> Running in 9c08beadb2c8 Removing intermediate container 9c08beadb2c8 —-> e9adad42af2c Step 3/10 : ENV MYPATH /usr/local —-> Running in cdbbbb85ee6b Removing intermediate container cdbbbb85ee6b —-> 8fcacdecf7ad Step 4/10 : WORKDIR $MYPATH —-> Running in 11ea6ae34521 Removing intermediate container 11ea6ae34521 —-> 718b6ad3e5ef Step 5/10 : RUN yum -y install vim —-> Running in a0431f8c2a80 CentOS Linux 8 - AppStream 8.4 MB/s | 8.8 MB 00:01 CentOS Linux 8 - BaseOS 6.4 MB/s | 5.6 MB 00:00 CentOS Linux 8 - Extras 17 kB/s | 10 kB 00:00

    Dependencies resolved.

    Package Arch Version Repository Size

    Installing: vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M Installing dependencies: gpm-libs x86_64 1.20.7-17.el8 appstream 39 k vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k which x86_64 2.21-12.el8 baseos 49 k

Transaction Summary

Install 5 Packages

Total download size: 7.8 M Installed size: 30 M Downloading Packages: (1/5): gpm-libs-1.20.7-17.el8.x86_64.rpm 342 kB/s | 39 kB 00:00 (2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 842 kB/s | 48 kB 00:00 (3/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 5.0 MB/s | 1.4 MB 00:00 (4/5): which-2.21-12.el8.x86_64.rpm 384 kB/s | 49 kB 00:00

(5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 15 MB/s | 6.3 MB 00:00

Total 5.8 MB/s | 7.8 MB 00:01 warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-17.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY CentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00 Importing GPG key 0x8483C65D: Userid : “CentOS (CentOS Official Signing Key) security@centos.org“ Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : which-2.21-12.el8.x86_64 1/5 Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5 Installing : vim-common-2:8.0.1763-15.el8.x86_64 3/5 Installing : gpm-libs-1.20.7-17.el8.x86_64 4/5 Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64 4/5 Installing : vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5 Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5 Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5 Verifying : gpm-libs-1.20.7-17.el8.x86_64 1/5 Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5 Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5 Verifying : vim-filesystem-2:8.0.1763-15.el8.noarch 4/5 Verifying : which-2.21-12.el8.x86_64 5/5

Installed: gpm-libs-1.20.7-17.el8.x86_64 vim-common-2:8.0.1763-15.el8.x86_64 vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarch which-2.21-12.el8.x86_64

Complete! Removing intermediate container a0431f8c2a80 —-> b24fe1460a37 Step 6/10 : RUN yum -y install net-tools —-> Running in 8d93802f92ef Last metadata expiration check: 0:00:09 ago on Thu Sep 2 22:08:45 2021.

Dependencies resolved.

Package Architecture Version Repository Size

Installing: net-tools x86_64 2.0-0.52.20160912git.el8 baseos 322 k

Transaction Summary

Install 1 Package

Total download size: 322 k Installed size: 942 k Downloading Packages:

net-tools-2.0-0.52.20160912git.el8.x86_64.rpm 1.5 MB/s | 322 kB 00:00

Total 496 kB/s | 322 kB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1 Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 1/1 Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1

Installed: net-tools-2.0-0.52.20160912git.el8.x86_64

Complete! Removing intermediate container 8d93802f92ef —-> 21faf23714e9 Step 7/10 : EXPOSE 80 —-> Running in 9330ed9b0c59 Removing intermediate container 9330ed9b0c59 —-> 0979d2a554a2 Step 8/10 : CMD echo $MYPATH —-> Running in 44f2eb41253f Removing intermediate container 44f2eb41253f —-> 77875e680c66 Step 9/10 : CMD echo “——end——“ —-> Running in 0d852a5a41ba Removing intermediate container 0d852a5a41ba —-> 6accda5d54d3 Step 10/10 : CMD /bin/bash —-> Running in ebce2e1a01ca Removing intermediate container ebce2e1a01ca —-> e49ddd3b677c Successfully built e49ddd3b677c Successfully tagged mycentos:0.1

  1. <a name="vnndp"></a>
  2. ## 3、测试运行
  3. - 原始centos
  4. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630621203889-0e8e555a-74b9-40cb-9d8f-e8278b893cc4.png#clientId=uae9f3b81-845c-4&from=paste&height=126&id=u34919aea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=189&originWidth=930&originalType=binary&ratio=1&size=25914&status=done&style=none&taskId=u750ba35f-4eaa-4b84-83ad-5adc981dde1&width=619)
  5. - `**docker run -it mycentos:0.1**`,`**docker run**`命令如果指定了参数会把CMD里的参数覆盖。这里说明一下,如:`**docker run -it mycentos:0.1 /bin/echo hello**` 命令的参数是指`**/bin/echo hello**`而非`**-it**`,`**-it**`只是docker的参数,而不是容器的参数,因此如果使用此命令,会覆盖CMD的`**/bin/bash**`,输出hello。而这里没有指定参数,因此直接就进入了/bin/bash,而不需要像平时一样`**docker run -it mycentos:0.1 /bin/bash**`多写一个`**/bin/bash**`。想要运行多个命令,可以使用ENTRYPOINT 指令 指定一个文件,文件中写多个指令即可。
  6. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630622313448-12eb8601-61a0-44c9-b88f-f63653b463a8.png#clientId=uae9f3b81-845c-4&from=paste&height=71&id=ubc161a6b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=74&originWidth=807&originalType=binary&ratio=1&size=8742&status=done&style=none&taskId=u1fc80776-01c9-481a-a0e2-fafb056b0a5&width=772.5)
  7. - 新的centos
  8. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630621296977-89dc3871-3765-4b51-be40-a3883414548e.png#clientId=uae9f3b81-845c-4&from=paste&height=461&id=u8b7456d3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=701&originWidth=927&originalType=binary&ratio=1&size=103995&status=done&style=none&taskId=u90276aa9-8ef1-4e30-bfa3-20a617afe5a&width=609.5)
  9. - 另外,还可以通过`**docker history 镜像ID/镜像名称**`查看镜像的构造历史
  10. - `**docker history mycentos:0.1**`,可以看到,最终的centos镜像是一层一层叠加起来的,很符合这个理念图
  11. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630621408296-3ee42b9c-d88c-4b85-ad4d-3c59f602ba82.png#clientId=uae9f3b81-845c-4&from=paste&height=196&id=u45a6b04b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=310&originWidth=1008&originalType=binary&ratio=1&size=61718&status=done&style=none&taskId=u3cd09e76-b225-4541-920d-038e893bca4&width=638)<br />![](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630378194134-f0a43a44-9cb2-42da-9175-edcc615c4fe6.png?x-oss-process=image%2Fresize%2Cw_846%2Climit_0#from=url&id=mfXeD&margin=%5Bobject%20Object%5D&originHeight=274&originWidth=846&originalType=binary&ratio=1&status=done&style=none)
  12. <a name="w6MQn"></a>
  13. # 六、CMD和ENTRYPOINT区别
  14. <a name="zLStA"></a>
  15. ## 1、CMD
  16. ```shell
  17. #构建DockerFile文件
  18. [root@VM-0-15-centos dockerfile]# vim docker-file-cmd
  19. #Dockerfile内容
  20. FROM centos
  21. CMD ["ls","-a"]
  22. #构建镜像
  23. [root@VM-0-15-centos dockerfile]# docker build -f docker-file-cmd -t cmdtest .
  24. Sending build context to Docker daemon 3.072kB
  25. Step 1/2 : FROM centos
  26. ---> 300e315adb2f
  27. Step 2/2 : CMD ["ls","-a"]
  28. ---> Running in 9f3bac8d1665
  29. Removing intermediate container 9f3bac8d1665
  30. ---> 23a0e7ffae6a
  31. Successfully built 23a0e7ffae6a
  32. Successfully tagged cmdtest:latest
  33. #启动容器,调用了ls -a
  34. [root@VM-0-15-centos dockerfile]# docker run cmdtest
  35. .
  36. ..
  37. .dockerenv
  38. bin
  39. dev
  40. etc
  41. home
  42. lib
  43. lib64
  44. lost+found
  45. media
  46. mnt
  47. opt
  48. proc
  49. root
  50. run
  51. sbin
  52. srv
  53. sys
  54. tmp
  55. usr
  56. var
  57. #想着实现ls -a -l的效果,直接在后面加入-l,那么-l就覆盖了ls -a,因此失败了
  58. [root@VM-0-15-centos dockerfile]# docker run cmdtest -l
  59. docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
  60. #正确的方法实现ls -a -l的效果
  61. [root@VM-0-15-centos dockerfile]# docker run cmdtest ls -al
  62. total 56
  63. drwxr-xr-x 1 root root 4096 Sep 2 23:28 .
  64. drwxr-xr-x 1 root root 4096 Sep 2 23:28 ..
  65. -rwxr-xr-x 1 root root 0 Sep 2 23:28 .dockerenv
  66. lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
  67. drwxr-xr-x 5 root root 340 Sep 2 23:28 dev
  68. drwxr-xr-x 1 root root 4096 Sep 2 23:28 etc
  69. drwxr-xr-x 2 root root 4096 Nov 3 2020 home
  70. lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
  71. lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
  72. drwx------ 2 root root 4096 Dec 4 2020 lost+found
  73. drwxr-xr-x 2 root root 4096 Nov 3 2020 media
  74. drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
  75. drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
  76. dr-xr-xr-x 148 root root 0 Sep 2 23:28 proc
  77. dr-xr-x--- 2 root root 4096 Dec 4 2020 root
  78. drwxr-xr-x 11 root root 4096 Dec 4 2020 run
  79. lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
  80. drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
  81. dr-xr-xr-x 13 root root 0 Sep 2 23:28 sys
  82. drwxrwxrwt 7 root root 4096 Dec 4 2020 tmp
  83. drwxr-xr-x 12 root root 4096 Dec 4 2020 usr
  84. drwxr-xr-x 20 root root 4096 Dec 4 2020 var
  85. [root@VM-0-15-centos dockerfile]#

2、ENTRYPOINT

  1. #构建DockerFile文件
  2. [root@VM-0-15-centos dockerfile]# vim docker-file-entrypoint
  3. #Dockerfile内容
  4. FROM centos
  5. ENTRYPOINT ["ls","-a"]
  6. #构建镜像
  7. [root@VM-0-15-centos dockerfile]# docker build -f docker-file-entrypoint -t entrypointtest .
  8. Sending build context to Docker daemon 4.096kB
  9. Step 1/2 : FROM centos
  10. ---> 300e315adb2f
  11. Step 2/2 : ENTRYPOINT ["ls","-a"]
  12. ---> Running in df8bced1251d
  13. Removing intermediate container df8bced1251d
  14. ---> 0691387ed2a7
  15. Successfully built 0691387ed2a7
  16. Successfully tagged entrypointtest:latest
  17. #启动容器,调用了ls -a
  18. [root@VM-0-15-centos dockerfile]# docker run entrypointtest
  19. .
  20. ..
  21. .dockerenv
  22. bin
  23. dev
  24. etc
  25. home
  26. lib
  27. lib64
  28. lost+found
  29. media
  30. mnt
  31. opt
  32. proc
  33. root
  34. run
  35. sbin
  36. srv
  37. sys
  38. tmp
  39. usr
  40. var
  41. #想着实现ls -a -l的效果,直接在后面加入-l,那么ls -a就追加了-l,因此成功了
  42. [root@VM-0-15-centos dockerfile]# docker run entrypointtest -l
  43. total 56
  44. drwxr-xr-x 1 root root 4096 Sep 2 23:32 .
  45. drwxr-xr-x 1 root root 4096 Sep 2 23:32 ..
  46. -rwxr-xr-x 1 root root 0 Sep 2 23:32 .dockerenv
  47. lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
  48. drwxr-xr-x 5 root root 340 Sep 2 23:32 dev
  49. drwxr-xr-x 1 root root 4096 Sep 2 23:32 etc
  50. drwxr-xr-x 2 root root 4096 Nov 3 2020 home
  51. lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
  52. lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
  53. drwx------ 2 root root 4096 Dec 4 2020 lost+found
  54. drwxr-xr-x 2 root root 4096 Nov 3 2020 media
  55. drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
  56. drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
  57. dr-xr-xr-x 150 root root 0 Sep 2 23:32 proc
  58. dr-xr-x--- 2 root root 4096 Dec 4 2020 root
  59. drwxr-xr-x 11 root root 4096 Dec 4 2020 run
  60. lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
  61. drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
  62. dr-xr-xr-x 13 root root 0 Sep 2 23:28 sys
  63. drwxrwxrwt 7 root root 4096 Dec 4 2020 tmp
  64. drwxr-xr-x 12 root root 4096 Dec 4 2020 usr
  65. drwxr-xr-x 20 root root 4096 Dec 4 2020 var
  66. #ls -a追加ls -al变成了ls -a ls -al,因此失败
  67. [root@VM-0-15-centos dockerfile]# docker run entrypointtest ls -al
  68. ls: cannot access 'ls': No such file or directory

七、实战:Tomcat镜像

1、文件准备

  • 准备镜像文件,tomcat压缩包(官网下载),jdk压缩包(官网下载),新建一个空的readme.txt文件
  • 也可用我下载好的,百度网盘链接:https://pan.baidu.com/s/1QjtWSmtvss5fUUex5I_ISQ 提取码:ccfj

image.png

2、编写dockerfile文件

  • 官方命名 Dockerfile ,build的时候会自动寻找这个文件,就不需要-f指定了 ```dockerfile FROM centos MAINTAINER xdd123456789@qq.com

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u301-linux-x64.tar.gz /usr/local ADD apache-tomcat-10.0.10.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local WORKDIR $MYPATH

注意这个如果用的跟我一样必须是jdk1.8.0_301,不然后面会报错运行不起来tomcat,深刻教训

错误示范:ENV JAVA_HOME /usr/local/jdk8u301 我想当然的就设置了个名字,结果是错的

解压后的名字为jdk1.8.0_301,因此这里最好也设置jdk1.8.0_301

ENV JAVA_HOME /usr/local/jdk1.8.0_301 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-10.0.10 ENV CATALINA_BASH /usr/local/apache-tomcat-10.0.10 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

tail -F:等同于—follow=name —retry,根据文件名进行追踪,并保持重试,即该文件被删除或改名后,如果再次创建相同的文件名,会继续追踪

CMD /usr/local/apache-tomcat-10.0.10/bin/startup.sh && tail -F /usr/local/apache-tomcat-10.0.10/logs/catalina.out

  1. <a name="JLLdf"></a>
  2. ## 3、构建镜像
  3. - `**docker build -t diytomcat .**`
  4. ```shell
  5. [root@VM-0-15-centos tomcat]# docker build -t diytomcat .
  6. Sending build context to Docker daemon 157.4MB
  7. Step 1/15 : FROM centos
  8. ---> 300e315adb2f
  9. Step 2/15 : MAINTAINER xdd<123456789@qq.com>
  10. ---> Running in d3da61a8177a
  11. Removing intermediate container d3da61a8177a
  12. ---> 9e1df92badf0
  13. Step 3/15 : COPY readme.txt /usr/local/readme.txt
  14. ---> 22fc0081ce2d
  15. Step 4/15 : ADD jdk-8u301-linux-x64.tar.gz /usr/local
  16. ---> f4ec24113686
  17. Step 5/15 : ADD apache-tomcat-10.0.10.tar.gz /usr/local
  18. ---> a1b470e2bd7d
  19. Step 6/15 : RUN yum -y install vim
  20. ---> Running in 614daf07d5b9
  21. CentOS Linux 8 - AppStream 9.0 MB/s | 8.8 MB 00:00
  22. CentOS Linux 8 - BaseOS 8.2 MB/s | 5.6 MB 00:00
  23. CentOS Linux 8 - Extras 11 kB/s | 10 kB 00:00
  24. Last metadata expiration check: 0:00:01 ago on Sat Sep 4 16:37:32 2021.
  25. Dependencies resolved.
  26. ================================================================================
  27. Package Arch Version Repository Size
  28. ================================================================================
  29. Installing:
  30. vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M
  31. Installing dependencies:
  32. gpm-libs x86_64 1.20.7-17.el8 appstream 39 k
  33. vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
  34. vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
  35. which x86_64 2.21-12.el8 baseos 49 k
  36. Transaction Summary
  37. ================================================================================
  38. Install 5 Packages
  39. Total download size: 7.8 M
  40. Installed size: 30 M
  41. Downloading Packages:
  42. (1/5): gpm-libs-1.20.7-17.el8.x86_64.rpm 328 kB/s | 39 kB 00:00
  43. (2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 824 kB/s | 48 kB 00:00
  44. (3/5): which-2.21-12.el8.x86_64.rpm 876 kB/s | 49 kB 00:00
  45. (4/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 4.9 MB/s | 1.4 MB 00:00
  46. (5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 16 MB/s | 6.3 MB 00:00
  47. --------------------------------------------------------------------------------
  48. Total 3.1 MB/s | 7.8 MB 00:02
  49. warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-17.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
  50. CentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00
  51. Importing GPG key 0x8483C65D:
  52. Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
  53. Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
  54. From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
  55. Key imported successfully
  56. Running transaction check
  57. Transaction check succeeded.
  58. Running transaction test
  59. Transaction test succeeded.
  60. Running transaction
  61. Preparing : 1/1
  62. Installing : which-2.21-12.el8.x86_64 1/5
  63. Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5
  64. Installing : vim-common-2:8.0.1763-15.el8.x86_64 3/5
  65. Installing : gpm-libs-1.20.7-17.el8.x86_64 4/5
  66. Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64 4/5
  67. Installing : vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
  68. Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
  69. Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5
  70. Verifying : gpm-libs-1.20.7-17.el8.x86_64 1/5
  71. Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5
  72. Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5
  73. Verifying : vim-filesystem-2:8.0.1763-15.el8.noarch 4/5
  74. Verifying : which-2.21-12.el8.x86_64 5/5
  75. Installed:
  76. gpm-libs-1.20.7-17.el8.x86_64 vim-common-2:8.0.1763-15.el8.x86_64
  77. vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarch
  78. which-2.21-12.el8.x86_64
  79. Complete!
  80. Removing intermediate container 614daf07d5b9
  81. ---> 05882b638556
  82. Step 7/15 : ENV MYPATH /usr/local
  83. ---> Running in 6f9ed4aba243
  84. Removing intermediate container 6f9ed4aba243
  85. ---> 73f831aacc97
  86. Step 8/15 : WORKDIR $MYPATH
  87. ---> Running in 061a96c81eab
  88. Removing intermediate container 061a96c81eab
  89. ---> 979f862d9edc
  90. Step 9/15 : ENV JAVA_HOME /usr/local/jdk-8u301
  91. ---> Running in 4a4f4a989d55
  92. Removing intermediate container 4a4f4a989d55
  93. ---> 606ed59a4fa1
  94. Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  95. ---> Running in 489c658ba9b4
  96. Removing intermediate container 489c658ba9b4
  97. ---> b43e29dd6f13
  98. Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-10.0.10
  99. ---> Running in 55dacf225f4d
  100. Removing intermediate container 55dacf225f4d
  101. ---> 8a4dd8f3878b
  102. Step 12/15 : ENV CATALINA_BASH /usr/local/apache-tomcat-10.0.10
  103. ---> Running in 896ab8940179
  104. Removing intermediate container 896ab8940179
  105. ---> 480c915facd1
  106. Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
  107. ---> Running in 170db3cfd12a
  108. Removing intermediate container 170db3cfd12a
  109. ---> ac5dfb75ad04
  110. Step 14/15 : EXPOSE 8080
  111. ---> Running in dd55e8c200aa
  112. Removing intermediate container dd55e8c200aa
  113. ---> 953bd5a52b36
  114. Step 15/15 : CMD /usr/local/apache-tomcat-10.0.10/bin/startup.sh && tail -F /usr/local/apache-tomcat-10.0.10/logs/catalina.out
  115. ---> Running in e8f0c4722972
  116. Removing intermediate container e8f0c4722972
  117. ---> ec6d3a066471
  118. Successfully built ec6d3a066471
  119. Successfully tagged diytomcat:latest

image.png

4、启动镜像

  • **docker run -d -p 9090:8080 --name xdddiytomcat -v /home/tomcat/test:/usr/local/apache-tomcat-10.0.10/webapps/test -v /home/tomcat/tomcatlogs/:/usr/local/apache-tomcat-10.0.10/logs diytomcat**

    5、测试访问

  • 添加入站规则

image.png

  • 测试访问,但是发现出错了

    1. [root@VM-0-15-centos tomcat]curl localhost:9090
    2. curl: (56) Recv failure: connection reset by peer
  • 进入容器查看日志,发现jdk的启动路径写错了。导致当我启动tomcat启动不起来

image.png

  • 那就将错就错,进入容器把目录名字改成我设置的错的名字就能找到目录了,设置好后重启容器,再次访问即可

    1. [root@VM-0-15-centos tomcat]# docker exec -it 717 /bin/bash
    2. [root@717d4ac1437a local]# ls
    3. apache-tomcat-10.0.10 bin etc games include jdk1.8.0_301 lib lib64 libexec readme.txt sbin share src
    4. [root@717d4ac1437a local]# mv jdk1.8.0_301 jdk-8u301
    5. [root@717d4ac1437a local]# exit
    6. [root@VM-0-15-centos tomcat]# docker restart 717
    7. 717
    8. [root@VM-0-15-centos tomcat]# curl localhost:9090

    image.png

  • 注意:因为我这里Dockerfile就写错了,生成出来的镜像的路径肯定每次也是错的,因此最好重写Dockerfile重新生成镜像,避免每次都要修改路径才能启动tomcat

    6、发布项目

  • 由于做了卷挂载,我们直接在本地编写项目就可以发布了 ```xml [root@VM-0-15-centos tomcat]cd /home [root@VM-0-15-centos home]# ls ceshi mysql tomcat www [root@VM-0-15-centos home]# cd tomcat [root@VM-0-15-centos tomcat]# ls test tomcatlogs [root@VM-0-15-centos tomcat]# cd test [root@VM-0-15-centos test]# mkdir WEB-INF [root@VM-0-15-centos test]# cd WEB-INF/ [root@VM-0-15-centos WEB-INF]# vim web.xml

<?xml version=”1.0” encoding=”UTF-8”?>

  1. ```jsx
  2. [root@VM-0-15-centos WEB-INF]# cd ..
  3. [root@VM-0-15-centos test]# ls
  4. WEB-INF
  5. [root@VM-0-15-centos test]# vim index.jsp
  6. <%@ page language="java" contentType="text/html; charset=UTF-8"
  7. pageEncoding="UTF-8"%>
  8. <!DOCTYPE html>
  9. <html>
  10. <head>
  11. <meta charset="utf-8">
  12. <title>Hello,小叮当</title>
  13. </head>
  14. <body>
  15. Hello World!<br/>
  16. <%
  17. out.println("你的 IP 地址 " + request.getRemoteAddr());
  18. System.out.println("----my test web logs----");
  19. %>
  20. </body>
  21. </html>
  • 访问成功**http://IP地址:9090/test**

image.png

  • 查看日志文件,也能看到响应记录
    1. [root@VM-0-15-centos tomcat]# cd tomcatlogs
    2. [root@VM-0-15-centos tomcatlogs]# ls
    3. catalina.2021-09-04.log catalina.out localhost.2021-09-04.log localhost_access_log.2021-09-04.txt
    4. [root@VM-0-15-centos tomcatlogs]# cat catalina.out
    image.png