Dockerfile 完全指南:从入门到最佳实践

Dockerfile 完全指南:从入门到最佳实践

1. Dockerfile 简介与作用

Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令。它允许开发者通过简单的指令定义镜像的构建过程,实现自动化、可重复的镜像构建。

主要作用

  • 自动化镜像构建过程
  • 确保环境一致性
  • 版本控制构建过程
  • 简化部署流程
  • 实现基础设施即代码(IaC)

2. Dockerfile 基本结构与工作原理

一个典型的 Dockerfile 包含以下部分:

# 注释
指令 参数

构建过程

  1. Docker 从基础镜像开始
  2. 按顺序执行 Dockerfile 中的指令
  3. 每条指令创建一个新的镜像层
  4. 最终生成一个可用的镜像

3. Dockerfile 常用指令详解

3.1 FROM - 指定基础镜像

FROM ubuntu:20.04
# 使用官方Ubuntu 20.04镜像作为基础
FROM python:3.9-slim
# 使用Python官方提供的精简版3.9镜像

说明

  • 必须是 Dockerfile 的第一条有效指令(注释除外)
  • 推荐使用官方镜像
  • 尽量使用特定版本标签而非latest

3.2 RUN - 执行命令

RUN apt-get update && apt-get install -y \curl \git \&& rm -rf /var/lib/apt/lists/*
# 更新包索引,安装curl和git,然后清理缓存
RUN pip install --no-cache-dir flask gunicorn
# 安装Python依赖但不缓存下载的包

最佳实践

  • 多个命令合并为一个RUN指令以减少镜像层
  • 清理不必要的文件减少镜像大小
  • 使用--no-cache选项避免缓存

3.3 COPY 与 ADD - 添加文件

COPY . /app
# 将当前目录所有文件复制到容器的/app目录
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
# 只复制requirements文件先安装依赖

ADD 与 COPY 区别

  • ADD 可以解压tar文件和从URL获取文件
  • 大多数情况下推荐使用更简单的COPY

3.4 WORKDIR - 设置工作目录

WORKDIR /app
# 后续指令都在/app目录下执行

特点

  • 相当于cd命令
  • 如果目录不存在会自动创建
  • 影响RUN、CMD、ENTRYPOINT等指令

3.5 EXPOSE - 声明端口

EXPOSE 80
# 声明容器将监听80端口
EXPOSE 3000/tcp
EXPOSE 3000/udp
# 可以指定协议类型

注意

  • 只是声明作用,实际发布端口需要在运行容器时指定
  • 有助于文档化和理解镜像用途

3.6 ENV - 设置环境变量

ENV NODE_ENV=production
ENV APP_HOME=/app
ENV PATH=/app/node_modules/.bin:$PATH
# 可以修改PATH等系统环境变量

用途

  • 配置应用程序
  • 设置路径变量
  • 定义版本号等常量

3.7 CMD 与 ENTRYPOINT - 容器启动命令

CMD ["python", "app.py"]
# 容器启动时默认运行python app.py
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["echo $HOME"]
# ENTRYPOINT作为主命令,CMD作为参数

区别

  • CMD 可以被docker run后的命令覆盖
  • ENTRYPOINT 不容易被覆盖
  • 通常组合使用

4. Dockerfile 高级功能

4.1 ARG - 构建时变量

ARG VERSION=latest
FROM ubuntu:$VERSION
# 构建时可以传递--build-arg VERSION=20.04来改变基础镜像版本

特点

  • 只在构建时有效,运行容器时不可用
  • 可以通过–build-arg覆盖默认值

4.2 VOLUME - 定义数据卷

VOLUME /var/lib/mysql
# 将MySQL数据目录声明为卷

用途

  • 持久化重要数据
  • 容器间共享数据

4.3 HEALTHCHECK - 健康检查

HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost/ || exit 1
# 每30秒检查一次服务是否健康

参数

  • –interval: 检查间隔
  • –timeout: 超时时间
  • –retries: 失败重试次数

4.4 USER - 指定运行用户

RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
# 创建非root用户并切换

安全实践

  • 避免以root用户运行容器
  • 减少安全风险

4.5 ONBUILD - 延迟执行指令

ONBUILD COPY . /app
ONBUILD RUN make build
# 这些指令会在基于此镜像构建其他镜像时执行

用途

  • 创建基础镜像
  • 构建框架镜像

5. Dockerfile 最佳实践

5.1 多阶段构建

# 构建阶段
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .# 运行阶段
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

优点

  • 显著减小最终镜像大小
  • 只包含运行时必要的文件

5.2 合理排序指令

# 变化频率低的指令放前面
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y package# 变化频率高的指令放后面
COPY . /app

原理

  • Docker会缓存每一层
  • 把频繁变化的指令放在后面可以利用缓存

5.3 最小化镜像层

RUN apt-get update && apt-get install -y \package1 \package2 \&& rm -rf /var/lib/apt/lists/*
# 合并多个RUN命令

技巧

  • 使用&&连接命令
  • 使用\换行提高可读性
  • 清理不必要的文件

5.4 使用.dockerignore文件

.git
node_modules
*.log
.DS_Store

作用

  • 排除不必要的文件
  • 加速构建过程
  • 减小镜像大小

5.5 安全实践

FROM alpine:latest
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 使用非root用户

建议

  • 定期更新基础镜像
  • 扫描镜像中的漏洞
  • 最小化安装软件包

6. 完整示例

# 多阶段构建示例 - Python应用
# 构建阶段
FROM python:3.9 as builderWORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1COPY requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt# 运行阶段
FROM python:3.9-slimWORKDIR /appCOPY --from=builder /app/wheels /wheels
COPY --from=builder /app/requirements.txt .RUN pip install --no-cache /wheels/* \&& rm -rf /wheels \&& rm -f requirements.txtCOPY . .RUN useradd -m myuser && chown -R myuser:myuser /app
USER myuserEXPOSE 8000HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:8000/health || exit 1CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

解释

  1. 使用多阶段构建减少最终镜像大小
  2. 构建阶段生成wheel文件
  3. 运行阶段只安装必要的依赖
  4. 创建非root用户增强安全性
  5. 设置健康检查
  6. 声明暴露端口
  7. 指定启动命令

7. 如何通过 Dockerfile 构建镜像

构建 Docker 镜像是使用 Dockerfile 的最终目的,本节将详细介绍如何使用 docker build 命令从 Dockerfile 创建镜像,并探讨各种构建选项和技巧。

7.1 基本构建命令

docker build -t my-image:1.0 .

参数解释

  • -t my-image:1.0:为镜像指定名称和标签
  • .:指定构建上下文路径(Dockerfile 所在目录)

构建过程输出示例

Sending build context to Docker daemon  2.048kB
Step 1/8 : FROM python:3.9-slim---> 2d0f2f3d3a3a
Step 2/8 : WORKDIR /app---> Running in a1b2c3d4e5f6
Removing intermediate container a1b2c3d4e5f6---> 123456789abc
...
Successfully built 789abc123def
Successfully tagged my-image:1.0

7.2 指定 Dockerfile 路径

当 Dockerfile 不在当前目录或使用不同名称时:

docker build -t my-image -f /path/to/Dockerfile .

示例

docker build -t backend-app -f docker/backend.Dockerfile .

7.3 构建时传递变量

使用 --build-arg 传递构建参数:

# Dockerfile
ARG VERSION=latest
FROM ubuntu:$VERSION
docker build -t my-ubuntu --build-arg VERSION=20.04 .

典型用途

  • 指定软件版本
  • 配置构建选项
  • 设置代理

7.4 构建缓存控制

跳过缓存

docker build --no-cache -t fresh-image .

指定缓存来源

docker build --cache-from=my-image:1.0 -t my-image:1.1 .

7.5 多阶段构建的目标阶段

对于多阶段构建,可以只构建特定阶段:

# Dockerfile
FROM node:14 as builder
...FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# 只构建builder阶段
docker build --target builder -t my-app-builder .

7.6 查看构建上下文

查看发送到Docker守护进程的文件

docker build --no-cache --progress=plain .

优化.dockerignore
确保.dockerignore文件排除不必要的文件:

.git
node_modules
*.log
*.md

7.7 构建性能优化技巧

  1. 并行构建
docker buildx build --platform linux/amd64,linux/arm64 -t my-image .
  1. 使用构建工具包(BuildKit)
DOCKER_BUILDKIT=1 docker build -t my-image .
  1. 分层构建
# 先安装依赖
COPY package.json .
RUN npm install# 再复制源代码
COPY . .

7.8 镜像构建后的操作

查看构建历史

docker history my-image:1.0

保存镜像到文件

docker save -o my-image.tar my-image:1.0

从文件加载镜像

docker load -i my-image.tar

7.9 实际构建示例

假设有以下项目结构:

/my-app├── Dockerfile├── app.py├── requirements.txt└── .dockerignore

构建过程

  1. 编写Dockerfile:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
  1. 构建命令:
cd /my-app
docker build -t my-python-app .
  1. 验证构建:
docker images | grep my-python-app
  1. 运行测试:
docker run -d -p 5000:5000 --name test-app my-python-app
curl localhost:5000

8. 总结(

通过本文我们全面了解了:

  1. Dockerfile 的基本语法和核心指令
  2. 高级功能如多阶段构建和健康检查
  3. 编写高效 Dockerfile 的最佳实践
  4. 如何使用 docker build 命令构建镜像
  5. 构建过程中的各种选项和优化技巧

关键构建要点

  • 始终为镜像指定有意义的标签
  • 合理利用缓存提高构建速度
  • 使用多阶段构建减小最终镜像大小
  • 通过.dockerignore减少构建上下文大小
  • 构建后验证镜像是否按预期工作

掌握这些 Dockerfile 编写和镜像构建技能,您将能够为任何应用程序创建高效、可靠的容器镜像,实现开发和生产环境的一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python httpx库终极指南

一、发展历程与技术定位 1.1 历史演进 起源:httpx 由 Encode 团队开发,于 2019 年首次发布,目标是提供一个现代化的 HTTP 客户端,支持同步和异步操作,并兼容 HTTP/1.1 和 HTTP/2。背景: requests 库虽然功…

app加固

1、什么是加固? 我们之前讲的逆向,大多数都是用加密算法去加密一些明文字符串,然后把得到的结果用 Base64、Hex等进行编码后提交。加固其实也一样,只不过他通常加密的是 dex文件而已。但是 dex 文件加密以后,安卓系统是没法直接运行的。所以加固的核心&…

Win全兼容!五五 Excel Word 转 PDF 工具解决多场景转换难题

各位办公小能手们!今天给你们介绍一款超牛的工具——五五Excel Word批量转PDF工具V5.5版。这玩意儿专注搞批量格式转换,能把Excel(.xls/.xlsx)和Word(.doc/.docx)文档唰唰地变成PDF格式。 先说说它的核心功…

springCloud/Alibaba常用中间件之Nacos服务注册与发现

文章目录 SpringCloud Alibaba:依赖版本补充六、Nacos:服务注册与发现1、下载安装Nacos2、服务注册1. 导入依赖(这里以服务提供者为例)2. 修改配置文件和主启动类3. 创建业务类4. 测试 3.服务映射1. 导入依赖2. 修改配置文件和主启动类3. 创建业务类和RestTemplate配置类用来提…

uniapp中score-view中的文字无法换行问题。

项目场景: 今天遇到一个很恶心的问题,uniapp中的文字突然无法换行了。得..就介样 原因分析: 提示:经过一fan研究后发现 scroll-view为了能够横向滚动设置了white-space: nowrap; 强制不换行 解决起来最先想到的是,父…

【STM32 学习笔记】I2C通信协议

注:通信协议的设计背景 3:00~10:13 I2C 通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强, 不需要USART、CAN等通讯协议的外部收发设备,现在被广…

【网络原理】数据链路层

目录 一. 以太网 二. 以太网数据帧 三. MAC地址 四. MTU 五. ARP协议 六. DNS 一. 以太网 以太网是一种基于有线或无线介质的计算机网络技术,定义了物理层和数据链路层的协议,用于在局域网中传输数据帧。 二. 以太网数据帧 1)目标地址 …

控制台打印带格式内容

1. 场景 很多软件会在控制台打印带颜色和格式的文字,需要使用转义符实现这个功能。 2. 详细说明 2.1.转义符说明 样式开始:\033[参数1;参数2;参数3m 可以多个参数叠加,若同一类型的参数(如字体颜色)设置了多个&…

[6-2] 定时器定时中断定时器外部时钟 江协科技学习笔记(41个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 V 30 31 32 33 34 35 36 37 38 39 40 41

数据库的脱敏策略

数据库的脱敏策略:就是屏蔽敏感的数据 脱敏策略三要求: (1)表对象 (2)生效条件(脱敏列、脱敏函数) (3)二元组 常见的脱敏策略规则: 替换、重排、…

Python序列化的学习笔记

1. Npy&Numpy O4-mini-Cursor:如果.npy文件里包含了「Python对象」而非纯数值数组时,就必须在加载时加上allow_pickleTrue。

[思维模式-27]:《本质思考力》-7- 逆向思考的原理与应用

目录 一、什么是逆向思考 1.1、逆向思考的六大核心思维模式 1.2、逆向思考的四大实践方法 1. 假设倒置法 2. 缺陷重构法 3. 用户反推法 4. 规则解构法 1.3、逆向思考的经典案例库 1. 商业创新:从“卖产品”到“卖服务” 2. 用户体验:从“功能满…

在python中,为什么要引入事件循环这个概念?

在Python中,事件循环(Event Loop)是异步编程的核心机制,它的引入解决了传统同步编程模型在高并发场景下的效率瓶颈问题。以下从技术演进、性能优化和编程范式三个角度,探讨这一概念的必要性及其价值。 一、同步模型的局…

Taccel:一个高性能的GPU加速视触觉机器人模拟平台

触觉感知对于实现人类水平的机器人操作能力至关重要。而视觉触觉传感器(VBTS)作为一种有前景的解决方案,通过相机捕捉弹性凝胶垫的形变模式来感知接触的方式,为视触觉机器人提供了高空间分辨率和成本效益。然而,这些传…

oracle 会话管理

会话管理 1:查看当前所有用户的会话(SESSION): SELECT * FROM V S E S S I O N W H E R E U S E R N A M E I S N O T N U L L O R D E R B Y L O G O N T I M E , S I D ; 其中 O r a c l e 内部进程的 U S E R N A M E 为空 2 :查看当前…

Python开发后端InfluxDB数据库测试接口

1、使用PyCharm创建一个Python项目wzClear 2、新建package包wzInfluxdb和wzConfig包,如上图所示,新建一个DB.json配置文件并添加influxdb配置信息,DB.json为统一配置文件 {"influxdbV1": {"url": "http://192.168.0…

采用LLaMa-Factory对QWen大模型实现微调(效果很好)

前言 LLaMA-factory是一个非常有用的开源框架。关于利用llama-factory实现大模型的微调,研究了有一个多月了,终于相对成功的微调了一个QWen的大模型。其中的曲折愿和大家分享! 一、源码的下载 在github上的网址: GitHub - hiyou…

深入理解深度Q网络DQN:基于python从零实现

DQN是什么玩意儿? 深度Q网络(DQN)是深度强化学习领域里一个超厉害的算法。它把Q学习和深度神经网络巧妙地结合在了一起,专门用来搞定那些状态空间维度特别高、特别复杂的难题。它展示了用函数近似来学习价值函数的超能力&#xf…

机械物理:水力发电站工作原理是什么?

水利发电站的工作原理是将水的势能转化为电能,主要依赖水体的重力作用与能量转换设备。以下是其核心步骤和组成部分的详细解释: 1. 蓄水与势能积累 水坝与水库:通过建造水坝拦截河流,形成水库蓄水。水位升高后,水体的…

[面试]SoC验证工程师面试常见问题(五)TLM通信篇

SoC验证工程师面试常见问题(五) 摘要:UVM (Universal Verification Methodology) 中的 TLM (Transaction Level Modeling) 通信是一种用于在验证组件之间传递事务(Transaction)的高层次抽象机制。它通过端口(Port)和导出(Export)实现组件间的解耦通信,避免了信…