使用多阶段构建
go应用程序
# Build stage
FROM golang:1.16 AS build
WORKDIR /app
COPY . .
RUN go build -o myapp .
# Runtime stage
FROM alpine:latest
WORKDIR /root/
COPY --from=build /app/myapp .
CMD ["./myapp"]
Nodejs应用程序
# Build stage
FROM node:14 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Runtime stage
FROM node:14-alpine
WORKDIR /app
COPY --from=build /app/package*.json ./
RUN npm install --only=production
COPY --from=build /app/build ./build
CMD ["node", "build/server.js"]
Java应用程序
# Build stage
FROM maven:3.6.3-jdk-11 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn -f pom.xml clean package
# Runtime stage
FROM openjdk:11-jre-slim
COPY --from=build /app/target/my-application.jar /usr/app/
WORKDIR /usr/app
EXPOSE 8080
CMD ["java", "-jar", "my-application.jar"]
选择正确的基础镜像
优化 Python 应用程序
FROM python:3.8
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
优化后
FROM python:3.8-slim
COPY . /app
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]
将多阶段构建与 Alpine 一起用于 Node.js 应用程序
# Build stage
FROM node:14-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Runtime stage
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app/build ./build
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "build/index.js"]
最小化层数
合并RUN、ENV指令
删除不必要的文件
FROM node:14
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package.json .
RUN npm install --production && \
npm cache clean --force
COPY . .
CMD ["node", "app.js"]
FROM python:3.8
COPY . .
RUN pip install --no-cache-dir -r requirements.txt && \
rm requirements.txt
ENV JAVA_HOME=/opt/jdk1.8.0_241 \
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib \
PATH=$PATH:$JAVA_HOME/bin
利用 Docker 忽略文件
Node.js应用程序的示例 .dockerignore 文件
node_modules
npm-debug.log
.DS_Store
.env
.git
.gitignore
README.md
LICENSE
docker-compose.yml
Dockerfile
tests/
.dockerignore 集成到 Python 项目中
*.pyc
*.pyo
*.pyd
__pycache__
.env
.git
.gitignore
README.md
Dockerfile
tests/
优化软件安装
FROM ubuntu:latest
RUN apt-get update && \
apt-get install -y curl git vim && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
FROM python:3.8-slim
RUN pip install --no-cache-dir flask gunicorn && \
find / -type d -name __pycache__ -prune -exec rm -rf {} \;
设置时区
FROM alpine:3.11.5
ENV TZ=Asia/Shanghai
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
设置系统语言
FROM alpine:3.11.5
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8
RUN apk --no-cache add ca-certificates \
&& wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \
&& wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-2.29-r0.apk \
&& wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-bin-2.29-r0.apk \
&& wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-i18n-2.29-r0.apk \
&& apk add glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk \
&& rm -rf /usr/lib/jvm glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk \
&& /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true \
&& echo "export LANG=$LANG" > /etc/profile.d/locale.sh \
&& apk del glibc-i18n
尽可能使用静态二进制文件
FROM golang:1.16 AS builder
WORKDIR /build
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .
FROM scratch
COPY --from=builder /build/myapp /myapp
CMD ["/myapp"]
使用 BuildKit 压缩镜像层
启用 BuildKit
BuildKit包含在 Docker18.09 及更高版本中,但默认情况下不启用。通过设置 DOCKER_BUILDKIT 环境变量来启用
export DOCKER_BUILDKIT=1
docker build .
或者将 Docker 守护程序配置为默认使用 BuildKit
{ "features": { "buildkit": true } }
使用 BuildKit 优化映像构建
FROM node:14
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
挤压镜像层
使用 docker export 和 docker import
docker build -t my-app .
docker container create --name temp-container my-app
docker export temp-container | docker import - my-app:squashed
docker container rm temp-container
使用 Docker Squash 工具
pip install docker-squash
docker save my-app:latest | docker-squash -t my-app:squashed | docker load