Dockerfile最佳实践

奥黛丽·逐爱者
2025-06-23 / 0 评论 / 0 阅读 / 正在检测是否收录...
使用多阶段构建

❌ 错误示范

一个常见的错误是在单个阶段中构建所有内容,最终导致构建的镜像中包含所有构建依赖项,特别臃肿

FROM node:22WORKDIR /appCOPY . .RUN npm installRUN npm run buildEXPOSE 3000CMD ["npm", "start"]

✅正确做法

使用多阶段构建将构建环境与运行时环境分开。

# Build stageFROM node:22 AS buildWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .RUN npm run build
# Production stageFROM node:22-slimWORKDIR /appCOPY --from=build /app/dist ./distCOPY --from=build /app/package*.json ./RUN npm install --only=productionEXPOSE 3000CMD ["npm", "start"]

选择正确的基础镜像

❌ 错误示范

FROM ubuntu:latestRUN apt-get update && apt-get install -y python3 python3-pipCOPY . /appWORKDIR /appRUN pip install -r requirements.txtCMD ["python3", "app.py"]

✅正确做法

选择满足您要求的最小基础镜像,查找带有 Docker Hub 官方徽章或已验证发布者标记的基础镜像,因为这些映像往往更安全且维护得更好。

FROM python:3.12-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .CMD ["python", "app.py"]

使用固定的镜像版本号

❌ 错误示范

不要使用像 latest 这样可能会意外更改的镜像版本。

FROM node:latestWORKDIR /appCOPY . .RUN npm installCMD ["node", "index.js"]

✅正确做法

固定到特定镜像版本。

FROM node:22.1.0WORKDIR /appCOPY . .RUN npm installCMD ["node", "index.js"]

即便使用固定的基础镜像版本,由于安全更新等原因远程仓库存储的镜像也可能会发生改变,如果你不希望这种改变发生,使用哈希摘要版本号来保证镜像不变。

FROM node:22.1.0@sha256:12a331df1e31e40b2f37d2524037973908895fb766b8bce742cdf8b1216e5ac2WORKDIR /appCOPY . .RUN npm installCMD ["node", "index.js"]

优化镜像层缓存

❌ 错误示范

不要将频繁变化的文件放在前面。

FROM node:22WORKDIR /app# 源代码变化频繁,直接拷贝源代码会导致后续的镜像层缓存失效,构建变慢COPY . .RUN npm installCMD ["npm""start"]

✅正确做法

先拷贝包依赖管理文件,如果依赖没有变化,npm install将使用缓存而无需重新下载依赖,加速构建过程。

FROM node:22WORKDIR /app# Copy package files firstCOPY package*.json ./# Install dependenciesRUN npm install# Then copy the rest of the codeCOPY . .CMD ["npm""start"]

正确处理apt-get和其他包管理器

❌ 错误示范

不要将 update 和 install 命令分开,此方法会缓存 apt-get update 结果,这意味着以后的构建可能会安装过时的软件包。

FROM ubuntu:24.04RUN apt-get updateRUN apt-get install -y nginxRUN apt-get install -y curl

✅正确做法

始终将 update 和 install 合并到单个 

RUN 指令中。

FROM ubuntu:24.04RUN apt-get update && apt-get install ---no-install-recommends \   nginx \   curl \&& rm -rf /var/lib/apt/lists/*

使用.dockerignore排除不必要的文件

❌ 错误示范

不要将整个项目目录作为构建上下文发送。

# Without .dockerignore, everything gets sent to Docker daemon$ docker build -t myapp .

✅正确做法

创建.dockerignore文件排除不必要的文件,这可以减小构建上下文的大小,加快构建过程,并有助于防止敏感信息泄漏到您的镜像中。

.git.github.gitignorenode_modulesnpm-debug.logDockerfile.dockerignore*.md.env**.logcoveragedistbuildtmp

不要为环境变量创建多个镜像层

❌ 错误示范

每个环境变量会生成一个新的镜像层。

FROM node:22ENV NODE_ENV=productionENV APP_PORT=3000ENV APP_VERSION=1.2.3

✅正确做法

FROM node:22# Group related environment variablesENV NODE_ENV=production \   APP_PORT=3000 \   APP_VERSION=1.2.3

设置适当的用户

❌ 错误示范

直接以root用户运行。

FROM nginx:alpineCOPY app/ /usr/share/nginx/htmlImplicitly runs as rootCMD ["nginx""-g""daemon off;"]

✅正确做法

创建和使用非特权用户。

FROM nginx:alpine# Create a non-root userRUN addgroup -g 1000 appgroup && \   adduser -u 1000 -G appgroup -h /home/appuser -D appuser
# Configure applicationCOPY --chown=appuser:appgroup app/ /usr/share/nginx/html
# For services that need to bind to privileged ports,# start as root then switch to the non-root userUSER appuser
# For processes that don't need rootCMD ["nginx""-g""daemon off;"]

使用WORKDIR而不是RUN cd

❌ 错误示范

这种方法易出错,难阅读。

FROM node:22# Bad practice - using cd commandsRUN cd /opt && mkdir appRUN cd /opt/app && npm init -yCOPY . /opt/app/RUN cd /opt/app && npm installCMD cd /opt/app && npm start

✅正确做法

使用WORKDIR 指定目录。

FROM node:22# Good practice - using WORKDIRWORKDIR /opt/appRUN npm init -yCOPY . .RUN npm installCMD ["npm", "start"]

0

评论 (0)

取消