导航菜单

Dockerfile 完全指南

陆兴东 2026-04-09 187 浏览 Docker

Dockerfile 基础

 

Dockerfile 指令大全

 

# ============ 基础指令 ============          

# FROM: 指定基础镜像          
FROM ubuntu:22.04          
FROM alpine:3.18          
FROM scratch# 空白镜像,用于构建最小镜像          

# LABEL: 添加元数据          
LABEL maintainer="your-email@example.com"          
LABEL version="1.0"          
LABEL description="This is a sample image"          

# RUN: 执行命令          
RUN apt-get update && apt-get install -y \          
    curl \          
    vim \          
    && rm -rf /var/lib/apt/lists/*          

# CMD: 容器启动时的默认命令          
CMD ["nginx", "-g", "daemon off;"]          
CMD ["python", "app.py"]          
CMD echo "Hello World"          

# ENTRYPOINT: 容器启动时的入口点          
ENTRYPOINT ["python", "app.py"]          
ENTRYPOINT ["nginx"]          

# ============ 文件操作 ============          

# COPY: 从主机复制文件到镜像          
COPY app.py /app/          
COPY . /app/          
COPY --from=builder /app/build /app/          

# ADD: 类似 COPY,但支持 URL 和自动解压          
ADD https://example.com/file.tar.gz /tmp/          
ADD archive.tar.gz /usr/local/# 自动解压          

# ============ 环境和配置 ============          

# ENV: 设置环境变量          
ENV APP_ENV=production          
ENV PATH="/app/bin:${PATH}"          
ENV \          
    APP_VERSION=1.0 \          
    APP_ENV=production          

# ARG: 构建时的参数          
ARG VERSION=1.0          
ARG BASE_IMAGE=ubuntu:22.04          
FROM ${BASE_IMAGE}          

# WORKDIR: 设置工作目录          
WORKDIR /app          
WORKDIR /var/www/html          

# ============ 端口和用户 ============          

# EXPOSE: 声明容器监听的端口          
EXPOSE 80 443          
EXPOSE 3000          

# USER: 指定运行用户          
USER nginx          
USER 1000:1000          

# ============ 卷和触发器 ============          

# VOLUME: 创建挂载点          
VOLUME ["/data"]          
VOLUME ["/var/log/app", "/var/lib/app"]          

# ONBUILD: 在子镜像构建时执行          
ONBUILD COPY . /app/          
ONBUILD RUN pip install -r requirements.txt          

# ============ 健康检查 ============          

# HEALTHCHECK: 健康检查指令          
HEALTHCHECK --interval=30s --timeout=3s \          
CMD curl -f http://localhost/ || exit 1          

HEALTHCHECK NONE# 禁用基础镜像的健康检查          

# ============ Shell 和信号 ============          

# SHELL: 覆盖默认 shell          
SHELL ["/bin/bash", "-c"]          

# STOPSIGNAL: 设置停止信号          
STOPSIGNAL SIGTERM          
STOPSIGNAL 9

 

________________________________________________________________________________

 

4.2 Dockerfile 最佳实践

 

1. 最小化镜像层数

 

# ❌ 不推荐:多层 RUN          
RUN apt-get update          
RUN apt-get install -y curl          
RUN apt-get install -y vim          
RUN rm -rf /var/lib/apt/lists/*          

# ✅ 推荐:合并 RUN 指令          
RUN apt-get update && apt-get install -y \          
    curl \          
    vim \          
    && rm -rf /var/lib/apt/lists/*

 

2. 使用 .dockerignore

 

# .dockerignore 文件示例          
.git          
.gitignore          
node_modules          
npm-debug.log          
.env          
__pycache__          
*.pyc          
.vscode          
.DS_Store          
*.md          
tests/          
*.test.js          
coverage/

 

3. 优化缓存利用

 

# ✅ 推荐:将变化少的指令放在前面          
FROM node:18-alpine          
WORKDIR /app          

# 先复制依赖文件(变化少)          
COPY package*.json ./          
RUN npm ci --only=production          

# 再复制源代码(变化多)          
COPY . .          

CMD ["node", "app.js"]

 

4. 多阶段构建

 

# ========== 构建阶段 ==========          
FROM node:18-alpine AS builder          

WORKDIR /app          
COPY package*.json ./          
RUN npm ci          
COPY . .          
RUN npm run build          

# ========== 生产阶段 ==========          
FROM node:18-alpine          

WORKDIR /app          
COPY --from=builder /app/dist ./dist          
COPY --from=builder /app/node_modules ./node_modules          
COPY package*.json ./          

EXPOSE 3000          
CMD ["node", "dist/app.js"]

 

5. 使用非 root 用户

 

FROM alpine:3.18          

# 安装必要的工具          
RUN apk add --no-cache curl          

# 创建用户          
RUN addgroup -g 1000 appuser && \          
    adduser -D -u 1000 -G appuser appuser          

# 设置工作目录并设置权限          
WORKDIR /app          
COPY --chown=appuser:appuser . .          

# 切换到非 root 用户          
USER appuser          

CMD ["python", "app.py"]

 

_________________________

 

4.3 实战 Dockerfile 示例

 

示例 1: Node.js 应用

 

# 多阶段构建          
FROM node:18-alpine AS builder          

WORKDIR /app          

# 安装依赖          
COPY package*.json ./          
RUN npm ci --only=production          

# 复制源代码          
COPY . .          

# 构建应用          
RUN npm run build          

# 生产镜像          
FROM node:18-alpine          

WORKDIR /app          

# 从构建阶段复制          
COPY --from=builder /app/dist ./dist          
COPY --from=builder /app/node_modules ./node_modules          
COPY package*.json ./          

# 创建非 root 用户          
RUN addgroup -g 1000 node && \          
    adduser -D -u 1000 -G node node          

# 设置权限          
RUN chown -R node:node /app          
USER node          

EXPOSE 3000          

# 健康检查          
HEALTHCHECK --interval=30s --timeout=3s \          
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"          

CMD ["node", "dist/app.js"]

 

示例 2: Python 应用

 

FROM python:3.11-slim          

# 设置环境变量          
ENV PYTHONDONTWRITEBYTECODE=1 \          
    PYTHONUNBUFFERED=1 \          
    PIP_NO_CACHE_DIR=1 \          
    PIP_DISABLE_PIP_VERSION_CHECK=1          

WORKDIR /app          

# 安装系统依赖          
RUN apt-get update && apt-get install -y \          
    gcc \          
    postgresql-client \          
    && rm -rf /var/lib/apt/lists/*          

# 安装 Python 依赖          
COPY requirements.txt .          
RUN pip install --no-cache-dir -r requirements.txt          

# 复制应用代码          
COPY . .          

# 创建非 root 用户          
RUN useradd -m -u 1000 appuser && \          
    chown -R appuser:appuser /app          
USER appuser          

EXPOSE 8000          

# 健康检查          
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \          
CMD curl -f http://localhost:8000/health || exit 1          

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

 

示例 3: Nginx 静态网站

 

FROM nginx:alpine          

# 删除默认配置          
RUN rm /etc/nginx/conf.d/default.conf          

# 复制自定义配置          
COPY nginx.conf /etc/nginx/nginx.conf          
COPY conf.d/ /etc/nginx/conf.d/          

# 复制静态文件          
COPY html/ /usr/share/nginx/html/          

# 创建 nginx 用户          
RUN addgroup -g 1000 nginx && \          
    adduser -D -u 1000 -G nginx nginx          

# 创建必要的目录并设置权限          
RUN mkdir -p /var/cache/nginx /var/log/nginx && \          
    chown -R nginx:nginx /var/cache/nginx /var/log/nginx && \          
    chown -R nginx:nginx /usr/share/nginx/html          

USER nginx          

EXPOSE 80 443          

CMD ["nginx", "-g", "daemon off;"]