热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

使用Dockerfile构建自己的镜像

Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。使用dockerbuild命令可以根据Dockerfile里面的指令编排来打包定制我

Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。使用docker build命令可以根据Dockerfile里面的指令编排来打包定制我们自己的docker镜像,首先我们来看一个通用的例子,制作自己的nginx镜像。


1.构建nginx镜像

# Base image
FROM centos:7
# MAINTAINER
MAINTAINER cbmiao
# 将nginx以及pcre源代码加入镜像
ADD nginx-1.20.1.tar.gz /usr/local/src/
ADD pcre-8.45.tar.gz /usr/local/src/
# 安装编译器
RUN yum install -y gcc gcc-c++ make openssl-devel lsof
RUN useradd -s /sbin/nologin -M nginx
# 指定工作目录
WORKDIR /usr/local/src/nginx-1.20.1/
# 编译nginx
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.45 && make && make install
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
# 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH
# 暴露80端口
EXPOSE 80
# 容器默认启动命令
ENTRYPOINT ["nginx"]

以上是通过Dockerfile来定制我们自己的nginx的Dockerfile,包含了如下指令:


2. Dockerfile基本格式


2.1 FROM指令

FROM指令用于指定基础镜像,必须为Dockerfile的第一个指令

# 格式:
# FROM
# FROM :
# 示例:
FROM mysql:5.7
# 注意:
# tag是可选的,如果不使用tag,则默认会使用latest版本的基础镜像

参数解释:



  • FROM mysql:5.7:第一行必须指定 基础镜像信息




2.2 MAINTAINER 指令

用于说明镜像维护者的信息,名字,邮箱,联系方式,实例如下

# 格式:
# MAINTAINER
# 示例:
MAINTAINER Michael Miu
MAINTAINER miaocbin@126.com
MAINTAINER Michael Miu

2.3 COPY|ADD指令

这两个命令的用法类似,都可以用于添加本地文件到镜像中(同样需求下,官方推荐使用 COPY),功能也类似,如:



  • 源路径可以有多个,相对于执行build的路径,如果源路径是一个目录,则该目录下面的所有内容都会被加入到容器,但目录本身不会被加入到容器;

  • 目标路径:必须是绝对路径或者相对于WORKDIR的相对路径;若目标路径不存在,则会自动创建完整路径;目标路径如果是文件夹,则必须已/结尾;

  • 路径中可以使用通配符

二者区别如下:



  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。

  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

  • COPY:指令能够将构建命令所在的主机本地的文件或目录,复制到镜像文件系统。

  • ADD:指令不仅能够将构建命令所在的主机本地的文件或目录,而且能够将远程URL所对应的文件或目录,作为资源复制到镜像文件系统。
    所以,可以认为ADD是增强版的COPY,支持将远程URL的资源加入到镜像的文件系统。

# 格式:
# ADD|COPY ...
# 示例:
ADD|COPY tes* /mydir/ # 添加所有以"tes"开头的文件
ADD|COPY test mydir/ # 添加 "test" 到 WORKDIR/mydir/
ADD|COPY test /opt/ # 添加 "test" 到 /opt/
# [--chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

说明:



  1. 对于从远程URL获取资源的情况,由于ADD指令不支持认证,如果从远程获取资源需要认证,则只能使用RUN wget或RUN curl替代。

  2. 如果源路径的资源发生变化,则该ADD指令将使Docker Cache失效,Dockerfile中后续的所有指令都不能使用缓存。因此尽量将ADD指令放在Dockerfile的后面。

  3. <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。

  4. <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。


2.4 WORKDIR

指定工作目录,通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。(WORKDIR 指定的工作目录,必须是提前创建好的)

# 格式:
# WORKDIR /path/to/workdir
# 示例:
WORKDIR /abc (这时工作目录为/abc)

2.5 RUN

构建镜像过程中执行命令(注意:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache)

# 格式:
# RUN
# 示例:
RUN yum -y install nginx
RUN pip install djaong
RUN mkdir test && rm -rf /var/lib/testfile

2.6 CMD

类似于RUN指令,用于运行程序,但二者运行的时间点不同:



  • CMD:用于指定在容器启动时所要执行的命令,在docker run 时运行。

  • RUN:RUN用于指定镜像构建时所要执行的命令,是在 docker build时运行。

作用:为启动的容器指定默认要运行的程序,也就是在容器启动时才进行调用。程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

# 格式:
# CMD ["executable","param1","param2"] (执行可执行文件,优先)
# CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
# CMD command param1 param2 (执行shell内部命令)
# 示例:
CMD ["/usr/bin/wc","--help"]
CMD ping www.baidu.com

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。


2.7 ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。

# 格式:
# ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
# ENTRYPOINT command param1 param2 (shell内部命令)
# 示例:
ENTRYPOINT ["/usr/bin/wc","--help"]

注意:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。


2.8 ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

# 格式:
# ENV
# ENV =
# 示例:
ENV myName John
ENV myCat=tomcat

2.9 EXPOSE指令

声明端口,作用如下:



  • 1)帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;

  • 2)在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口;但是,EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口。

  • 3)docker ps的时候看到的PORTS字段信息就是这里声明的信息;

  • 4)需要说明的是,即便这里不写EXPOSE指令,也不影响镜像构建和运行,只是会导致其他的使用者不清楚镜像监听的端口,使用的时候映射端口没有那么直观。

# 格式:
# EXPOSE

[

...]
# 示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp

2.10 LABEL指令

用来给镜像添加一些元数据(metadata),以键值对的形式

# 语法格式:
# LABEL = = = ...
# 例如:添加镜像作者
LABEL org.opencontainers.image.authors="runoob"

2.11 VOLUME指令

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。作用:



  • 避免重要的数据,因容器重启而丢失,这是非常致命的。

  • 避免容器不断变大。

# 格式:
# VOLUME ["<路径1>", "<路径2>"...]
# VOLUME <路径>
# 举例:
VOLUME [/var/lib/mysql]

3. Dockerfile镜像构建命令

利用Dockerfile构建自己的镜像命令

docker build . -t ImageName:ImageTag -f Dockerfile


  • . 是上下文路径

  • 上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。



解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。

如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。

注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。


3.1 执行构建过程

docker build . -t my-nginx:v1.20.1 -f Dockerfile
Sending build context to Docker daemon 3.163MB
Step 1/13 : FROM centos:7
---> 8652b9f0cb4c
Step 2/13 : LABEL maintainer="cbmiao "
---> Using cache
---> 16c2487146bc
Step 3/13 : ENV DEBIAN_FRONTEND noninteractive
---> Using cache
---> 5f3132177398
Step 4/13 : ADD nginx-1.20.1.tar.gz /usr/local/src/
---> Using cache
---> 116344a28ea2
Step 5/13 : ADD pcre-8.45.tar.gz /usr/local/src
---> Using cache
---> 23451b87c29b
Step 6/13 : RUN yum install -y wget gcc gcc-c++ make openssl-devel
---> Using cache
---> dcaa1cbaf4bd
Step 7/13 : RUN useradd -s /sbin/nologin -M nginx
---> Using cache
---> e0ace7f20ffc
Step 8/13 : WORKDIR /usr/local/src/nginx-1.20.1/
---> Using cache
---> d437722febe2
Step 9/13 : RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.45 && make && make install
---> Using cache
---> 307b6228d110
Step 10/13 : RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
---> Using cache
---> dc8e0e800987
Step 11/13 : ENV PATH /usr/local/nginx/sbin:$PATH
---> Using cache
---> e5a1119dced2
Step 12/13 : EXPOSE 80
---> Using cache
---> 63c669be20e4
Step 13/13 : ENTRYPOINT ["nginx"]
---> Using cache
---> 391f75b825bd
Successfully built 391f75b825bd
Successfully tagged my-nginx:v1.20.1

3.2 查看构建结果

docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
my-nginx v1.20.1 391f75b825bd 17 minutes ago 490MB

3.3 运行镜像

# 利用我们刚构建的镜像来启动容器
docker run -d --name nginx-test my-nginx:v1.20.1
348a73f420181c36abf7a99c958ed76862503e930793331ab819629ea2bdc4a2
# 进入容器查看nginx状态
docker exec -ti nginx-test bash
[root@348a73f42018 nginx-1.20.1]#
# 确认80端口
[root@348a73f42018 nginx-1.20.1]# lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1 root 6u IPv4 645923 0t0 TCP *:http (LISTEN)
# 确认nginx进程已经启动成功
[root@348a73f42018 nginx-1.20.1]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 46096 3280 ? Ss 05:43 0:00 nginx: master process nginx
nginx 7 0.0 0.0 46532 1880 ? S 05:43 0:00 nginx: worker process
root 8 0.2 0.0 11828 1908 pts/0 Ss 05:43 0:00 bash
root 26 0.0 0.0 51732 1712 pts/0 R+ 05:43 0:00 ps aux
# 访问nginx也正常
[root@348a73f42018 nginx-1.20.1]# curl localhost







Welcome to nginx!

If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.

For online documentation and support please refer to
nginx.org.

Commercial support is available at
nginx.com.

Thank you for using nginx.



若想让我们的nginx向外提供服务,还需要在启动容器时,将端口映射到主机,然后我们通过主机IP加上映射端口,就可以访问了

docker run -d --name nginx-test1 -p 80:80 my-nginx:v1.20.1

以上就添加了一个[-p 80:80]参数,将容器内的nginx的80端口,映射到宿主机。然后我们就可以通过宿主机的IP加上80端口访问刚才启动的nginx容器里的nginx服务,有关docker启动容器有不清楚的,可以看我的另外一篇博客:Docker简介及基本使用


4. Dockerfile构建镜像的原则



  • 不必要的内容不要放在镜像中:以免增大镜像,同时也带来安全隐患;



  • 减少不必要的层文件



  • 减少网络传输操作:尽量使用本地文件,加快镜像构建速度,特别是后面我们将利用Jenkins做自动化构建的时候;



  • 可以适当的包含一些调试命令




5. JAR包制作成docker镜像实例

FROM java:8u211
ENV JAVA_OPTS "\
-Xmx4096m \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=256m"
ENV JAVA_HOME /usr/local/java
ENV PATH ${PATH}:${JAVA_HOME}/bin
COPY target/myweb.jar myweb.jar
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
EXPOSE 8080
CMD java ${JAVA_OPTS} -jar myweb.jar

 









人们永远没有足够的时间把它做好,但永远有足够的时间重新来过。

可是,因为并不是总有机会重做一遍,你必须做得更好,换句话说,

人们永远没有足够的时间去考虑到底是不是想要它,但永远有足够的时间去为之后悔。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

浅掘千口井,不如深挖一口井!当知识支撑不了野心时,那就静下心来学习吧!运维技术交流QQ群:618354452

个人微信公众号,定期发布技术文章和运维感悟。欢迎大家关注交流。







推荐阅读
  • docker镜像重启_docker怎么启动镜像dock ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 本文深入探讨了 Redis 的两种持久化方式——RDB 快照和 AOF 日志。详细介绍了它们的工作原理、配置方法以及各自的优缺点,帮助读者根据具体需求选择合适的持久化方案。 ... [详细]
  • 科研单位信息系统中的DevOps实践与优化
    本文探讨了某科研单位通过引入云原生平台实现DevOps开发和运维一体化,显著提升了项目交付效率和产品质量。详细介绍了如何在实际项目中应用DevOps理念,解决了传统开发模式下的诸多痛点。 ... [详细]
  • 20100423:Fixes:更新批处理,以兼容WIN7。第一次系统地玩QT,于是诞生了此预备式:【QT版本4.6.0&#x ... [详细]
  • 本文介绍了一种在 MySQL 客户端执行 NOW() 函数时出现时间偏差的问题,并详细描述了如何通过配置文件调整时区设置来解决该问题。演示场景中,假设当前北京时间为2023年2月17日19:31:37,而查询结果显示的时间比实际时间晚8小时。 ... [详细]
  • Struts与Spring框架的集成指南
    本文详细介绍了如何将Struts和Spring两个流行的Java Web开发框架进行整合,涵盖从环境配置到代码实现的具体步骤。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 深入理解 .NET 中的中间件
    中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
  • 本文详细介绍了如何将 Python 3.6.3 程序转换为 Windows 可执行文件(.exe),并解决了使用 py2exe 和 cx_Freeze 时遇到的问题。推荐使用 PyInstaller 进行打包,提供完整的安装和打包步骤。 ... [详细]
  • 本文探讨了如何通过预处理器开关选择不同的类实现,并解决在特定情况下遇到的链接器错误。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 深入理解ExtJS:从入门到精通
    本文详细介绍了ExtJS的功能及其在大型企业前端开发中的应用。通过实例和详细的文件结构解析,帮助初学者快速掌握ExtJS的核心概念,并提供实用技巧和最佳实践。 ... [详细]
  • HTML基础入门指南
    本文将深入浅出地介绍HTML的基础知识,包括其定义、开发工具、制定机构、特性、基本标签及更多实用内容。 ... [详细]
  • 深入解析Docker镜像的工作机制
    本文旨在深入探讨Docker镜像的内部结构及其工作机制,包括镜像的分层体系、联合文件系统(UnionFS)的应用,以及各层如bootfs和rootfs的具体作用。 ... [详细]
author-avatar
mobiledu2502870747
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有