【Docker】Dockerfile 编写实践

👻创作者:丶重明
👻创作时间:2025年4月8日
👻擅长领域:运维

目录

  • 1. Dockerfile编写原则
    • 1.1.选择合适的基础镜像
    • 1.2.镜像层优化
    • 1.3.多阶段构建
    • 1.4.安全增强
  • 2. 关键指令与技巧
    • 2.1.COPY vs ADD
    • 2.2.ENTRYPOINT vs CMD
    • 2.3.健康检查
    • 2.4.环境变量管理
  • 3. 实战:构建Prometheus镜像
  • 4. 附页:Dockerfile指令

1. Dockerfile编写原则

1.1.选择合适的基础镜像

基础镜像的选择直接影响镜像的安全性、体积和可维护性。可以从这三个方面考虑:

  • 最小化原则:优先使用轻量级镜像
  • 安全扫描:定期检查基础镜像漏洞(使用 docker scan)
  • 固定版本:避免使用latest标签,明确指定版本号

示例:

# 推荐,这个镜像很小,仅有8MB左右
alpine:3.21.3# 不推荐,基础镜像过大,版本号不明确
ubuntu:latest

1.2.镜像层优化

Docker 镜像由只读层(Layer)堆叠而成,每一层对应 Dockerfile 中的一条指令。优化层的核心逻辑是减少层数和层体积。

  • 合并指令:通过&& \合并多个RUN命令
  • 清理缓存:在同一个RUN层中删除临时文件
  • 层顺序:将高频变化的层(如代码)放在最后

示例:

# 通过&& \这种方式将多个命令合并为一层
RUN apk add --no-cache curl tar && \curl -LO https://example.com/pkg.tar.gz && \tar -xzf pkg.tar.gz && \rm pkg.tar.gz

1.3.多阶段构建

多阶段构建(Multi-stage Build)是减少生产镜像体积的杀手锏。其核心思想是:用“胖”镜像构建,用“瘦”镜像运行。

  • 分离构建环境与运行时环境
  • 减少最终镜像体积

1.4.安全增强

容器安全是生产环境的核心要求。以下是三个关键实践:

  • 非root用户运行
  • 限制文件系统写入权限
  • 使用 .dockerignore 排除敏感文件

示例:

RUN addgroup -S appgroup && \adduser -S appuser -G appgroup
USER appuser

2. 关键指令与技巧

2.1.COPY vs ADD

  • 优先使用COPY:仅用于复制本地文件
  • 谨慎使用ADD:自动解压压缩包,可能引入意外行为

2.2.ENTRYPOINT vs CMD

  • ENTRYPOINT:定义容器主进程
  • CMD:提供默认参数

示例:

ENTRYPOINT ["/bin/prometheus"]
CMD ["--config.file=/etc/prometheus/prometheus.yml"]

2.3.健康检查

HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:9090/-/healthy || exit 1

这一层命令的含义是:

  • HEALTHCHECK:为容器设定健康检查机制
  • --interval=30s:健康检查的时间间隔
  • --timeout=3s:健康检查命令的超时时间
  • CMD ...:具体的健康检查命令

每隔 30 秒就向http://localhost:9090/-/healthy发送一个 HTTP 请求,并且要求在 3 秒内完成。

若请求成功(状态码为 200 - 399),则判定容器健康;若请求失败或者超时,就判定容器不健康。

2.4.环境变量管理

  • 使用 ENV 定义常量
  • 敏感数据通过 --env-file 或 Secrets 传递

3. 实战:构建Prometheus镜像

dockerfile目录结构:直接在外部目录解压

# tree /prom_docker/
/prom_docker/
├── dockerfile
└── prometheus├── LICENSE├── NOTICE├── prometheus├── prometheus.yml└── promtool1 directory, 6 files

完整的Dockerfile文件:

FROM alpine:3.21.3# 创建非特权用户
RUN addgroup -S prometheus && \adduser -S -D -H -s /bin/false -G prometheus prometheus && \mkdir -p /etc/prometheus /prometheus && \chown -R prometheus:prometheus /etc/prometheus /prometheus# 复制必要文件
COPY prometheus/LICENSE prometheus/NOTICE .
COPY prometheus/prometheus \prometheus/promtool \/usr/local/bin/
COPY prometheus/prometheus.yml \/etc/prometheus/# 设置运行时参数
USER prometheus
WORKDIR /prometheus
EXPOSE 9090
VOLUME ["/prometheus"]# 健康检查(使用 promtool 无依赖)
HEALTHCHECK --interval=30s --timeout=10s \CMD ["/usr/local/bin/promtool", "check", "healthy", "--prometheus-url=http://localhost:9090"]# 入口指令
ENTRYPOINT ["/usr/local/bin/prometheus"]
CMD [ \"--config.file=/etc/prometheus/prometheus.yml", \"--storage.tsdb.path=/prometheus", \"--web.enable-lifecycle", \"--web.external-url=/" \
]

构建镜像:

[root@localhost prom_docker]# docker build -t prometheus:v3.2.1 .

运行测试:

# docker run -d -p 9090:9090 --name prometheus-1 2c7c81224aa2
b91210a45af9f60c93c7e6652480da8d98a9077818cd2e75c769e3670ec1429d

在这里插入图片描述

4. 附页:Dockerfile指令

以下是 Dockerfile 中常见指令及其功能、语法和示例的表格:

指令功能语法示例
FROM指定基础镜像,是 Dockerfile 的起始指令FROM <image>[:<tag>][@<digest>]FROM python:3.9
RUN在新的镜像层中执行命令,常用于安装软件包等操作RUN <command>(shell 形式)
RUN ["executable", "param1", "param2"](exec 形式)
RUN apt-get update && apt-get install -y python3
RUN ["pip", "install", "flask"]
CMD为容器提供默认的执行命令,一个 Dockerfile 中只能有一个 CMD,若有多个则只有最后一个生效CMD ["executable","param1","param2"](exec 形式)
CMD command param1 param2(shell 形式)
CMD ["param1","param2"](为 ENTRYPOINT 提供默认参数)
CMD ["python", "app.py"]
CMD python app.py
LABEL为镜像添加元数据,如作者、版本等信息LABEL <key>=<value> <key>=<value> ...LABEL maintainer="example@example.com" version="1.0"
EXPOSE声明容器运行时监听的网络端口,但不进行端口映射EXPOSE <port> [<port>/<protocol> ...]EXPOSE 8080
EXPOSE 80/tcp 443/tcp
ENV设置环境变量,在容器运行时可使用ENV <key>=<value> ...ENV APP_NAME=myapp
ENV DB_HOST=localhost DB_PORT=5432
ADD将文件、目录或远程文件复制到镜像中,若复制的是压缩文件会自动解压ADD <src>... <dest>ADD app.tar.gz /app
ADD http://example.com/file.txt /tmp/
COPY将文件或目录从构建上下文复制到镜像中,不具备自动解压和远程文件处理功能COPY <src>... <dest>COPY requirements.txt /app/
ENTRYPOINT配置容器启动时执行的命令,可与 CMD 结合使用ENTRYPOINT ["executable", "param1", "param2"](exec 形式)
ENTRYPOINT command param1 param2(shell 形式)
ENTRYPOINT ["python", "app.py"]
VOLUME创建挂载点,用于将主机目录或数据卷挂载到容器中VOLUME ["/data"]VOLUME ["/var/lib/mysql"]
USER指定后续 RUNCMDENTRYPOINT 指令执行时的用户和用户组USER <user>[:<group>]USER myuser
WORKDIR设置工作目录,后续的 RUNCMDENTRYPOINTCOPYADD 指令都会在该目录下执行WORKDIR /path/to/workdirWORKDIR /app
ARG定义构建时的变量,在构建镜像时可通过 --build-arg 传递值ARG <name>[=<default value>]ARG VERSION=1.0
docker build --build-arg VERSION=2.0 .
ONBUILD定义一个触发器,当该镜像被用作其他镜像的基础镜像时,这些指令会在后续的 FROM 指令之后执行ONBUILD <INSTRUCTION>ONBUILD COPY . /app
STOPSIGNAL设置停止容器时发送的系统调用信号STOPSIGNAL signalSTOPSIGNAL SIGTERM
HEALTHCHECK配置容器的健康检查命令HEALTHCHECK [OPTIONS] CMD <command>
HEALTHCHECK NONE
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1
SHELL覆盖默认的 shell 命令,用于 RUNCMDENTRYPOINT 指令的 shell 形式SHELL ["executable", "parameters"]SHELL ["/bin/bash", "-c"]

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

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

相关文章

【数学建模】(智能优化算法)萤火虫算法(Firefly Algorithm)详解与实现

萤火虫算法(Firefly Algorithm)详解与实现 文章目录 萤火虫算法(Firefly Algorithm)详解与实现前言1. 算法原理2. 算法流程3. Python实现4. 算法特点4.1 优点4.2 缺点 5. 应用领域6. 算法变种7. 总结与展望参考文献 前言 大家好&#xff0c;今天给大家介绍一种有趣且高效的群体…

VSCode会击败Cursor和Windsurf吗?

VSCode 会击败 Cursor 和 Windsurf 吗&#xff1f;微软能不能靠自己的地盘优势和规则限制打压对手&#xff1f;答案是"能"&#xff0c;但他们真的会这么干吗&#xff1f; Cursor & Windsurf vs VSCode Copilot 大PKAI编程工具大战越来越激烈现在最火最赚钱的AI…

2025-4-11 情绪周期视角复盘(mini)

简单说两句好了&#xff0c;做一个阶段记录&#xff0c;目前阶段就是上一轮 中毅达 第二轮补涨的退潮结束&#xff0c;回盛生物 金河生物 它们的题材导致 农业和医药这2个题材退潮&#xff0c;注意的是不靠谱导致的反制题材是在这个二轮补涨周期里一起走的&#xff0c;所以 海…

【SLAM】将realsense-viewer录制的rosbag视频导出成图片序列(RealSense D435)

本文介绍了如何将realsense-viewer录制的rosbag格式的视频导出成图片序列&#xff0c;方便合并成mp4视频或插入到论文中。 本文首发于❄慕雪的寒舍 说明 Intel提供的realsense-viewer软件录制的视频都是rosbag格式的&#xff0c;为了编写论文&#xff0c;需要从录制的视频中截…

Ubuntu ROS 对应版本

Ubuntu 18.04 (Bionic Beaver) - 2018年4月发布 对应的ROS版本&#xff1a;ROS Melodic (2018年5月发布) Ubuntu 20.04 (Focal Fossa) - 2020年4月发布 对应的ROS版本&#xff1a;ROS Noetic (2020年5月发布) Ubuntu 22.04 (Jammy Jellyfish) - 预计2022年4月发布 对应的ROS版…

Ubuntu 软件卸载与清理终极指南

Ubuntu 软件卸载与清理指南 适用范围&#xff1a;Ubuntu 及其衍生发行版&#xff08;如 Linux Mint、Pop!_OS 等&#xff09;&#xff0c;Debian 系统大部分方法也适用。 目标&#xff1a;帮助你快速、彻底卸载软件并清理残余文件&#xff0c;保持系统整洁。 前提&#xff1a;建…

基于javaweb的SpringBoot新闻视频发布推荐评论系统(源码+部署文档)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

Linux-内核驱动

open uboot.bin target-connect U-Boot&#xff08;Universal Boot Loader&#xff09;是一种广泛使用的开源引导加载程序&#xff0c;它允许用户从各种设备&#xff08;如硬盘、USB设备、网络等&#xff09;加载操作系统。U-Boot提供了丰富的命令行接口&#xff08;CLI&#…

DAPP实战篇:使用ethers.js连接以太坊智能合约

专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读344次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你想要知道区块…

[原创](现代Delphi 12指南): 设置、运行和调试你的第一个macOS应用程序.

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、C …

Adobe Photoshop 2025 Mac中文 Ps图像编辑

Adobe Photoshop 2025 Mac中文 Ps图像编辑 一、介绍 Adobe Photoshop 2025 Mac版集成了多种强大的图像编辑、处理和创作功能。①强化了Adobe Sensei AI的应用&#xff0c;通过智能抠图、自动修复、图像生成等功能&#xff0c;用户能够快速而精确地编辑图像。②3D编辑和动画功…

蓝桥杯备赛知识点总结

一、数论 如果想要计算整除向上取整&#xff08;xy-1&#xff09;/y 或者&#xff08;x-1&#xff09;/y 1 最大公约数&#xff1a; int gcd(int a,int b){return b0?a:gcd(b,a%b); }最小公倍数&#xff1a; int lcm(int a,int b){return a/gcd(a,b)*b; } 埃氏筛法&#…

设计模式 --- 状态模式

状态模式​​是一种​​行为型设计模式​​&#xff0c;允许对象在内部状态改变时动态改变其行为​​&#xff0c;使对象的行为看起来像是改变了。该模式通过将状态逻辑拆分为独立类​​&#xff0c;消除复杂的条件分支语句&#xff0c;提升代码的可维护性和扩展性。 状态模式的…

【读者求助】如何跨行业进入招聘岗位?

文章目录 读者留言回信岗位细分1. 中介公司的招聘岗位2. 猎头专员3. 公司的招聘专员选择建议 面试建议1. 请简单介绍你过去 3 年的招聘工作经历&#xff0c;重点说下你负责的岗位类型和规模2. 你在招聘流程中最常用的渠道有哪些&#xff1f;如何评估渠道效果&#xff1f;3. 当你…

AI Agent入门指南

图片来源网络 ‌一、开箱暴击&#xff1a;你以为的"智障音箱"&#xff0c;其实是赛博世界的007‌ ‌1.1 从人工智障到智能叛逃&#xff1a;Agent进化史堪比《甄嬛传》‌ ‌青铜时代&#xff08;2006-2015&#xff09;‌ “小娜同学&#xff0c;关灯” “抱歉&…

pnpm 中 Next.js 模块无法找到问题解决

问题概述 项目在使用 pnpm 管理依赖时,出现了 “Cannot find module ‘next/link’ or its corresponding type declarations” 的错误。这是因为 pnpm 的软链接机制在某些情况下可能导致模块路径解析问题。 问题诊断 通过命令 pnpm list next 确认项目已安装 Next.js 15.2.…

vulnhub:sunset decoy

靶机下载地址https://www.vulnhub.com/entry/sunset-decoy,505/ 渗透过程 简单信息收集 nmap 192.168.56.0/24 -Pn # 确定靶机ip&#xff1a;192.168.56.121 nmap 192.168.56.121 -A -T4 # 得到开放端口22,80 在80端口得到save.zip&#xff0c;需要密码解压。 john破解压缩…

代码学习总结(一)

代码学习总结&#xff08;一&#xff09; 这个系列的博客是记录下自己学习代码的历程&#xff0c;有来自平台上的&#xff0c;有来自笔试题回忆的&#xff0c;主要基于 C 语言&#xff0c;包括题目内容&#xff0c;代码实现&#xff0c;思路&#xff0c;并会注明题目难度&…

OSPF的接口网络类型【复习篇】

OSPF在不同网络环境下默认的不同工作方式 [a3]display ospf interface g 0/0/0 # 查看ospf接口的网络类型网络类型OSPF接口的网络类型&#xff08;工作方式&#xff09;计时器BMA&#xff08;以太网&#xff09;broadcast &#xff0c;需要DR/BDR的选举hello&#xff1a;10s…

PHM学习软件|PHM预测性维护系统

使用步骤教程如下 1、登录 用户名&#xff1a;52phm 密码&#xff1a;xxx &#xff08;区别在于不同用户密钥不一样&#xff09; 2、上传需要分析的数据集 支持数据集格式&#xff1a;csv、xlsx、xls、mat、json 3、主题1&#xff1a;机械参数计算 计算轴承、齿轮、皮带的…