如何编写高效的Dockerfile

简介: 【8月更文挑战第17天】镜像是包含应用及其运行环境的打包文件,含文件系统等。为确保一致性,镜像需包含整个根文件系统(rootfs)。

镜像就是一个打包文件,里面包含了应用程序还有它运行所依赖的环境,例如文件系统、环境变量、配置参数等等。

环境变量、配置参数这些东西还是比较简单的,随便用一个 manifest 清单就可以管理,真正麻烦的是文件系统。为了保证容器运行环境的一致性,镜像必须把应用程序所在操作系统的根目录,也就是 rootfs,都包含进来。

容器镜像内部并不是一个平坦的结构,而是由许多的镜像层组成的,每层都是只读不可修改的一组文件,相同的层可以在镜像之间共享,然后多个层像搭积木一样堆叠起来,再使用一种叫“Union FS 联合文件系统”的技术把它们合并在一起,就形成了容器最终看到的文件系统。

docker inspect 来查看镜像的分层信息,比如 nginx:alpine 镜像。

image.gif 编辑

通过这张截图就可以看到,nginx:alpine 镜像里一共有 6 个 Layer。

比起容器、镜像来说,Dockerfile 非常普通,它就是一个纯文本,里面记录了一系列的构建指令,比如选择基础镜像、拷贝文件、运行脚本等等,每个指令都会生成一个 Layer,而 Docker 顺序执行这个文件里的所有步骤,最后就会创建出一个新的镜像出来。

首先因为构建镜像的第一条指令必须是 FROM,所以基础镜像的选择非常关键。如果关注的是镜像的安全和大小,那么一般会选择 Alpine;如果关注的是应用的运行稳定性,那么可能会选择 Ubuntu、Debian、CentOS。

FROM alpine:3.15                # 选择Alpine镜像
FROM ubuntu:bionic              # 选择Ubuntu镜像

image.gif

RUN 通常会是 Dockerfile 里最复杂的指令,会包含很多的 Shell 命令,但 Dockerfile 里一条指令只能是一行,所以有的 RUN 指令会在每行的末尾使用续行符 \,命令之间也会用 && 来连接,这样保证在逻辑上是一行,就像下面这样:

RUN apt-get update \
    && apt-get install -y \
        build-essential \
        curl \
        make \
        unzip \
    && cd /tmp \
    && curl -fSL xxx.tar.gz -o xxx.tar.gz\
    && tar xzf xxx.tar.gz \
    && cd xxx \
    && ./config \
    && make \
    && make clean

image.gif

把这些 Shell 命令集中到一个脚本文件里,用 COPY 命令拷贝进去再用 RUN 来执行:

COPY setup.sh  /tmp/                # 拷贝脚本到/tmp目录
RUN cd /tmp && chmod +x setup.sh \  # 添加执行权限
    && ./setup.sh && rm setup.sh    # 运行脚本然后再删除

image.gif

Dockerfile 里也可以做到,需要使用两个指令 ARG 和 ENV。它们区别在于 ARG 创建的变量只在镜像构建过程中可见,容器运行时不可见,而 ENV 创建的变量不仅能够在构建镜像的过程中使用,在容器运行时也能够以环境变量的形式被应用程序使用。

因为命令行“docker”是一个简单的客户端,真正的镜像构建工作是由服务器端的“Docker daemon”来完成的,所以“docker”客户端就只能把“构建上下文”目录打包上传(显示信息 Sending build context to Docker daemon ),这样服务器才能够获取本地的这些文件。

如何编写 Dockerfile 内容?

  1. 创建镜像需要编写 Dockerfile,写清楚创建镜像的步骤,每个指令都会生成一个 Layer。
  2. Dockerfile 里,第一个指令必须是 FROM,用来选择基础镜像,常用的有 Alpine、Ubuntu 等。其他常用的指令有:COPY、RUN、EXPOSE,分别是拷贝文件,运行 Shell 命令,声明服务端口号。
  3. docker build 需要用 -f 来指定 Dockerfile,如果不指定就使用当前目录下名字是“Dockerfile”的文件。
  4. docker build 需要指定“构建上下文”,其中的文件会打包上传到 Docker daemon,所以尽量不要在“构建上下文”中存放多余的文件。
  5. 创建镜像的时候应当尽量使用 -t 参数,为镜像起一个有意义的名字,方便管理。
相关文章
|
4月前
|
Ubuntu Shell 应用服务中间件
|
4月前
|
NoSQL Shell 应用服务中间件
Dockerfile详解及优化技巧
Dockerfile详解及优化技巧
|
10月前
|
Shell Docker 容器
dockerfile编写和构建运行
dockerfile编写和构建运行
|
27天前
|
JSON JavaScript 开发者
Composerize神器:自动化转换Docker运行命令至Compose配置,简化容器部署流程
【8月更文挑战第7天】Composerize神器:自动化转换Docker运行命令至Compose配置,简化容器部署流程
Composerize神器:自动化转换Docker运行命令至Compose配置,简化容器部署流程
|
24天前
|
缓存 开发者 Docker
Dockerfile是Docker容器化过程中的核心组件,它允许开发者以一种可重复、可移植的方式自动化地构建Docker镜像
【8月更文挑战第19天】Dockerfile是构建Docker镜像的脚本文件,含一系列指令定义镜像构建步骤。每条大写指令后跟至少一个参数,按序执行,每执行一条指令即生成新的镜像层。常用指令包括:FROM指定基础镜像;RUN执行构建命令;EXPOSE开放端口;CMD指定容器启动行为等。优化策略涉及减少镜像层数、选择轻量基础镜像、利用缓存及清理冗余文件。示例:基于Python应用的Dockerfile包括设置工作目录、复制文件、安装依赖等步骤。掌握Dockerfile有助于高效自动化构建镜像,加速应用部署。
21 1
|
2月前
|
Linux 应用服务中间件 开发工具
Dockerfile编写
Dockerfile编写
35 3
|
4月前
|
安全 Java Maven
编写 Dockerfile 最佳实践
编写 Dockerfile 最佳实践
|
Linux 网络安全 Docker
2021最简洁的docker安装流程
2021最简洁的docker安装流程
147 0
|
运维 Java 数据安全/隐私保护
DockerFile 构建过程解析 | 学习笔记
快速学习 DockerFile 构建过程解析
94 0
DockerFile 构建过程解析 | 学习笔记