Dockerfile 生成器
概览
这项技能提供了一个全面的工作流程,用于生成遵循当前标准和最佳实践的生产就绪 Dockerfile。生成多阶段构建、安全加固配置和优化的层结构,并自动验证和迭代错误修复。
主要特点:
- 多阶段构建以优化镜像大小(减少 50-85%)
- 安全加固(非根用户、最小基础镜像、无密钥)
- 层缓存优化以加快构建速度
- 语言特定模板(Node.js、Python、Go、Java)
- 自动 .dockerignore 生成
- 与 devops-skills:dockerfile-validator 集成以进行验证
- 迭代验证和错误修复(如果发现错误至少迭代 1 次)
- WebSearch 和 context7 集成用于框架特定模式
何时使用此技能
在以下情况下调用此技能:
- 从头开始创建新的 Dockerfile
- 容器化应用程序(Node.js、Python、Go、Java或其他语言)
- 实施多阶段构建以优化大小
- 将现有 Dockerfile 转换为最佳实践
- 生成生产就绪的容器配置
- 为安全性和性能优化 Docker 构建
- 用户要求“创建”、“生成”、“构建”或“编写”Dockerfile
- 为微服务实现容器化
- 设置 CI/CD 管道容器构建
不要为此技能使用
- 验证现有的 Dockerfile(改用 devops-skills:dockerfile-validator)
- 构建或运行容器(使用 docker build/run 命令)
- 调试运行中的容器(使用 docker logs、docker exec)
- 管理 Docker 镜像或注册表
Dockerfile 生成工作流程
按照此工作流程生成 Dockerfile。根据用户需求调整:
第一阶段:收集需求
**目标:**了解需要容器化的内容并收集所有必要的信息。
需要收集的信息:
-
应用程序详细信息:
- 编程语言和版本(Node.js 18/20、Python 3.11/3.12、Go 1.21+、Java 17/21 等)
- 应用程序类型(Web 服务器、API、CLI 工具、批处理作业等)
- 框架(Express、FastAPI、Spring Boot 等)
- 入口点(主文件、运行命令)
-
依赖项:
- 包管理器(npm/yarn/pnpm、pip/poetry、go mod、maven/gradle)
- 系统依赖项(构建工具、库等)
- 构建时与运行时依赖项
-
应用程序配置:
- 要暴露的端口
- 需要的环境变量
- 配置文件
- 健康检查端点(Web 服务)
- 卷挂载(如果有)
-
构建需求:
- 构建命令
- 测试命令(可选)
- 编译需求(对于编译语言)
- 静态资产生成
-
生产需求:
- 预期的镜像大小限制
- 安全要求
- 扩展需求
- 资源限制(CPU、内存)
如果信息缺失或不清晰,请使用 AskUserQuestion。
示例问题:
- 您的应用程序使用哪种编程语言和版本?
- 运行您的应用程序的主入口点是什么?
- 您的应用程序是否暴露任何端口?如果是,哪些?
- 您的应用程序是否需要除基础语言运行时之外的任何系统依赖项?
- 您的应用程序是否需要健康检查端点?
第二阶段:框架/库文档查找(如果需要)
**目标:**研究框架特定的容器化模式和最佳实践。
何时执行此阶段:
- 用户提到特定框架(Next.js、Django、FastAPI、Spring Boot 等)
- 应用程序具有复杂的构建需求
- 需要框架特定优化的指导
研究过程:
-
首先尝试 context7 MCP(首选):
使用 mcp__context7__resolve-library-id 与框架名称 示例: - "next.js" 用于 Next.js 应用程序 - "django" 用于 Django 应用程序 - "fastapi" 用于 FastAPI 应用程序 - "spring-boot" 用于 Spring Boot 应用程序 - "express" 用于 Express.js 应用程序 然后使用 mcp__context7__get-library-docs 与: - 从解析步骤中获取 context7CompatibleLibraryID - topic: "docker deployment production build" - page: 1(如果需要,获取额外页面) -
如果 context7 失败,则退回到 WebSearch:
搜索查询模式: "<框架>" "<版本>" dockerfile 最佳实践生产 2025 示例: - "Next.js 14 dockerfile 最佳实践生产 2025" - "FastAPI dockerfile 最佳实践生产 2025" - "Spring Boot 3 dockerfile 最佳实践生产 2025" -
提取关键信息:
- 推荐的基镜像
- 构建优化技术
- 框架特定环境变量
- 生产与开发配置
- 安全考虑
第三阶段:生成 Dockerfile
**目标:**创建遵循最佳实践的生产就绪、多阶段 Dockerfile。
核心原则:
-
多阶段构建(编译语言必需,所有语言推荐):
- 分离构建阶段和运行时阶段
- 将构建工具从最终镜像中移除
- 仅复制必要的工件
- 结果是 50-85% 更小的镜像
-
安全加固(必需):
- 使用特定版本标签(永远不使用 :latest)
- 以非根用户运行(创建专用用户)
- 使用最小基础镜像(alpine、distroless)
- 不要硬编码密钥
- 扫描基础镜像中的漏洞
-
层优化(必需):
- 从最少变化到最频繁变化的顺序排列指令
- 在应用程序代码之前复制依赖文件
- 使用 && 结合相关的 RUN 命令
- 在同一层中清理包管理器缓存
- 有效利用构建缓存
-
生产就绪(必需):
- 为服务添加 HEALTHCHECK
- 使用 exec 形式的 ENTRYPOINT/CMD
- 设置绝对路径的 WORKDIR
- 使用 EXPOSE 文档化暴露的端口
语言特定模板:
Node.js 多阶段 Dockerfile
# syntax=docker/dockerfile:1
# 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
# 复制依赖文件以进行缓存
COPY package*.json ./
# 使用 npm ci 进行确定性构建
RUN npm ci --only=production && \
npm cache clean --force
# 复制应用程序代码
COPY . .
# 构建应用程序(如果需要)
# RUN npm run build
# 生产阶段
FROM node:20-alpine AS production
WORKDIR /app
# 创建非根用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# 从构建器复制依赖项和应用程序
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --chown=nodejs:nodejs . .
# 切换到非根用户
USER nodejs
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# 启动应用程序
CMD ["node", "index.js"]
Python 多阶段 Dockerfile
# syntax=docker/dockerfile:1
# 构建阶段
FROM python:3.12-slim AS builder
WORKDIR /app
# 安装构建依赖项
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖项
RUN pip install --no-cache-dir --user -r requirements.txt
# 生产阶段
FROM python:3.12-slim AS production
WORKDIR /app
# 创建非根用户
RUN useradd -m -u 1001 appuser
# 从构建器复制依赖项
COPY --from=builder /root/.local /home/appuser/.local
# 复制应用程序代码
COPY --chown=appuser:appuser . .
# 更新 PATH
ENV PATH=/home/appuser/.local/bin:$PATH
# 切换到非根用户
USER appuser
# 暴露端口
EXPOSE 8000
# 健康检查(根据需要调整端点)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()" || exit 1
# 启动应用程序
CMD ["python", "app.py"]
Go 多阶段 Dockerfile
# syntax=docker/dockerfile:1
# 构建阶段
FROM golang:1.21-alpine AS builder
WORKDIR /app
# 复制 go mod 文件
COPY go.mod go.sum ./
RUN go mod download
# 复制源代码
COPY . .
# 构建应用程序
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o main .
# 生产阶段(使用 distroless 以获得最小镜像)
FROM gcr.io/distroless/static-debian12 AS production
WORKDIR /
# 从构建器复制二进制文件
COPY --from=builder /app/main /main
# 暴露端口
EXPOSE 8080
# 健康检查(distroless 没有 shell,因此此注释)
# HEALTHCHECK 不支持无 shell 的 distroless
# 切换到非根用户(distroless 默认以非 root 运行)
USER nonroot:nonroot
# 启动应用程序
ENTRYPOINT ["/main"]
Java 多阶段 Dockerfile
# syntax=docker/dockerfile:1
# 构建阶段
FROM eclipse-temurin:21-jdk-jammy AS builder
WORKDIR /app
# 复制 Maven 包装器和 pom.xml
COPY mvnw pom.xml ./
COPY .mvn .mvn
# 下载依赖项(缓存层)
RUN ./mvnw dependency:go-offline
# 复制源代码
COPY src ./src
# 构建应用程序
RUN ./mvnw clean package -DskipTests && \
mv target/*.jar target/app.jar
# 生产阶段(使用 JRE 而不是 JDK)
FROM eclipse-temurin:21-jre-jammy AS production
WORKDIR /app
# 创建非根用户
RUN useradd -m -u 1001 appuser
# 从构建器复制 JAR
COPY --from=builder --chown=appuser:appuser /app/target/app.jar ./app.jar
# 切换到非根用户
USER appuser
# 暴露端口
EXPOSE 8080
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
# 启动应用程序
ENTRYPOINT ["java", "-jar", "app.jar"]
选择逻辑:
- Node.js:用于 JavaScript/TypeScript 应用程序
- Python:用于 Python 应用程序(Web、API、脚本)
- Go:用于 Go 应用程序(非常适合最小镜像)
- Java:用于 Spring Boot、Quarkus 或其他 Java 框架
- 通用:为其他语言创建自定义 Dockerfile
始终包括:
- 语法指令:
# syntax=docker/dockerfile:1 - 多阶段构建(构建 + 生产阶段)
- 创建并使用非根用户
- 服务的 HEALTHCHECK(如果适用)
- 适当的 WORKDIR 设置
- 文档化的 EXPOSE 端口
- 清理包管理器缓存
- CMD/ENTRYPOINT 的 exec 形式
第四阶段:生成 .dockerignore
**目标:**创建全面的 .dockerignore 以减少构建上下文并防止密钥泄露。
生成 Dockerfile 时始终创建 .dockerignore。
标准 .dockerignore 模板:
# Git
.git
.gitignore
.gitattributes
# CI/CD
.github
.gitlab-ci.yml
.travis.yml
.circleci
# 文档
README.md
CHANGELOG.md
CONTRIBUTING.md
LICENSE
*.md
docs/
# Docker
Dockerfile*
docker-compose*.yml
.dockerignore
# 环境
.env
.env.*
*.local
# 日志
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 依赖项(语言特定 - 根据需要添加)
node_modules/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
venv/
.venv/
target/
*.class
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# 测试
coverage/
.coverage
*.cover
.pytest_cache/
.tox/
test-results/
# 构建工件
dist/
build/
*.egg-info/
根据语言定制:
- Node.js:添加
node_modules/,npm-debug.log,yarn-error.log - Python:添加
__pycache__/,*.pyc,.venv/,.pytest_cache/ - Go:添加
vendor/,*.exe,*.test - Java:添加
target/,*.class,*.jar(除了最终工件)
第五阶段:使用 devops-skills:dockerfile-validator 验证
**目标:**确保生成的 Dockerfile 遵循最佳实践并且没有问题。
必需:生成后始终验证。
验证过程:
-
调用 devops-skills:dockerfile-validator 技能:
使用技能工具调用 devops-skills:dockerfile-validator 这将运行: - hadolint(语法和最佳实践) - Checkov(安全扫描) - 自定义验证(层优化等) -
解析验证结果:
- 按严重程度分类问题(错误、警告、信息)
- 确定可操作的修复
- 优先处理安全问题
-
预期的验证输出:
[1/4] 语法验证(hadolint) [2/4] 安全扫描(Checkov) [3/4] 最佳实践验证 [4/4] 优化分析
第六阶段:迭代验证错误
**目标:**修复任何验证错误并重新验证。
必需:如果验证发现错误,则至少迭代一次。
迭代过程:
-
如果验证发现错误:
- 分析每个错误
- 将修复应用到 Dockerfile
- 重新运行验证
- 重复直到清理或最多 3 次迭代
-
如果验证发现警告:
- 评估警告是否可以接受
- 为关键警告应用修复
- 记录压制的警告并说明理由
-
常见修复:
- 为基镜像添加版本标签
- 在 CMD 之前添加 USER 指令
- 为服务添加 HEALTHCHECK
- 结合 RUN 命令
- 清理包管理器缓存
- 使用 COPY 代替 ADD
示例迭代:
迭代 1:
- 错误:DL3006 - 缺少版本标签
- 修复:将 FROM node:alpine 更改为 FROM node:20-alpine
- 重新验证
迭代 2:
- 警告:DL3059 - 多个连续的 RUN 命令
- 修复:使用 && 结合 RUN 命令
- 重新验证
迭代 3:
- 所有检查通过 ✓
第七阶段:最终审查和建议
**目标:**提供全面的总结和后续步骤。
交付物:
-
生成的文件:
- Dockerfile(经过验证和优化)
- .dockerignore(全面)
-
验证摘要:
- 所有验证结果
- 任何剩余的警告(附有理由)
- 安全扫描结果
-
使用说明:
# 构建镜像 docker build -t myapp:1.0 . # 运行容器 docker run -p 3000:3000 myapp:1.0 # 测试健康检查(如果适用) curl http://localhost:3000/health -
优化指标(必需 - 提供明确的估计):
始终包括这样的摘要:
## 优化指标 | 指标 | 估计 | |--------|----------| | 镜像大小 | ~150MB(与没有多阶段的 ~500MB 相比,减少了 70%) | | 构建缓存 | 为依赖项启用了层缓存 | | 安全 | 非根用户、最小基础镜像、无密钥 |语言特定大小估计:
- Node.js:与完整 node 镜像相比,使用 Alpine 时约为 50-150MB(~1GB)
- Python:与完整 python 镜像相比,使用 slim 时约为 150-250MB(~900MB)
- Go:与完整 golang 镜像相比,使用 distroless/scratch 时约为 5-20MB(~800MB)
- Java:与 JDK 相比,使用 JRE 时约为 200-350MB(~500MB+)
-
后续步骤(必需 - 始终以项目列表形式包括):
始终提供明确的后续步骤:
## 后续步骤 - [ ] 测试本地构建:`docker build -t myapp:1.0 .` - [ ] 运行并验证容器按预期工作 - [ ] 更新 CI/CD 管道以使用新的 Dockerfile - [ ] 考虑使用 BuildKit 缓存挂载以实现更快的构建(见现代 Docker 特性) - [ ] 设置使用 `docker scout` 或 `trivy` 的自动漏洞扫描 - [ ] 添加到容器注册表并部署
生成脚本(可选参考)
scripts/ 目录包含用于手动 Dockerfile 生成的独立 bash 脚本,这些脚本不在此技能之外:
generate_nodejs.sh- Node.js Dockerfile 的 CLI 工具generate_python.sh- Python Dockerfile 的 CLI 工具generate_golang.sh- Go Dockerfile 的 CLI 工具generate_java.sh- Java Dockerfile 的 CLI 工具generate_dockerignore.sh- .dockerignore 生成的 CLI 工具
**目的:**这些脚本是参考实现和手动工具,供想要通过命令行生成 Dockerfile 的用户使用,而不是使用 Claude Code。它们展示了此技能中嵌入的相同最佳实践。
**使用此技能时:**Claude 直接使用此技能.md 中记录的模板和模式生成 Dockerfile,而不是调用这些脚本。此文档中的模板是权威来源。
脚本使用示例:
# 手动 Dockerfile 生成
cd .claude/skills/dockerfile-generator/scripts
./generate_nodejs.sh --version 20 --port 3000 --output Dockerfile
最佳实践参考
安全最佳实践
-
使用特定标签:
# 差 FROM node:alpine # 好 FROM node:20-alpine # 更好(带有用于可重复性的摘要) FROM node:20-alpine@sha256:abc123... -
以非根用户运行:
# 创建用户 RUN addgroup -g 1001 -S appgroup && \ adduser -S appuser -u 1001 -G appgroup # 在 CMD 之前切换到用户 USER appuser -
使用最小基础镜像:
- Alpine Linux(小而安全)
- Distroless(无 shell,最小攻击面)
- 特定运行时镜像(node:alpine vs node:latest)
-
永远不要硬编码密钥:
# 差 ENV API_KEY=secret123 # 好 - 使用构建密钥 # docker build --secret id=api_key,src=.env RUN --mount=type=secret,id=api_key \ API_KEY=$(cat /run/secrets/api_key) ./configure
优化最佳实践
-
层缓存:
# 首先复制依赖文件 COPY package.json package-lock.json ./ RUN npm ci # 最后复制应用程序代码 COPY . . -
结合 RUN 命令:
# 差(创建 3 个层) RUN apt-get update RUN apt-get install -y curl RUN rm -rf /var/lib/apt/lists/* # 好(创建 1 个层) RUN apt-get update && \ apt-get install -y --no-install-recommends curl && \ rm -rf /var/lib/apt/lists/* -
多阶段构建:
# 构建阶段 - 可以很大 FROM node:20 AS builder WORKDIR /app COPY . . RUN npm install && npm run build # 生产阶段 - 最小化 FROM node:20-alpine COPY --from=builder /app/dist ./dist CMD ["node", "dist/index.js"]
生产就绪
-
健康检查:
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1 -
正确信号:
# 使用 exec 形式以正确处理信号 CMD ["node", "server.js"] # 好 CMD node server.js # 差(无信号转发) -
元数据:
LABEL maintainer="team@example.com" \ version="1.0.0" \ description="My application"
常见模式
模式 1:带有 Next.js 的 Node.js
# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]
模式 2:带有 FastAPI 的 Python
# syntax=docker/dockerfile:1
FROM python:3.12-slim AS builder
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 --user -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
RUN useradd -m -u 1001 appuser
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser:appuser . .
ENV PATH=/home/appuser/.local/bin:$PATH
USER appuser
EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
模式 3:Go CLI 工具
# syntax=docker/dockerfile:1
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /bin/app
FROM scratch
COPY --from=builder /bin/app /app
ENTRYPOINT ["/app"]
现代 Docker 特性(2025)
多平台构建与 BuildX
**用例:**构建在 AMD64 和 ARM64 架构上均能工作的镜像(例如,x86 服务器和 Apple Silicon Mac)。
启用 BuildX:
# BuildX 默认包含在 Docker Desktop 中
# 对于 Linux,请确保已安装 BuildX
docker buildx version
创建多平台镜像:
# 为多个平台构建
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myapp:latest \
--push \
.
# 为当前平台构建并加载(测试)
docker buildx build \
--platform linux/amd64 \
-t myapp:latest \
--load \
.
Dockerfile 考虑因素:
# 大多数 Dockerfile 自动跨平台工作
# 需要时使用特定平台的基础镜像
FROM --platform=$BUILDPLATFORM node:20-alpine AS builder
# 访问构建参数以获取平台信息
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM"
何时使用:
- 在混合基础设施(x86 + ARM)上部署
- 支持 Apple Silicon Mac 在开发中的使用
- 针对 AWS Graviton(基于 ARM 的)实例进行优化
- 构建跨平台 CLI 工具
软件物料清单(SBOM)
**用例:**生成 SBOM 以实现供应链安全和合规性(在 2025 年日益成为要求)。
在构建期间生成 SBOM:
# 使用 BuildKit 生成 SBOM(Docker 24.0+)
docker buildx build \
--sbom=true \
-t myapp:latest \
.
# SBOM 附加到镜像的证明
# 查看 SBOM
docker buildx imagetools inspect myapp:latest --format "{{ json .SBOM }}"
从现有镜像生成 SBOM:
# 使用 Syft
syft myapp:latest -o json > sbom.json
# 使用 Docker Scout
docker scout sbom myapp:latest
SBOM 好处:
- 跨供应链的漏洞跟踪
- 许可合规性验证
- 依赖项透明度
- 安全审查的审计跟踪
- 政府/企业合同所需
与 CI/CD 集成:
# GitHub Actions 示例
- name: 构建带有 SBOM
run: |
docker buildx build \
--sbom=true \
--provenance=true \
-t myapp:latest \
--push \
.
BuildKit 缓存挂载(高级)
**用例:**通过持久化包管理器缓存,实现更快的构建。
已在 references/optimization_patterns.md(第 98-125 行)中详细说明。
快速参考:
# syntax=docker/dockerfile:1
# NPM 缓存挂载(构建速度提高 30-50%)
RUN --mount=type=cache,target=/root/.npm \
npm ci
# Go 模块缓存
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
# Pip 缓存
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
错误处理
常见生成问题
-
缺少依赖文件:
- 确保 package.json、requirements.txt、go.mod、pom.xml 存在
- 请求用户提供或生成模板
-
未知框架:
- 使用 WebSearch 或 context7 进行研究
- 退回到通用模板
- 请求用户提供具体需求
-
验证失败:
- 自动应用修复
- 迭代直到清理
- 记录任何抑制
与其他技能的集成
此技能与以下技能很好地结合使用:
- devops-skills:dockerfile-validator - 验证生成的 Dockerfile(必需)
- k8s-generator - 为容器生成 Kubernetes 部署
- helm-generator - 创建带有容器镜像的 Helm 图表
注释
- 始终使用多阶段构建 编译语言
- 始终创建非根用户 以提高安全性
- 始终生成 .dockerignore 以防止密钥泄露
- 始终使用 devops-skills:dockerfile-validator 进行验证
- 如果验证发现错误,则至少迭代一次
- 尽可能使用 Alpine 或 distroless 基础镜像
- 固定所有版本标签(永远不使用 :latest)
- 在同一层中清理包管理器缓存
- 从最少变化到最频繁变化的顺序排列 Dockerfile 指令
- 使用 BuildKit 功能进行高级优化
- 在提交之前测试本地构建
- 保持 Dockerfile 简单且易于维护
- 使用注释记录任何非显而易见的模式
来源
此技能基于来自权威来源的综合研究:
官方 Docker 文档:
安全指南:
优化资源: