当前位置: 首页 > news >正文

Dockerfile基础

一、Dockerfile概念

Dockerfile 定义镜像,依赖镜像来运行容器,因此 Dockerfile 是镜像和容器的关键。

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像的定制实际上就是定制每一层所添加的配置、文件。如果可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,这个脚本就是 Dockerfile。

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。

二、Dockerfile与Docker commit

(1)Docker commit创建镜像

搭建过程:

  1. 启动一个基础容器;
  2. 在容器中进行软件安装、环境配置等操作;
  3. 使用docker commit 命令将修改后的容器保存为镜像。

优点:

  • 简单直观,不需要太复杂的操作;
  • 快速上手,适合初学者或临时需求,快速创建镜像;

缺点:

  • 缺乏可重复性,手动操作无法保证每次构建出的镜像完全一致;
  • 不可追踪,容器中的修改过程没有记录,他人难以理解镜像的构建过程;
  • 不可维护,若需要更新镜像,必须手动操作,难以维护;
  • 体积臃肿,docker commit 创建的镜像通常是一个整体快照,无法充分利用 docker 的分层存储机制,导致镜像体积较大;

(2)Dockerfile创建镜像

搭建过程:

  1. 编写dockerfile文件;
  2. 使用docker build 命令依据dockerfile构建镜像。

优点:

  • 可重复性,dockerfile明确记录了镜像的构建过程,便于在不同环境重复构建相同的镜像;
  • 透明性,可以查看dockerfile文件,了解镜像是如何搭建的;
  • 体积小,dockerfile的每一行都会生成一个新的镜像层,有利于优化镜像大小和构建速度;

缺点:

  • 上手难度高,需熟悉dockerfile的指令语法。

三、Dockerfile创建镜像

(1)dockerfile目录

首先需要有一个制作镜像的目录,该目录下有个文件,名称必须为Dockerfile,docker build读取Dockerfile是按顺序依次Dockerfile里的配置。可以在docker build命令中使用 -f 标志指向文件系统中任何位置的Dockerfile。

把文件路径写入到.dockerignore,对应的路径将不会被打包到新镜像。

(2)dockerfile文件格式

Dockerfile有指定的格式,#号开头为注释,指令默认用大写字母来表示,以区分指令和参数,且第一条非注释指令必须是FROM 开头,表示基于哪个基础镜像来构建新镜像。

下面通过一个示例来介绍其文件格式:

# This dockerfile uses the ubuntu image

# VERSION 2 - EDITION 1 # Author: docker_user

# Command format: Instruction [arguments / command] ..

# 1、第一行必须指定 基础镜像信息

FROM ubuntu

# 2、维护者信息

MAINTAINER docker_user docker_user@email.com

# 3、镜像操作指令

RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list

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

RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# 4、暴露端口,启动执行指令

EXPOSE 80

CMD /usr/sbin/nginx

Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令。一开始必须要指明所基于的镜像名称,接下来一般会说明维护者信息;后面则是镜像操作指令,例如 RUN 指令。每执行一条RUN 指令,镜像添加新的一层,并提交;最后是 CMD 指令,来指明运行容器时的操作命令。

(3)根据dockerfile构建镜像

编写完成 Dockerfle 之后,可以通过 docker build 命令来创建镜像。

该命令将读取指定路径下(包括子目录)的Dockerfle,并将该路径下所有数据作为上下文(Context)发送给 Docker 服务端。Docker 服务端在校验 Dockerfle 格式通过后,逐条执行其中定义的指令,碰到 ADD、COPY 和 RUN 指令会生成一层新的镜像。最终如果创建镜像成功,会返回最终镜像的 ID。

如果上下文过大,会导致发送大量数据给服务端,延缓创建过程。因此除非是生成镜像所必需的文件,不然不要放到上下文路径下。如果使用非上下文路径下的Dockerfle,可以通过-f选项来指定其路径。

要指定生成镜像的标签信息,可以通过-t选项。该选项可以重复使用多次为镜像一次添加多个名称。例如,上下文路径为 /tmp/docker builder/,并且希望生成镜像标签为 builder/rst_image:1.0.0,可以使用下面的命令:

$ docker build -t builder/first_image:1.0.0 /tmp/docker_builder

四、dockerfile指令

(1)FROM

指定所创建镜像的基础镜像。

# 示例
FROM ubuntu:20.04

 (2)ARG和ENV

定义创建镜像过程中使用的变量。

# 示例
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

注意:使用 ARG 定义构建时参数(如镜像版本号);使用 ENV 设置运行时环境变量。其中ARG的值仅在构建时有效,而ENV的值会保留在最终镜像中。

(3)LABEL和MAINTAINER

为镜像添加元数据,用于描述镜像的信息,便于管理和追踪。

# 示例
LABEL version="1.0" maintainer="example@example.com"
MAINTAINER docker_user docker_user@email.com

(4)WORKDIR

定义容器内的工作目录,后续的指令都会在这个目录下执行。

# 示例
WORKDIR /app

(5)COPY

复制本地主机的<src> (为Dockerfile所在目录的相对路径)下内容到镜像中的<dest>。目标路径不存在时,会自动创建。

# 示例
COPY app.py /app/app.py

(6)ADD

ADD功能更强大,除了可以复制文件外,还支持从远程 URL 下载文件以及自动解压压缩文件。

# 示例
ADD https://example.com/config.json /app/config.json

(7)RUN

运行命令以安装依赖或配置环境。

# 示例
RUN apt-get update && apt-get install -y nginx

(8)EXPOSE

声明容器运行时监听的端口。

# 示例
EXPOSE 80 443

(9)ENTRYPOINT

ENTRYPOINT 用于配置容器作为一个可执行程序运行,提供固定入口点,其在运行容器时不可以被覆盖。

语法:

ENTRYPOINT ["executable", "param1", "param2"]  # JSON 数组格式(推荐)
ENTRYPOINT command param1 param2              # Shell 格式

示例:

ENTRYPOINT ["/start.sh"]

(10)CMD

CMD 指令用来指定启动容器时默认执行的命令,其在运行容器时可以被覆盖。

格式:

CMD ["executable", "param1", "param2"]  # JSON 数组格式(推荐)
CMD command param1 param2              # Shell 格式
CMD ["param1", "param2"]               # 默认参数形式(补充 ENTRYPOINT)

示例:

CMD ["python", "app.py"]
# 也可以与ENTRYPOINT组合使用
ENTRYPOINT ["python"]
CMD ["app.py"]

注意:每个Dockerfile 只能有一条 CMD命令。 如果指定了多条命令,只有最后一条会被执行。

五、dockerfile构建镜像原则

dockerfile构建镜像需要遵循以下原则:

  • 单一职责,每个层级只做每个层级的事。
  • 提供注释信息,以便他人理解。
  • 保持容器最小化。
  • 合理选择基础镜像,尽量选择成熟易用的基础镜像版本。
  • 最小化镜像层数,尽量精简,否则容易出错,可能回影响加载速度。
http://www.xdnf.cn/news/873523.html

相关文章:

  • SpringCloudAlibaba微服务架构
  • AI在网络安全领域的应用现状和实践
  • 代码训练LeetCode(21)跳跃游戏2
  • vivo y300pro 无法连接adb
  • 【算法篇】逐步理解动态规划模型4(子数组问题)
  • 【BUG解决】关于BigDecimal与0的比较问题
  • linux_centos7.x的ifconfig命令显示内容详解
  • Python 入门到进阶全指南:从语言特性到实战项目
  • rk3588 上运行smolvlm-realtime-webcam,将视频转为文字描述
  • 【映射】2024-睿抗-AcWing 5834. 谁进线下了?
  • J-Link 烧录SPI Flash
  • idea相关功能
  • [Java 基础]面向对象-封装
  • 【AI论文】VideoReasonBench:多模态大语言模型(MLLMs)能否执行以视觉为中心的复杂视频推理?
  • python基础day04
  • 算法竞赛推荐书单
  • spring-ai入门
  • 容器化实施:Docker容器构建与优化深度剖析
  • 深入理解CSS浮动:从基础原理到实际应用
  • 知识宇宙-思考篇:AI的出现,是否能替代IT从业者?
  • 实时数据湖架构设计:从批处理到流处理的企业数据战略升级
  • LangChain开发环境搭建
  • 破解通信难题,modbus转profibus网关在高炉水冲渣系统中稳定好用
  • css实现圆环展示百分比,根据值动态展示所占比例
  • Java八股文——Redis篇
  • 算法打卡第15天
  • 电路设计基础-2
  • pikachu靶场通关笔记14 XSS关卡10-XSS之js输出(五种方法渗透)
  • C# 从 ConcurrentDictionary 中取出并移除第一个元素
  • Python中的`with`语句用法