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

【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"]

相关文章:

【Docker】Dockerfile 编写实践

&#x1f47b;创作者&#xff1a;丶重明 &#x1f47b;创作时间&#xff1a;2025年4月8日 &#x1f47b;擅长领域&#xff1a;运维 目录 1. Dockerfile编写原则1.1.选择合适的基础镜像1.2.镜像层优化1.3.多阶段构建1.4.安全增强 2. 关键指令与技巧2.1.COPY vs ADD2.2.ENTRYPOIN…...

Jakarta EE 11发布:云原生Java企业应用的新标准

&#x1f4dd; 摘要 Jakarta EE 11于2023年正式发布&#xff0c;这是Java企业版技术栈的一次重要更新。本文将详细介绍Jakarta EE 11的核心特性、改进之处以及如何利用这些新功能构建现代化的云原生应用。我们将通过实际代码示例展示新特性的使用方法&#xff0c;并分析其对Ja…...

蓝桥杯第十五届C++B组省赛真题解析

蓝桥杯第十五届CB组省赛真题解析 一、宝石组合https://www.lanqiao.cn/problems/19711/learning/ 解题思路 题目要求找到三个数&#xff0c;使得它们的最大公约数&#xff08;GCD&#xff09;尽可能大&#xff0c;并在GCD相同的情况下选择数值最小的三个数。以下是分步解析&a…...

LabVIEW商业软件开发注意问题

在 LabVIEW 商业软件开发进程中&#xff0c;性能优化、界面设计及兼容性与扩展性&#xff0c;对软件品质、用户体验和市场适配性起着决定性作用。下面&#xff0c;借助多个LabVIEW 编程特性的实际案例&#xff0c;深入分析这些方面的开发要点。 一、性能优化&#xff1a;提升软…...

面试算法高频04-分治与回溯

分治与回溯 分治和回溯算法&#xff0c;包括其概念、特性、代码模板&#xff0c;并结合具体题目进行讲解&#xff0c;旨在帮助学员理解和掌握这两种算法的应用。 分治与回溯的概念 分治&#xff08;Divide & Conquer&#xff09;&#xff1a;本质上基于递归&#xff0c;先…...

记录vscode连接不上wsl子系统下ubuntu18.04问题解决方法

记录vscode连接不上wsl子系统下ubuntu18.04问题解决方法 报错内容尝试第一次解决方法尝试第二次解决方法注意事项参考连接 报错内容 Unable to download server on client side: Error: Request downloadRequest failed unexpectedly without providing any details… Will tr…...

Java 中 SQL 注入问题剖析​

一、引言​ 在当今数字化时代&#xff0c;数据是企业和组织的核心资产之一。许多应用程序都依赖于数据库来存储和管理数据&#xff0c;而 Java 作为一种广泛使用的编程语言&#xff0c;常被用于开发与数据库交互的应用程序。然而&#xff0c;SQL 注入这一安全漏洞却如同隐藏在…...

华为数字芯片机考2025合集2已校正

单选 1. 题目内容 关于亚稳态的描述错误的是&#xff08; &#xff09;。 1. 解题步骤 1.1 理解亚稳态&#xff08;Metastability&#xff09;的核心特性 亚稳态是指触发器无法在指定时间内稳定输出有效逻辑电平&#xff08;0或1&#xff09;的状态&#xff0c;其关键特点…...

Leedcode刷题 | Day27_贪心算法01

一、学习任务 455.分发饼干代码随想录376. 摆动序列53. 最大子序和 二、具体题目 1.455分发饼干455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09; 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对…...

深度学习项目--分组卷积与ResNext网络实验探究(pytorch复现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 ResNext是分组卷积的开始之作&#xff0c;这里本文将学习ResNext网络&#xff1b;本文复现了ResNext50神经网络&#xff0c;并用其进行了猴痘病分类实验…...

CSS 笔记——Flexbox(弹性盒布局)

目录 1. Flex 容器与 Flex 项目 2. 主轴与交叉轴 3. Flex 容器的属性 display flex-direction justify-content align-items align-content flex-wrap 4. Flex 项目的属性 flex-grow flex-shrink flex-basis flex align-self 5. Flexbox 的优点 6. Flexbox 的…...

[实战] linux驱动框架与驱动开发实战

linux驱动框架与驱动开发实战 Linux驱动框架与驱动开发实战一、Linux驱动框架概述1.1 Linux驱动的分类1.2 Linux驱动的基本框架 二、Linux驱动关键API详解2.1 模块相关API2.2 字符设备驱动API2.3 内存管理API2.4 中断处理API2.5 PCI设备驱动API 三、Xilinx XDMA驱动开发详解3.1…...

cpp(c++)win 10编译GDAL、PROJ、SQLite3、curl、libtiff

cpp&#xff08;c&#xff09;编译GDAL、PROJ、SQLite3 Sqlite3libtiffcurlprojGDAL Sqlite3 1、下载 Sqlite3 源码、工具、二进制预编译 exe Sqlite3 官网&#xff1a;https://www.sqlite.org/download.html 下载 sqlite-amalgamation-3430200.zipsqlite-dll-win64-x64-3430…...

每日一题(小白)暴力娱乐篇23

由题意得知给我们一串数字&#xff0c;我们每次交换两位&#xff0c;最少交换多少次成功得到有顺序的数组。我们以平常的思维去思考&#xff0c;加入给你一串数字获得最少的交换次数&#xff0c;意味着你的交换后续基本不会变&#xff0c;比如说2 1 3 5 4 中1与2交换后不变&…...

01-Redis-基础

1 redis诞生历程 redis的作者笔名叫做antirez&#xff0c;2008年的时候他做了一个记录网站访问情况的系统&#xff0c;比如每天有多少个用户&#xff0c;多少个页面被浏览&#xff0c;访客的IP、操作系统、浏览器、使用的搜索关键词等等(跟百度统计、CNZZ功能一样)。最开始存储…...

【从零开始学习JVM | 第一篇】快速认识JVM

什么是JVM&#xff1f; JVM--Java虚拟机&#xff0c;它是Java实现平台无关性的基石。 Java程序运行的时候&#xff0c;编译器将Java代码编译为平台无关的Java字节码文件&#xff08;.class&#xff09;&#xff0c;接下来对应平台的JVM对字节码进行运行解释&#xff0c;翻译成…...

使用RabbitMQ实现异步秒杀

搭建RabbitMQ 在虚拟机上用docker搭建RabbitMQ&#xff0c;首先拉取镜像 docker run --privilegedtrue -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management mkdir -p /usr/local/docker/rabbitmq再创建rabbitmq容器&#xff0c;下面的命令已经能够创建之后…...

Spring Boot 配置文件加载优先级全解析

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 Spring Boot 配置文件加载优先级全解析 Spring Boot 的配置文件加载机制是开发者管理不同环境配置的核心功能之一。其通过外部化配置&#xff08;Externaliz…...

解决华硕主板Z890m下载ubuntu20.04后没有以太网问题

问题描述&#xff1a; 华硕主板Z890m下载双系统ubuntu20.04后&#xff0c;发现ubuntu不能打开以太网。 问题原因&#xff1a; 华硕主板的网卡驱动是r8125,而ubuntu20.04的驱动版本是r8169&#xff0c;所以是网卡驱动不匹配造成 解决方案 开机界面按下F2进入BOIS模式&#…...

xLua的Lua调用C#的2,3,4

使用Lua在Unity中创建游戏对象&#xff0c;组件&#xff1a; 相关代码如下&#xff1a; Lua --Lua实例化类 --C# Npc objnew Npc() --通过调用构造函数创建对象 local objCS.Npc() obj.HP100 print(obj.HP) local obj1CS.Npc("admin") print(obj1.Name)--表方法希…...

Debian系统_主板作为路由器_测试局域网设备间网速

Debian系统_主板作为路由器_测试局域网设备间网速 一、360软件测网速 360测出来的网速实际上是宽带的速度&#xff0c;并不是路由器LAN口到电脑这一段的网速 二、使用iperf3 进行双向带宽测试 1、开发板端下载软件 //Debian系统或者/Ubuntu sudo apt update && sudo…...

从 macos 切换到 windows 上安装的工具类软件

起因 用了很多年的macos, 已经习惯了macos上的操作, 期望能在windows上获得类似的体验, 于是花了一些时间来找windows上相对应的软件. 截图软件 snipaste​​​​​​ windows和macos都有的软件, 截图非常好用 文件同步软件 oneDrive: 尝试了不同的同步软件, 还是微软在各…...

JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)

目录 JavaScript中通过array.map(&#xff09;实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等&#xff0c;array.map&#xff08;&#xff09;的使用详解&#xff08;附实际应用代码&#xff09; 一、什么时候该使用Array.map()&#xff0…...

去除Mysql表中的空格、回车、换行符和特殊字符

系列文章目录 文章目录 系列文章目录前言一、示例1.sql层面2.java层面 前言 一、示例 1.sql层面 参考 ## 例子1 ## CHAR(10) 表示换行符 ## CHAR(13) 表示回车UPDATE 表名 SET 列名 REPLACE(REPLACE(列名, CHAR(10), ), CHAR(13), )## 例子2 ## 删除字段中的空格、换行符、…...

P9242 [蓝桥杯 2023 省 B] 接龙数列

这道题说要求最少删多少个使剩下的序列是接龙序列&#xff0c;这个问题可以转换为序列中最长的接龙序列是多少&#xff0c;然后用总长度减去最长接龙序列的长度就可以了&#xff0c;在第一个暴力版本的代码中我用了两个for循环求出了所有的接龙序列的长度&#xff0c;但是会超时…...

macos下 ragflow二次开发环境搭建

参考官网链接 https://ragflow.io/docs/dev/launch_ragflow_from_source虚拟环境 git clone https://github.com/infiniflow/ragflow.git cd ragflow/ # if not pipx, please install it at first pip3 install pipxpipx install uv uv sync --python 3.10 --all-extras 安装 …...

SQL优化技术分享:从 321 秒到 0.2 秒的性能飞跃 —— 基于 PawSQL 的 TPCH 查询优化实战

在数据库性能优化领域&#xff0c;TPC-H 测试集是一个经典的基准测试工具&#xff0c;常用于评估数据库系统的查询性能。本文将基于 TPCH 测试集中的第 20个查询&#xff0c;结合 PawSQL 自动化优化工具&#xff0c;详细分析如何通过 SQL 重写和索引设计&#xff0c;将查询性能…...

密码学基础——DES算法

前面的密码学基础——密码学文章中介绍了密码学相关的概念&#xff0c;其中简要地对称密码体制(也叫单钥密码体制、秘密密钥体制&#xff09;进行了解释&#xff0c;我们可以知道单钥体制的加密密钥和解密密钥相同&#xff0c;单钥密码分为流密码和分组密码。 流密码&#xff0…...

在 Linux 终端中轻松设置 Chromium 的 User-Agent:模拟手机模式与自定义浏览体验

在 Linux 系统中&#xff0c;通过终端灵活控制 Chromium 的行为可以大幅提升工作效率。本文将详细介绍如何通过命令行参数和环境变量自定义 Chromium 的 User-Agent&#xff0c;并结合手机模式模拟&#xff0c;实现更灵活的浏览体验。 为什么需要自定义 User-Agent&#xff1f;…...

ChatGPT 4:引领 AI 创作新时代

文章目录 前言一、ChatGPT 4 的技术革新二、AI 文案创作&#xff1a;精准生成与个性化定制三、AI 绘画艺术&#xff1a;从文字到图像的神奇转化四、AI 视频制作&#xff1a;自动化剪辑与创意实现五、知识库与 ChatGPT 4 的深度融合六、全新的变革和机遇七、相关书籍推荐《ChatG…...