DockerFile | 简介

1.Dockerfile概念

Dockerfile是一个文本格式的配置文件,用于定义Docker镜像的内容和构建步骤。它包含一系列指令,每个指令代表一个构建步骤,从基础镜像开始,逐步构建出最终的镜像。通过Dockerfile,用户可以精确地描述应用程序运行环境的配置、依赖项安装、文件复制等操作。这使得应用程序的部署和分发变得更加可控和可重复。Dockerfile的内容可以根据需求自定义,允许开发者根据应用程序的特性和需求来灵活配置镜像的构建过程,从而实现高效、可靠的容器化部署

2.Dockerfile的优缺点

优点:

简化部署:Dockerfile 使得应用的部署过程变得标准化和可重复

容器为单位的应用交付:开发者可以将应用和它的依赖打包到一个容器中,这就意味着应用可以在任何支持 Docker 的机器上运行

易于维护:Dockerfile 是代码,所以有版本控制

易于理解:Dockerfile 是一种声明式语言,可以让用户理解镜像是如何构建的

高效:使用 Dockerfile 构建的镜像层可以高度重用,因此镜像的大小也会小

缺点:

构建时间:每次构建都会重新安装所有依赖,这可能会增加构建时间

构建大小:每一层都会增加最终镜像的大小

安全问题:如果在 Dockerfile 中使用错误的指令或者将敏感信息暴露在 Dockerfile中,可能会引起安全问题

3.基本结构

Dockerfile由一行行命令语句组成,并且支持以 # 开头的注释行。

一般而言,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

4.Dockerfile 指令详解

  1. FROM:指定基础镜像,用于后续的指令构建

该指令有两种格式:

FROM

指定基础image为该image的最后修改的版本。或者:

FROM :

指定基础image为该image的一个tag版本。

例如:FROM ubuntu:20.04

2.RUN:构建镜像时运行的指令

shell格式:就像在命令行中输入的Shell脚本命令一样。

RUN

exec格式:就像是函数调用的格式。

RUN ["executable", "param1", "param2"]

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大

RUN apt-get update && apt-get install -y nginx

3.CMD:容器启动时要运行的命令

包含三种语法格式,如下所示:

第一种就是shell这种执行方式和写法

CMD command param1 param2

第二种是可执行文件加上参数的形式(推荐)

CMD ["executable","param1","param2"]

该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

CMD ["","",...]

需要注意的是,一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用。CMD会被docker run之后的参数替换,如果我们在Dockerfile中指定了CMD指令,通过在docker run命令行中也指定了要运行的命令,命令行中的指令会覆盖Dockerfile中的CMD指令

4.COPY:从上下文目录中复制文件或者目录到容器里指定路径

COPY <源路径> <目标路径>

复制宿主机文件index.html到容器/data/html/index.html

COPY index.html /data/html/index.html

复制宿主机data目录下文件(包括子目录)到容器/data/目录下,并不会复制目录本身

例:COPY data /data/

5.ADD:ADD 指令和 COPY 的使用类似(同样需求下,官方推荐使用COPY),功能也类似。除 此之外,ADD还支持使用tar文件和URL路径,并且会将tar压缩文件(gzip, bzip2以及 xz格式) 解压缩,如果指定的是url,会从指定的url下载文件放到目录中(如果url下载的文件为tar文件,则不会展开)

ADD

例:ADD /data/src/nginx-1.14.0.tar.gz /data/src/

6.ENV:在容器内部设置环境变量

ENV=

例:ENV JAVA_HOME=/usr/local/jdk1.7.0_79

ENV PATH=JAVA_HOME/bin:PATH

7.ENTRYPOINT:设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。

当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2 (shell内部命令)

比如:

CMD指令将不会被执行,只有ENTRYPOINT指令被执行

CMD echo "Hello, World!"

ENTRYPOINT ls -l

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分。ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。

FROM centos7

CMD ["-l"]

ENTRYPOINT ["/usr/bin/ls"]

8.EXPOSE:EXPOSE指令用于告诉Docker容器监听哪些网络端口。在Dockerfile中使用EXPOSE指令并不会自动将容器的端口暴露出来,需要使用docker run命令的-p或者-P选项来映射容器内部端口到宿主机的端口

EXPOSE指令的语法格式为:

EXPOSE[/...]

其中,表示需要监听的端口号,可以是1-65535之间的整数;表示需要监听的协议,可以是tcp或udp。

如果需要监听多个端口,则可以在EXPOSE指令中多次指定端口号,或者使用","分隔多个端口号。

下面是一个示例:

FROM ubuntu:18.04

EXPOSE 80/tcp

EXPOSE 443/tcp

以上Dockerfile告诉Docker容器需要监听80和443端口,并使用tcp协议。在运行容器时,可以使用如下命令将容器内部的80端口映射到宿主机的8080端口:

docker run -p 8080:80 myimage

这样,就可以通过访问宿主机的8080端口来访问容器内部的80端口了

9.VOLUME:为容器创建挂载点或声明卷

作用:

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

避免容器不断变大。

格式:VOLUME ["<路径1>", "<路径2>"...]

VOLUME <路径>

定义一个匿名卷

FROM ubuntu:16.04

VOLUME /data

定义多个匿名卷

FROM ubuntu:16.04

VOLUME ["/data", "/command"]

使用VOLUME指令后,Docker会在容器中创建一个或多个匿名卷(anonymous volume),这些匿名卷将持久化存储容器中的数据。当容器删除时,这些匿名卷不会被自动删除,需要手动删除它们。

10.USER:用于指定执行后续命令的用户和用户组

格式:USER <用户名>[:<用户组>]

USER user

USER user:group

11.ONBUILD:用于延迟构建命令的执行。简单的说,就是Dockerfile里用ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的Dockerfile 使用了之前构建的镜像FROM test-buil,这时执行新镜像的Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令

格式:ONBUILD <其它指令>

ONBUILD RUN mkdir test

12.ARG:构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile内有效,也就是说只有docker build 的过程中有效,构建好的镜像内不存在此环境变量。构建命令docker build 中可以用 --build-arg <参数名>=<值> 来覆盖

格式:ARG <参数名>[=<默认值>]

13.WORKDIR:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录

格式:WORKDIR <工作目录路径>

WORKDIR /path/to/workdir

在 /p1/p2 下执行 vim a.txt

WORKDIR /p1 WORKDIR p2 RUN vim a.txt

14.LABEL:使用LABEL指令可以为镜像添加元数据,这些元数据可以包含关于镜像的描述、版本号、维护者信息等

LABEL指令的语法如下:

LABEL===...

比如我们可以添加镜像的作者:

LABEL org.opencontainers.image.authors="runoob"

15.HEALTHCHECK:用于指定某个程序或者指令来监控 docker 容器服务的运行状态是否正常

语法格式如下:

设置检查容器健康状况的命令

HEALTHCHECK [OPTIONS] CMD <命令>

如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK NONE

5.示例

相关推荐
超级小忍10 分钟前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
程序无bug14 分钟前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
小莫分享17 分钟前
Java Lombok 入门
java
程序无bug17 分钟前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队18 分钟前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端
苦学编程的谢32 分钟前
Maven
java·maven·intellij-idea
考虑考虑34 分钟前
Maven 依赖范围(Scope)
java·后端·maven
chao_78937 分钟前
回溯题解——子集【LeetCode】二进制枚举法
开发语言·数据结构·python·算法·leetcode
张小洛41 分钟前
Spring AOP 设计解密:代理对象生成、拦截器链调度与注解适配全流程源码解析
java·后端·spring·spring aop·aop
Wyc724091 小时前
SpringBoot
java·spring boot·spring