【Docker】构建镜像时使用的 Dockerfile ,以及其中的 MicroDNF
·
目录
==================
■Docker 命令使用 Dockerfile
# 1. 默认使用 Dockerfile docker build . # 使用 Dockerfile # 2. 显式指定不同文件 docker build -f Dockerfile.dev . # 使用 Dockerfile.dev docker build -f Dockerfile.prod . # 使用 Dockerfile.prod
简单例子(Dockerfile中的内容)
====
# 第一阶段:构建阶段
FROM node:18-alpine AS builder
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制源代码
COPY src/ src/
# 第二阶段:运行阶段
FROM node:18-alpine AS runner
LABEL maintainer="team@example.com"
LABEL version="1.2.0"
WORKDIR /app
# 创建非root用户
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nodejs
# 从builder阶段复制文件
COPY --from=builder --chown=nodejs:nodejs /app /app
USER nodejs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node healthcheck.js || exit 1
CMD ["node", "src/server.js"]
====
基础指令
1. FROM - 指定基础镜像
# 必须放在第一行(除了注释和ARG) FROM ubuntu:22.04 FROM python:3.9-slim FROM node:18-alpine
2. RUN - 执行命令
# 在镜像构建时执行的命令 RUN apt-get update && apt-get install -y nginx RUN pip install -r requirements.txt RUN npm install
3. CMD - 容器启动命令
# 指定容器启动时的默认命令 CMD ["nginx", "-g", "daemon off;"] CMD ["python", "app.py"] CMD echo "Hello World"
4. ENTRYPOINT - 入口点
# 类似CMD,但不会被docker run后的命令覆盖 ENTRYPOINT ["docker-entrypoint.sh"] ENTRYPOINT ["nginx", "-g", "daemon off;"]
5. COPY - 复制文件
# 从宿主机复制文件到镜像 COPY app.py /app/ COPY requirements.txt /tmp/ COPY --chown=user:group src/ dest/
6. ADD - 添加文件(功能更强)
# 类似COPY,但可以解压压缩文件或从URL下载 ADD app.tar.gz /app/ # 自动解压 ADD https://example.com/file.tar.gz /tmp/ ADD . /app
7. ENV - 设置环境变量
# 设置环境变量,在容器运行时可用 ENV NODE_ENV=production ENV APP_VERSION=1.0.0 ENV PATH="/app/bin:$PATH"
配置指令
8. WORKDIR - 设置工作目录
# 设置后续命令的工作目录(会自动创建) WORKDIR /app WORKDIR /usr/src/app
9. EXPOSE - 声明端口
# 声明容器监听的端口(仅文档作用) EXPOSE 80 EXPOSE 443 EXPOSE 3000/tcp
10. USER - 指定用户
# 切换执行命令的用户 USER nginx USER 1000:1000 # UID:GID USER nobody
11. ARG - 构建参数
# 定义构建时的变量,只在构建时有效 ARG VERSION=latest ARG USERNAME=admin
12. VOLUME - 挂载点
# 创建挂载点(匿名卷) VOLUME /data VOLUME ["/var/log", "/var/db"]
优化与元数据指令
13. LABEL - 添加元数据
# 添加镜像的元数据标签 LABEL version="1.0" LABEL maintainer="dev@example.com" LABEL description="Web application"
14. HEALTHCHECK - 健康检查
# 定义容器健康检查 HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ CMD curl -f http://localhost/ || exit 1
15. SHELL - 指定shell
# 更改默认的shell SHELL ["/bin/bash", "-c"] SHELL ["powershell", "-Command"]
16. ONBUILD - 触发器指令
# 当本镜像被其他镜像作为基础时触发 ONBUILD COPY . /app ONBUILD RUN pip install -r requirements.txt
17. STOPSIGNAL - 停止信号
# 指定容器停止时发送的信号 STOPSIGNAL SIGTERM STOPSIGNAL SIGINT
多阶段构建指令
18. AS - 别名
# 多阶段构建中给阶段命名 FROM node:18 AS builder FROM nginx:alpine AS production
======
■Dockerfile 中的 MicroDNF
MicroDNF 在镜像制作中
==
# microdnf 是制作镜像的工具之一 FROM ubi8/ubi-minimal # ← 这个基础镜像已经包含了 microdnf # 使用 microdnf 安装软件包来构建镜像 RUN microdnf install -y nginx \ && microdnf clean all # ← 这是构建过程的一部分
=
MicroDNF 本身就是镜像的一部分
# 查看镜像中的 microdnf docker run --rm ubi8/ubi-minimal which microdnf # 输出:/usr/bin/microdnf docker run --rm ubi8/ubi-minimal ls -lh /usr/bin/microdnf # 输出:显示 microdnf 文件大小(约1-2MB)
-
microdnf 是 被包含在镜像中的工具
-
就像蓝图里包含"去哪个家具店购物"的说明
层次结构对比
| 层级 | 内容 | microdnf 的作用 |
|---|---|---|
| 镜像 | 静态文件层 | 1. microdnf 是镜像中的一个文件 2. microdnf 用于在构建时安装其他软件 |
| 容器 | 运行实例 | 1. microdnf 是可执行命令 2. 可以临时安装软件(不推荐) |
| Dockerfile | 构建指令 | 1. 使用 RUN microdnf install 指令2. 定义镜像构建过程 |
更形象的比喻
一家汽车工厂(Docker): 1. 设计图纸(镜像)上写着: - "从工具库(microdnf)取螺丝刀、扳手" - "安装发动机、轮胎" 2. 生产车间(构建过程): - 工人按照图纸,从工具库拿工具 - 用工具安装零件,生产出汽车 3. 成品汽车(容器): - 可以在使用时临时放东西(microdnf安装) - 但不改变设计图纸
===
-
microdnf 是工具:像螺丝刀、扳手
-
镜像是设计蓝图:包含"使用什么工具"的说明
-
容器是成品:运行时可以临时使用工具
===
镜像 = 基础系统 + microdnf工具 容器 = 镜像的实例化运行 microdnf的作用 = ①构建镜像时安装软件 ②容器内临时管理软件
====
场景1:构建新镜像
# 创建 Dockerfile
cat > Dockerfile << 'EOF'
FROM ubi8/ubi-minimal
# 1. 使用镜像中的 microdnf
RUN microdnf install -y httpd
# 2. 生成包含 httpd 的新镜像
CMD ["httpd", "-DFOREGROUND"]
EOF
# 构建镜像(microdnf 在构建过程中起作用)
docker build -t my-webapp .
场景2:在运行的容器中调试
# 1. 从镜像运行容器
docker run -d --name web my-webapp
# 2. 进入运行的容器
docker exec -it web /bin/bash
# 3. 在容器内使用 microdnf 安装调试工具
[root@web]# microdnf install -y curl wget
# 4. 容器被修改了,但镜像没变
===
■镜像举例
=============
FROM icr.io/appcafe/websphere-liberty:25.0.0.12-full-java21-openj9-ubi-minimal
---
拆分说明
---
| 方面 | 说明 |
|---|---|
| FROM 指令 | 指定基础镜像,所有后续操作都基于此镜像。 |
| 镜像全称 | icr.io/appcafe/websphere-liberty:25.0.0.12-full-java21-openj9-ubi-minimal |
| 镜像来源 | IBM 官方容器注册中心,由 IBM 维护。 |
| Liberty 版本 | 25.0.0.12(2025 年版本) |
| 特性集 | full – 包含所有受支持的 Liberty 特性。 |
| Java 版本 | Java 21(LTS 版本) |
| JVM 实现 | OpenJ9 – 由 IBM 开源贡献的高效 JVM,低内存占用、启动快。 |
| 操作系统 | UBI Minimal – Red Hat 提供的精简安全基础镜像。 |
| OpenJ9 与 IBM 关系 | 源于 IBM 的 J9 JVM,IBM 将之开源为 Eclipse OpenJ9,并持续主导其开发。IBM 官方 Java 运行时(Semeru)即基于 OpenJ9。 |
==
icr.io 补充说明
| 组成部分 | 代表含义 | 解释 |
|---|---|---|
| I | IBM | 毫无疑问,代表这个服务的归属方是 IBM 公司。 |
| CR | Container Registry | 这是“容器镜像仓库”的英文缩写,直接点明了服务的性质——用于存储和分发容器镜像的地方。 |
| .io | 顶级域名 | 这是一个流行的顶级域名,常被科技公司(尤其是云服务和初创企业)采用,因为它简短、现代,并且可以联想到“输入/输出”的概念,与科技行业很契合。 |
===
Registry 和 repository 之间的区别
| 概念 | 类比 | 在镜像地址中的位置 | 示例 |
|---|---|---|---|
| Registry(注册表) | 像是一个代码托管平台(如 GitHub)或软件商店,它是一个服务,负责托管和管理多个项目。 | 镜像地址的主机名部分(域名或IP)。 | docker.io(Docker Hub)、quay.io、icr.io(IBM 注册表) |
| Repository(仓库) | 像是一个具体的项目或软件包(例如 GitHub 上的一个代码库),它包含了同一个软件或应用的所有版本镜像。 | 镜像地址中主机名之后、标签之前的部分,通常按命名空间/名称组织。 | library/ubuntu(Docker Hub 上的 Ubuntu 官方库)、ibmcom/websphere-liberty、appcafe/websphere-liberty |
===
ubi-minimal 补充说明
Minimal /ˈmɪn.ɪ.məl/
Minimal 在这里是“最小化”、“精简”的意思。它表示这个基础镜像只包含运行应用程序所绝对必要的最小系统组件,去除了所有非必需的软件包、工具和库。
| 方面 | 说明 |
|---|---|
| UBI 英文全称 | Universal Base Image(通用基础镜像) |
| 开发维护者 | Red Hat(红帽公司) |
| 与 Ubuntu 的关系 | UBI 与 Ubuntu 没有直接关系。它们是两个不同的 Linux 发行版系列: • UBI 基于 Red Hat Enterprise Linux (RHEL) 构建,使用 RPM 包管理,注重企业级稳定性、安全认证和长生命周期支持,特别适合在 Red Hat OpenShift 等红帽生态中使用。 • Ubuntu 是基于 Debian 的发行版,使用 APT/DEB 包管理,由 Canonical 公司维护,社区活跃,更新较快,广泛用于开发环境和云部署。 |
| UBI Minimal 特点 | • 精简安全:仅包含运行 Liberty 和 Java 所需的最小系统组件,减少了潜在攻击面。 • 企业兼容:完全符合 Red Hat 的企业级支持标准,可与 Red Hat 生态系统无缝集成。 • 体积小巧:相比标准 UBI 镜像,Minimal 版本进一步去除了非必需的工具和库,显著降低镜像大小,适合容器化部署。 |
| 使用场景优势 | 使用 UBI Minimal 作为基础镜像,可以确保您的应用运行在一个经过加固、受官方支持且与生产环境(尤其是 OpenShift)高度一致的 Linux 环境中,同时还能享受 OpenJ9 和 Liberty 带来的性能优势。 |
==
更多推荐
所有评论(0)