跳到主要内容

多阶段构建

2024年06月24日
柏拉文
越努力,越幸运

一、认识


多阶段构建(Multi-stage Builds 是一种在 Dockerfile 中使用多个 FROM 指令的方法。每个 FROM 指令标志着一个新的构建阶段。多阶段构建允许你在一个 Dockerfile 中定义多个构建阶段,并在最后阶段中只保留实际需要的文件,从而创建一个更小、更高效的 Docker 镜像。这种方法特别适用于需要构建和运行的应用程序,例如需要编译的 GoJavaC++ 等语言的应用程序。

多阶段构建的优势:

  1. 减少镜像大小: 运行阶段不包含构建工具和依赖,最终生成的镜像更小。这减少了传输和存储的开销。

  2. 提高安全性: 通过剥离不必要的构建工具和依赖,可以减少潜在的安全风险。

  3. 构建效率高: 多阶段构建允许在单个 Dockerfile 中定义和管理多个构建阶段,这提高了构建效率并减少了重复下载和编译的时间。

  4. 简化 CI/CD 流程: 多阶段构建使得在 CI/CD 流程中更容易构建和发布高效的 Docker 镜像。

二、操作


实现多阶段构建的步骤如下:

  1. 定义多个构建阶段: 在一个 Dockerfile 中使用多个 FROM 指令。如下所示:

    FROM node:latest as nodeBuilder 

    ……

    FROM nginx:latest
  2. 使用 AS 关键字命名阶段: 为每个阶段命名,方便在后续阶段中引用。

    FROM node:latest as nodeBuilder 

    ……

    FROM nginx:latest
  3. 复制文件: 使用 COPY --from=<stage> 指令从一个阶段复制文件到另一个阶段。语法如下:

    COPY --from=<stage1> stage1目录  stage2目录

三、最佳实践


3.1 Web 构建

阶段一、构建阶段 使用 Node.js 官方镜像安装依赖并构建 Vue.js 应用。

  1. 使用 Node.js 镜像作为构建阶段的基础镜像

  2. 设置工作目录为 /app

  3. package.jsonpackage-lock.json 复制到 /app 目录

  4. 安装项目依赖

  5. 将项目文件复制到 /app 目录

  6. 运行 npm run build 构建 Vue.js 应用

阶段二、运行阶段 使用 Nginx 官方镜像作为基础镜像,将构建的文件复制到 Nginx 静态文件目录。

  1. 使用 Nginx 镜像作为运行阶段的基础镜像

  2. 将构建阶段生成的 dist 目录下的文件复制到 Nginx 静态文件目录

  3. 将自定义的 nginx.conf 配置文件复制到 Nginx 配置文件目录

  4. 暴露 80 端口并启动 Nginx 服务

  5. 使用 nginx -g "daemon off;" 命令启动 Nginx 服务

Dockerfile

FROM node:latest as nodeBuilder
WORKDIR /app
COPY package*.json /app
RUN npm install
COPY . /app
RUN npm run build

FROM nginx:latest
COPY --from=nodeBuilder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx/conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

nginx.conf

server {
listen 80;

server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}

# 可选:代理 API 请求到后端服务
location /api {
proxy_pass http://backend:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

.dockerignore

node_modules
dist
.git
.dockerignore
.gitignore
README.md

构建 Docker 镜像

docker build -t vue-app . 

运行 Docker 镜像

docker run -d --name vue-app -p 9090:80 vue-app

3.2 Node 构建