docker入门(八)—— dockerfile详细先容,编写dockerfile

打印 上一主题 下一主题

主题 876|帖子 876|积分 2628

dockerfile(重点)

大家想想,Nginx,tomcat,mysql 这些镜像都是哪里来的?官方能写,我们不能写吗?
我们要研究本身如何做一个镜像,而且我们写的微服务项目打包上云部署,docker 就是最方便的。
微服务打包成镜像,任何装了 docker 的地方,都可以下载利用,极其方便。
流程:开辟应用 => 编写 dockerfile => 打包为镜像 => 上传到堆栈(私有堆栈公司内部,公有堆栈 dockerhub)=> 下载镜像 => 启动运行。
还可以方便移植!
什么是 dockerfile

dockerfile 是一种用于界说和构建 docker 镜像的文本文件。它包含一系列的指令和参数,用于形貌镜像的构建过程,包括基础映像、软件包安装、文件拷贝、情况变量设置等。
通过编写 dockerfile,可以将应用程序、情况和依赖项打包成一个独立的容器镜像,使其可以在不同的情况宁静台上运行,实现应用程序的可移植性和可扩展性。
dockerfile 的根本结构包括以下几个部门:


  • 基础映像(Base Image):利用 FROM 指令指定基础映像,作为构建镜像的出发点。基础映像通常包含了操作体系和一些预装的软件和工具。
  • 构建过程指令:利用一系列指令来形貌构建过程,例如 RUN 用于实行命令和安装软件包,COPY 用于拷贝文件和目录,ADD 用于拷贝和提取文件,WORKDIR 用于设置工作目录,等等。
  • 容器启动指令:利用 CMD 或 ENTRYPOINT 指令来界说容器启动时要实行的命令,也就是默认的容器实行命令。
通过编写 dockerfile,可以自界说构建过程,选择所需的软件和设置,以及设置情况变量、袒露端口等。dockerfile 的语法简单且易于明白,使得镜像的构建过程变得可重复和可维护。
总的来说,dockerfile 是界说和构建 docker 镜像的文本文件,通过编写指令和参数来形貌镜像的构建过程和设置,以实现应用程序的打包和部署。它是利用 docker 进行容器化开辟和部署的告急工具。
构建步骤:

  • 编写 dockerfile 文件
  • docker build 构建镜像
  • docker run 镜像
dockerfile 构建过程

基础知识:


  • 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  • 指令按照从上到下,顺序实行
  • # 体现注释
  • 每条指令都会创建一个新的镜像层,并对镜像进行提交
流程:

  • docker 从基础镜像运行一个容器
  • 实行一条指令并对容器做出修改
  • 实行类似 docker commit 的操作提交一个新的镜像层
  • docker 再基于刚提交的镜像运行一个新容器
  • 实行 dockerfile 中的下一条指令直到所有指令都实行完成!
阐明:
从应用软件的角度来看,dockerfile,docker 镜像与 docker 容器分别代表软件的三个不同阶段。


  • dockerfile 是软件的原材料(代码)
  • docker 镜像则是软件的交付品(.apk)
  • docker 容器则是软件的运行状态(客户下载安装实行)
dockerfile 面向开辟,docker 镜像成为交付尺度,docker 容器则涉及部署与运维,三者缺一不可!



  • dockerfile:必要界说一个 dockerfile,dockerfile 界说了历程必要的一切东西。dockerfile 涉及的内容包括实行代码大概是文件、情况变量、依赖包、运行时情况、动态链接库、操作体系的发行版、服务历程和内核历程(当引用进行必要和体系服务和内核历程打交道,这时必要思量如何计划 namespace 的权限控制)等等。
  • docker镜像:在 dockerfile 界说了一个文件之后,docker build 时会产生一个 docker 镜像,当运行 docker 镜像时,会真正开始提供服务;
  • docker容器:容器是直接提供服务的。
dockerfile 指令

关键字:
  1. FROM         # 基础镜像,当前新镜像是基于哪个镜像的
  2. MAINTAINER   # 镜像维护者的姓名混合邮箱地址
  3. RUN          # 容器构建时需要运行的命令
  4. EXPOSE       # 当前容器对外保留出的端口
  5. WORKDIR      # 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点
  6. ENV          # 用来在构建镜像过程中设置环境变量
  7. ADD          # 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
  8. COPY         # 类似ADD,拷贝文件和目录到镜像中!
  9. VOLUME       # 容器数据卷,用于数据保存和持久化工作
  10. CMD          # 指定一个容器启动时要运行的命令,dockerFile中可以有多个CMD指令,但只有最后一个生效!
  11. ENTRYPOINT   # 指定一个容器启动时要运行的命令!和CMD一样
  12. ONBUILD      # 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的ONBUILD被触发
复制代码

编写 dockerfile

dockerhub 中99%的镜像都是通过在 base 镜像(Scratch)中安装和设置必要的软件构建出来的
Scratch 镜像很赞,它简洁、小巧而且快速,它没有 bug、安全漏洞、延缓的代码或技术债务。除了被 docker 添加了 metadata 之外,它根本上是空的。
我们在利用 dockerfile 构建 docker 镜像时,一种方式是利用官方预先设置好的容器镜像。优点是我们不消从头开始构建,节省了许多工作量,但付出的代价是必要下载很大的镜像包。
如果我们的需求是在构建一个符合我们现实业务需求的 docker 镜像的条件下,确保镜像尺寸尽可能的小,应该怎么做呢?
思绪是利用空镜像 scratch,可以说是真正的从零开始构建属于本身的镜像,镜像的第一层
发布一个本身编写的 centos

由于阿里云官方的 centos 是不完整的,许多命令都没有(例如 vim、ipconfig 等),我们自界说一个 centos 镜像,,让它可以或许拥有这些命令
  1. # dockerfile文件名字可以任意取,最好为Dockerfile
  2. vim Dockerfile
复制代码
编写 dockerfile 如下:
  1. FROM centos7.9.2009
  2. MAINTAINER akuya<123456@qq.com>
  3. # 配置环境以及工作目录
  4. ENV MYPATH /usr/local
  5. WORKDIR $MYPATH
  6. # 安装vim、ipconfig等命令
  7. RUN yum -y install vim
  8. RUN yum -y install net-tools
  9. # 暴露端口
  10. EXPOSE 80
  11. CMD echo $MYPATH
  12. CMD echo "---akuya---"
  13. CMD /bin/bash
复制代码
由于最新版 centos8 有 bug,故利用 centos7.9版本
   根据 dockerfile 构建镜像
  1. docker build .
复制代码
参数:


  • -f:等价于--file,指定 dockerfile 文件
  • -t:等价于--tag,指定输出的镜像文件名:版本号
命令最后一定要加一个.
  1. # 构建镜像命令
  2. docker build -f Dockerfile -t mycentos:1.0 .
复制代码
  1. [root@iZbp15293q8kgzhur7n6kvZ home]# docker build -f Dockerfile -t mycentos:1.0 .
  2. [+] Building 54.3s (8/8) FINISHED                                                                                  docker:default
  3. => [internal] load build definition from Dockerfile                                                                         0.0s
  4. => => transferring dockerfile: 282B                                                                                         0.0s
  5. => [internal] load metadata for docker.io/library/centos:7.9.2009                                                          15.7s
  6. => [internal] load .dockerignore                                                                                            0.0s
  7. => => transferring context: 2B                                                                                              0.0s
  8. => [1/4] FROM docker.io/library/centos:7.9.2009@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987    10.0s
  9. => => resolve docker.io/library/centos:7.9.2009@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987     0.0s
  10. => => sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 1.20kB / 1.20kB                               0.0s
  11. => => sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f 529B / 529B                                   0.0s
  12. => => sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809ab675bb17ab3a16c517c9 2.75kB / 2.75kB                               0.0s
  13. => => sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc 76.10MB / 76.10MB                             6.1s
  14. => => extracting sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc                                    3.4s
  15. => [2/4] WORKDIR /usr/local                                                                                                 2.2s
  16. => [3/4] RUN yum -y install vim                                                                                            21.2s
  17. => [4/4] RUN yum -y install net-tools                                                                                       3.4s
  18. => exporting to image                                                                                                       1.7s
  19. => => exporting layers                                                                                                      1.7s
  20. => => writing image sha256:1e7fb59b8a162a54a01bc41930d654d7d474cbd7ade3d110f12d95727e1d193f                                 0.0s
  21. => => naming to docker.io/library/mycentos:1.0                                                                              0.0s
复制代码
  1. [root@iZbp15293q8kgzhur7n6kvZ home]# docker images                                                                                
  2. REPOSITORY   TAG       IMAGE ID       CREATED              SIZE                                                                  
  3. mycentos     1.0       1e7fb59b8a16   About a minute ago   708MB
  4. centos       latest    5d0da3dc9764   2 years ago          231MB
复制代码
根据这个镜像运行容器后发现并没有打印出目录/usr/local和---akuya---,这是由于 CMD 指令如果存在多个,只有最后一个会被实行
   docker history 检察镜像的变动历史
  如果你下载了一个镜像,报错了大概你想检察一些构建逻辑,利用 docker history
  1. [root@iZbp15293q8kgzhur7n6kvZ home]# docker history mycentos:1.0
  2. IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
  3. 1e7fb59b8a16   7 minutes ago   CMD ["/bin/sh" "-c" "/bin/bash"]                0B        buildkit.dockerfile.v0
  4. <missing>      7 minutes ago   CMD ["/bin/sh" "-c" "echo "---akuya---""]     0B        buildkit.dockerfile.v0
  5. <missing>      7 minutes ago   CMD ["/bin/sh" "-c" "echo $MYPATH"]             0B        buildkit.dockerfile.v0
  6. <missing>      7 minutes ago   EXPOSE map[80/tcp:{}]                           0B        buildkit.dockerfile.v0
  7. <missing>      7 minutes ago   RUN /bin/sh -c yum -y install net-tools # bu…   208MB     buildkit.dockerfile.v0
  8. <missing>      7 minutes ago   RUN /bin/sh -c yum -y install vim # buildkit    296MB     buildkit.dockerfile.v0
  9. <missing>      7 minutes ago   WORKDIR /usr/local                              0B        buildkit.dockerfile.v0
  10. <missing>      7 minutes ago   ENV MYPATH=/usr/local                           0B        buildkit.dockerfile.v0
  11. <missing>      7 minutes ago   MAINTAINER akuya<123456@qq.com>                 0B        buildkit.dockerfile.v0
  12. <missing>      2 years ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
  13. <missing>      2 years ago     /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
  14. <missing>      2 years ago     /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB     
复制代码
  项目中编写 dockerfile 思绪
  

  • 基于一个空的镜像
  • 下载必要的情况 ADD
  • 实行情况变量的设置 ENV
  • 实行一些Linux命令 RUN
  • 日志 CMD
  • 端口袒露 EXPOSE
  • 挂载数据卷 VOLUMES
这个过程就是你手动部署项目的过程,你通过 docker 可以再未来实现自动化构建。
CMD 与 ENTRYPOINT 区别

两个命令都是指定一个容器启动时要运行的命令,但二者有很大的区别


  • CMD:容器内有多个 CMD 指令时,只有最后一个 CMD 指令会见效,而如果在实行docker run命令时携带了别的命令,将会覆盖掉所有 dockerfile 的 CMD 指令
  • ENTRYPOINT:ENTRYPOINT 的命令不容易被覆盖。在docker run命令中提供的任何参数都会作为 ENTRYPOINT 命令的参数传递。
当两者组合利用时:那么 CMD 将作为 ENTRYPOINT 的默认参数,如果在docker run命令中提供了参数,它将覆盖 CMD 并作为 ENTRYPOINT 的参数传递。
例如:
  1. FROM centos
  2. CMD ["echo", "hello world"]
复制代码
运行容器时,可以覆盖默认的 CMD:
  1. docker build -f Dockerfile -t cmdtest .
  2. docker run cmdtest /bin/bash
复制代码
效果不会打印出hello world
利用 ENTRYPOINT 指令:
  1. FROM centos
  2. ENTRYPOINT ["echo", "hello "]
  3. CMD ["world"]
复制代码
运行容器时,可以传递参数给 ENTRYPOINT:
  1. docker build -f Dockerfile -t entrytest .
  2. docker run entrytest                   # 输出hello world
  3. docker run entrytest akuya        # 输出hello akuya
复制代码
训练:构建一个 tomcat,编写首页

利用空镜像从零构建一个完整的 tomcat
一般一个项目都在一个文件夹中,我们只必要在项目目录下编辑一个 Dockerfile 文件即可
当实行docker bulid指定时如果没有-f参数指定 dockerfile 文件,会默认探求项目目录下的 Dockerfile 来构建镜像,所以我们名字通常设定为Dockerfile
准备工作:准备 tomcat 和 jdk 的 jar 包,创建Dockerfile文件,以及一个任意内容的readme.md即可

编辑Dockerfile,内容如下:
  1. FROM centos:7.9.2009
  2. MAINTAINER akuya<123456@qq.com>
  3. # 宿主机目录下文件拷贝到容器内,文件如果不是绝对路径会默认寻找 dockerfile 文件的同级目录下,所以最好所有文件都在同一个目录下
  4. COPY readme.md /usr/local/readme.md
  5. # 添加我们自己的安装包
  6. ADD jdk-8u11-linux-x64.tar.gz /usr/local
  7. ADD apache-tomcat-9.0.22.tar.gz /usr/local
  8. #安装vim编辑器
  9. RUN yum -y install vim
  10. # 配置工作目录
  11. ENV MYPATH /usr/local
  12. WORKDIR $MYPATH
  13. # 配置环境变量
  14. ENV JAVA_HOME /usr/local/jdk1.8.0_11
  15. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  16. ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
  17. ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
  18. ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
  19. # 暴露端口
  20. EXPOSE 8080
  21. # 启动的时候自动运行tomcat,打印日志
  22. CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
复制代码
构建并运行:
  1. # 构建,不指定 dockerfile 文件会自动寻找该目录下的 Dockerfile
  2. docker build -t mytomcat .
  3. # 运行
  4. docker run -d -p 8080:8080 --name mytomcat \
  5. -v /root/mytomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test \
  6. -v /root/mytomcat/logs:/usr/local/apache-tomcat-9.0.22/logs \
  7. --privileged=true \
  8. mytomcat
复制代码
运行成功后打开浏览器,输入ip所在:8080,即可访问到 tomcat 主页

在我们自界说的 tomcat 服务器中上传一个项目,在本地挂载目录,丢一个项目上去。
起首辈入到我们挂载的宿主机目录下/root/mytomcat下
  1. [root@iZbp15293q8kgzhur7n6kvZ mytomcat]# cd /root/mytomcat/
  2. [root@iZbp15293q8kgzhur7n6kvZ mytomcat]# ll
  3. total 8
  4. drwxr-xr-x 2 root root 4096 Mar 21 14:45 logs
  5. drwxr-xr-x 2 root root 4096 Mar 21 14:45 test
复制代码
在 test 目录下丢项目即可
示例:编写一个index.html
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>docker test</title>
  6. </head>
  7. <body>
  8.     <h1>----------hello akuya----------------</h1>
  9.     <br>
  10.     <h2>my docker tomcattest</h2>
  11. </body>
  12. <script>
  13.     console.log("my docker tomcat log")
  14. </script>
  15. </html>
复制代码
浏览器访问ip所在:8080/test/

发布镜像

   公有堆栈:DockerHub
  现在 DockerHub 网址无法访问,相识即可
注册dockerhub https://hub.docker.com/signup,必要有一个账号
发布镜像遵循以下几个步骤:

  • 登录用户:
  1. docker login
复制代码
参数:


  • -u:等价于--username,登录所需的用户名
  • -p:等价于--password,密码

  • 给要上传的镜像打上标签
  1. docker tag 镜像id 镜像名:版本号
复制代码

  • 上传镜像
  1. docker push 镜像名:版本号
复制代码
私有堆栈,一般都是公司内部自行搭建的,步骤跟上述相同

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表