惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
H
Hacker News: Front Page
Stack Overflow Blog
Stack Overflow Blog
B
Blog
I
InfoQ
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
F
Full Disclosure
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recent Announcements
Recent Announcements
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
T
Tailwind CSS Blog
S
Secure Thoughts
P
Privacy International News Feed
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LINUX DO - 最新话题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Cybersecurity and Infrastructure Security Agency CISA
Last Week in AI
Last Week in AI
W
WeLiveSecurity
Google Online Security Blog
Google Online Security Blog
P
Privacy & Cybersecurity Law Blog
D
DataBreaches.Net
Engineering at Meta
Engineering at Meta
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Project Zero
Project Zero
V2EX - 技术
V2EX - 技术
H
Heimdal Security Blog
博客园 - Franky
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Troy Hunt's Blog
V
Vulnerabilities – Threatpost
H
Help Net Security
Martin Fowler
Martin Fowler
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
G
GRAHAM CLULEY
博客园 - 【当耐特】

博客园 - xiashengwang

Rocky Linux 9 安装docker Rocky Linux 9 与Centos区别,以及软件安装dnf命令 《Linux 基础点滴》:(17)SSH 密钥生成与管理 – 免密登录的利器 Linux服务器安全登录:从入门到实践 putty 基础 《Linux 基础点滴》:(16)firewalld 防火墙管理命令 《Linux 基础点滴》:(15)用户管理 – 创建、删除、权限与 sudo 《Linux 基础点滴》:(14)定时任务 – 用 crontab 自动化 《Linux 基础点滴》:(13)文本编辑入门 – 使用 Vim 《Linux 基础点滴》:(12)tldr – 简化版命令手册 《Linux 基础点滴》:(11)系统信息与资源监控 – 掌握服务器状态 《Linux 基础点滴》:(10)压缩与打包 – tar 的艺术 《Linux 基础点滴》:(9)查找与过滤 – find, grep, 管道 《Linux 基础点滴》:(8)网络基础 – 查看 IP、连通性与端口 《Linux 基础点滴》:(7)进程管理 – 查看与控制运行中的程序 《Linux 基础点滴》:(6)文件权限与所有者 – 保护你的文件 《Linux 基础点滴》:(5)文件与目录操作 – 增删改查必会命令 《Linux 基础点滴》:(4)磁盘空间查看 – df 和 du 的妙用 《Linux 基础点滴》:(3)Linux 文件系统概览 – 一切皆文件 《Linux 基础点滴》:(2)SSH 连接与基础命令 – 从登录到第一次操作 《Linux 基础点滴》:(1)初识 Linux 大家族 – 发行版分类与选择 docker学习(7)-docker compose 文件 docker学习(11)- 容器的日志(log) docker学习(10)-利用Github Action 自动化部署 docker学习(9)-Docker Swarm + Nginx 跨机器负载均衡 docker学习(8)-从 Windows 开发到 Linux 部署 docker学习(6)-数据持久化与网络通信 学会 Git Tag,让版本管理不再混乱 docker学习(4)-Docker常用命令 docker学习(3)-一个简单的例子 docker学习(2)-安装 docker学习(1)-基本概念 Github 使用 Self-hosted Runner 实现服务器自动化部署 github创建分支 + Pull Request 合并 Git Rebase vs Git Merge:深入理解与实战选择 Git 系统学习教程:从零到团队协作 AI学习笔记(2)-OpenClaw安装 windbg分析dmp文件 docker desktop 和 Vmware冲突的解决办法
docker学习(5)-Dockerfile
xiashengwang · 2026-04-15 · via 博客园 - xiashengwang

2026-04-15 18:01  xiashengwang  阅读(24)  评论()    收藏  举报

一、Dockerfile 基础

1. Dockerfile是什么
Dockerfile 是一个文本文件,包含了一系列指令,用于自动化构建 Docker 镜像。每个指令都会在镜像中创建一个新的层。

2. 常用指令详解

指令 说明 示例
FROM 指定基础镜像,必须是第一条指令 FROM python:3.9-slim
RUN 在构建时执行命令,用于安装软件包等 RUN apt-get update && apt-get install -y curl
COPY 将本地文件复制到镜像中,推荐使用 COPY app.py /app/
ADD 类似 COPY,但支持自动解压 tar 和 URL 下载 ADD app.tar.gz /app/
WORKDIR 设置工作目录,后续指令在该目录下执行 WORKDIR /app
ENV 设置环境变量 ENV NODE_ENV=production
ARG 定义构建参数,构建时通过 --build-arg 传递 ARG VERSION=latest
EXPOSE 声明容器运行时监听的端口(仅文档作用) EXPOSE 8080
CMD 容器启动时执行的命令,可被 docker run 覆盖 CMD ["python", "app.py"]
ENTRYPOINT 容器启动时执行的命令,不可被覆盖(可追加参数) ENTRYPOINT ["python"]
VOLUME 声明数据卷,用于持久化 VOLUME /data
USER 指定运行用户(安全) USER appuser
LABEL 添加元数据 LABEL version="1.0"
HEALTHCHECK 定义健康检查命令 HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD curl -f http://localhost/ || exit 1

注意:

  • RUN 尽量合并为一条,减少层数。
  • CMDENTRYPOINT 的区别:ENTRYPOINT 定义容器的主要进程,CMD 提供默认参数。通常组合使用:ENTRYPOINT ["python"]CMD ["app.py"],这样 docker run image script.py 可覆盖 app.py

二、镜像分层与构建缓存

1. 镜像分层原理
Docker 镜像由多个只读层叠加而成。每条指令创建一个新层。当运行容器时,在最上面添加一个可写层。
优点:

  • 共享基础层,节省磁盘空间和网络带宽。
  • 构建时利用缓存,如果某层未改变,则直接利用缓存。

2. 构建缓存最佳实践

  • 将不常变化的层放在前面,如依赖安装。
  • 例如,先 COPY requirements.txt,再 RUN pip install,这样只要 requirements.txt 不变,依赖层就会使用缓存。
  • 频繁变化的代码放在后面,如 COPY .

3. 查看镜像历史
docker history <image>
可看到各层的大小和构建指令。

三、编写高效的 Dockerfile

1. 选择合适的基础镜像

  • alpine:体积小(5MB),但可能存在兼容性问题。
  • slim:官方精简版,体积适中(~150MB),推荐用于 Python/Node.js。
  • 全量版:体积大,但包含所有工具,适合开发。
    原则:在满足需求的前提下,选择尽可能小的基础镜像。

2. 减少层数

  • 合并 RUN 指令,例如 RUN apt-get update && apt-get install -y package && rm -rf /var/lib/apt/lists/*
    对于Debian/Ubuntu系(nginx,node,python),安装软件后删除缓存:rm -rf /var/lib/apt/lists/*
    对于Alpine系(node:alpine、nginx:alpine),安装软件后删除缓存:RUN apk add --no-cache 你要装的软件

3. 清理临时文件
在同一个 RUN 中安装后删除缓存,避免镜像臃肿。
比如上面的最后一条命令:rm -rf /var/lib/apt/lists/*

4. 使用 .dockerignore
在同一个 RUN 中安装后删除缓存,避免镜像臃肿。

  • 创建 .dockerignore 文件,排除不需要的文件(如 node_modules.git__pycache__),加快构建并减小上下文。

.dockerignore

# 通用
.git
.gitignore
.env
.DS_Store

# Node
node_modules
npm-debug.log
dist

# Python
__pycache__
.venv
*.pyc

5. 多阶段构建(Multi-stage Builds)
多阶段构建允许你在一个 Dockerfile 中使用多个 FROM 语句,最终只将需要的产物复制到最终镜像中,极大减小镜像体积。

# 构建阶段
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

上面这段,node:18只是用于编译,真正的输出镜像是基于nginx:alpine的。并且docker有缓存机制,node:18的npm安装不会每次都下载,只要package*.json不变,他就会跳过,节省编译时间。

6. 安全实践

  • 避免以 root 用户运行:创建专用用户并切换。
  • 使用 COPY 而非 ADD,除非需要自动解压。
  • 固定基础镜像版本:避免使用 latest,指定具体标签(如 python:3.9-slim)。

四、实践任务

1:为 Python Flask 应用编写优化的 Dockerfile

  • 使用 python:3.9-slim 作为基础镜像
  • 设置非 root 用户运行
  • 使用多阶段构建?不需要,但可尝试将依赖安装与代码复制分离,利用缓存
  • 最终镜像尽可能小(<200MB)

1)创建dockerfile,如下:

# 使用官方 Python slim 镜像
FROM Python:3.9-slim

#环境变量
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1

#创建非root用户
RUN addgroup --system app && adduser --system --group app

# 设置工作目录
WORKDIR /app

# 安装系统依赖(如有需要)
RUN apt-get update && apt-get install -y --no-install-recommends gcc && rm -rf /var/lib/apt/lists/*

# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY app.py .

# 切换到非root用户
USER app

# 暴露应用端口
EXPOSE 5000

# 启动应用
CMD ["python", "app.py"]

2)构建镜像:
切换到项目的根目录,执行以下命令:
docker build -t flask-app-optimized .
语法是这样的:

docker build    [选项]        [参数]
      构建      -t 标签      在哪里找Dockerfile

3)查看镜像大小
docker images
怎么感觉比之前那个还大?
image

4)运行容器测试
docker run -d --name my-flask-app-optimized -p 5001:5000 flask-app-optimized
如果出错,可以查看log,命令如下:
docker logs 容器名
image

5)分析镜像层
使用 docker history 分析任一镜像的层大小
image

6)使用 .dockerignore
在项目根目录创建 .dockerignore 文件,内容示例:

__pycache__
*.pyc
*.pyo
*.pyd
.Python
.env
.git
.gitignore
.idea
.vscode
*.log

在构建时就不会使用这些文件,加快构建时间。