Dockerfile 完全指南 🐳

🚀 掌握Docker镜像构建的艺术,打造高效、安全的容器化应用
📋 目录
- 🎯 Dockerfile 简介
- 📝 指令详解
- 🏗️ 多阶段构建
- ✅ 最佳实践
- 🔒 安全指南
- ⚡ 实战示例
- 🚀 构建与优化
- 🐛 调试技巧
🎯 Dockerfile 简介
📖 什么是 Dockerfile?
Dockerfile 是一个文本文件,包含了一系列的指令和参数,用于自动化构建 Docker 镜像。它就像是容器的”食谱”,定义了如何构建应用程序的运行环境。
🎨 基本结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| FROM ubuntu:20.04
LABEL maintainer="your.email@example.com" LABEL version="1.0" LABEL description="My awesome application"
ENV APP_HOME=/app \ NODE_ENV=production
WORKDIR $APP_HOME
COPY . .
RUN apt-get update && \ apt-get install -y python3 pip && \ pip install -r requirements.txt
EXPOSE 8000
CMD ["python3", "app.py"]
|
📝 指令详解
🏗️ FROM - 基础镜像
1 2 3 4 5 6 7 8 9
| FROM python:3.9-slim
FROM node:16.15.1-alpine3.16
FROM golang:1.19 as builder FROM alpine:3.16 as runtime
|
⚙️ RUN - 执行命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| RUN apt-get update
RUN apt-get update && \ apt-get install -y \ git \ curl \ wget && \ rm -rf /var/lib/apt/lists/*
RUN curl -sSL https://deb.nodesource.com/setup_16.x | bash -
RUN mkdir -p /app/logs && \ chmod 755 /app/logs
|
📂 COPY vs ADD - 文件复制
1 2 3 4 5 6 7 8 9 10 11
| COPY ./src /app/src COPY package*.json ./ COPY requirements.txt .
ADD https://example.com/file.tar.gz /tmp/ ADD local-file.tar.gz /tmp/
COPY --chown=node:node . /app
|
🎯 CMD vs ENTRYPOINT - 启动命令
1 2 3 4 5 6 7 8 9
| CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["/app/start.sh"]
ENTRYPOINT ["/app/entrypoint.sh"] CMD ["--help"]
|
🌐 ENV - 环境变量
1 2 3 4 5 6 7 8 9 10 11
| ENV APP_VERSION=1.0.0
ENV APP_HOME=/app \ PORT=3000 \ NODE_ENV=production
ARG BUILD_VERSION ENV VERSION=$BUILD_VERSION
|
📁 WORKDIR - 工作目录
1 2 3 4 5 6 7 8 9
| WORKDIR /app
RUN pwd
WORKDIR /app/src RUN pwd
|
🚪 EXPOSE - 端口暴露
1 2 3 4 5 6 7 8 9
| EXPOSE 80
EXPOSE 80 443 3000
EXPOSE 80/tcp EXPOSE 53/udp
|
👤 USER - 用户设置
1 2 3 4 5 6 7 8 9
| RUN groupadd -r app && \ useradd -r -g app app
USER app
USER 1000:1000
|
🏗️ 多阶段构建
🎯 为什么使用多阶段构建?
· 减小镜像大小 🐋 → 🐢
· 提高安全性 🔒
· 分离构建和运行环境 🏗️ → 🚀
📦 完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| FROM node:16 as builder WORKDIR /build COPY package*.json ./ RUN npm ci --only=production
FROM node:16 as tester WORKDIR /test COPY . . COPY --from=builder /build/node_modules ./node_modules RUN npm test
FROM node:16-alpine as runtime WORKDIR /app
RUN apk add --no-cache tzdata && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=builder /build/node_modules ./node_modules COPY . .
RUN addgroup -g 1001 -S app && \ adduser -u 1001 -S app -G app USER app
EXPOSE 3000 CMD ["node", "server.js"]
|
🔧 高级多阶段技巧
1 2 3 4 5 6 7 8 9 10 11 12 13
| FROM nginx:alpine as web COPY --from=builder /app/dist /usr/share/nginx/html
FROM scratch COPY --from=builder /app/bin/app / CMD ["/app"]
FROM --platform=$BUILDPLATFORM golang:1.19 as builder ARG TARGETARCH RUN GOARCH=$TARGETARCH go build -o /app
|
✅ 最佳实践
🎯 1. 使用官方镜像
1 2 3 4 5 6
| FROM python:3.9-slim
FROM ubuntu:20.04 RUN apt-get update && apt-get install -y python3
|
📦 2. 优化层缓存
1 2 3 4 5 6 7 8 9 10
| COPY package.json package-lock.json ./ RUN npm install
COPY . .
COPY . . RUN npm install
|
🧹 3. 清理缓存和临时文件
1 2 3 4 5 6 7 8
| RUN apt-get update && \ apt-get install -y \ build-essential \ git && \ apt-get purge -y build-essential git && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/*
|
📝 4. 使用 .dockerignore
创建 .dockerignore 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| .git .gitignore README.md Dockerfile .dockerignore
node_modules logs temp dist
*.log *.tmp *.swp
|
🔧 5. 健康检查
1 2 3 4 5 6
| HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:3000/health || exit 1
HEALTHCHECK NONE
|
🔒 安全指南
🛡️ 1. 避免以root运行
1 2 3 4 5 6
| RUN adduser -D -u 1000 appuser USER appuser
USER 1000
|
🔐 2. 使用可信的基础镜像
1 2 3 4 5
| FROM debian:bullseye-20221004-slim
|
📦 3. 最小化安装
1 2 3 4 5 6 7
| RUN apt-get update && \ apt-get install -y \ --no-install-recommends \ ca-certificates \ curl && \ rm -rf /var/lib/apt/lists/*
|
🚨 4. 安全扫描
1 2 3 4 5
| docker scout quickview <image-name>
trivy image <image-name>
|
⚡ 实战示例
🐍 Python 应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| FROM python:3.9-slim as production
ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=on
WORKDIR /app
RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc \ libpq-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd --create-home --shell /bin/bash app USER app
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
|
⚛️ Node.js 应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| FROM node:18-alpine as builder WORKDIR /build COPY package*.json ./ RUN npm ci --only=production
FROM node:18-alpine as runtime WORKDIR /app
COPY --from=builder /build/node_modules ./node_modules COPY --chown=node:node . .
USER node
EXPOSE 3000 ENV NODE_ENV=production
CMD ["node", "src/index.js"]
|
🐹 Go 应用
1 2 3 4 5 6 7 8 9 10 11 12
| FROM golang:1.19 as builder WORKDIR /build COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o app .
FROM scratch COPY --from=builder /build/app /app COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ EXPOSE 8080 CMD ["/app"]
|
🚀 构建与优化
⚡ 构建命令
1 2 3 4 5 6 7 8 9 10 11
| docker build -t my-app:1.0 .
docker build -f Dockerfile.prod -t my-app:prod .
docker build --build-arg VERSION=1.0.0 -t my-app .
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:multi .
|
🎯 构建参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ARG VERSION=latest ARG BUILD_NUMBER
LABEL version=$VERSION ENV BUILD_NUMBER=$BUILD_NUMBER
RUN if [ "$VERSION" = "dev" ] ; then \ npm install; \ else \ npm ci --only=production; \ fi
|
📊 镜像分析
1 2 3 4 5 6 7 8 9
| docker history my-app:latest
docker images my-app
docker save my-app:latest | docker run -i --rm \ wagoodman/dive:latest
|
🐛 调试技巧
🔍 调试Dockerfile
1 2 3 4 5 6 7 8
| RUN if [ "$DEBUG" = "true" ] ; then \ apt-get update && \ apt-get install -y curl vim; \ fi
ARG DEBUG=false
|
📝 调试命令
1 2 3 4 5 6 7 8 9 10 11
| docker build --target builder -t debug .
docker run -it --rm --entrypoint sh debug
docker run -it --rm my-app ls -la /app
docker run -it --rm my-app env
|
🐳 Docker BuildKit 特性
1 2 3 4 5 6 7 8 9
| DOCKER_BUILDKIT=1 docker build .
docker build --progress=plain .
docker build --no-cache . docker build --cache-from=my-app:previous .
|
💡 专业提示: 定期更新基础镜像以获取安全补丁,使用多阶段构建来减小镜像大小,并且始终扫描镜像中的漏洞。记住,一个好的Dockerfile就像是应用程序的文档,它应该清晰、简洁且易于维护。
Happy Dockerizing! 🎉 祝您构建顺利!