[译] 面向 React 和 Nginx 的 Docker 多阶段构建

原文:progressivecoder.com/docker-mult…html

Docker 多阶段构建(Multi-Stage) 是一种建立生产环境 Docker 镜像的极佳途径。前端

若是你是一位 Docker 新手,强烈推荐你先阅读“理解 Docker 基础”一文 (progressivecoder.com/understandi…)。另外一篇“从头为 NodeJS 应用建立 Dockerfile” (progressivecoder.com/creating-a-…) 也颇有意思。vue

若你已经掌握了 Docker 基础知识,就能够跟随如下每一步的细致讲解继续阅读了。node

1. 为何要用 Docker 多阶段构建?

Docker 多阶段构建 是 Docker 17.05 版本开始才有的一个相对较新的特性。多阶段构建容许咱们将多个 FROM 语句放在同一个 Dockerfile 中。react

每条 FROM 指令均可以使用各自不一样的基础镜像。每一个 FROM 语句也都标记了 Docker 构建过程当中一个新阶段的开始。咱们能够拷贝一个阶段的产出物到另外一个阶段,也能够抛弃不须要的部分。nginx

基本上,在咱们不但愿构建过程依赖项被拷贝到最终镜像的状况下这是个很是有用的特性。换句话说,Docker 多阶段构建帮助咱们把镜像变得更小了git

2. 开发和生产过程的区别

为了演示 Docker 多阶段构建,咱们将以一个 React 应用为例github

下图展现了要成功构建和运行一个 React 应用所须要完成的事情。web

Docker 多阶段构建

如上所示,整个过程被分为 构建阶段运行阶段vue-cli

在构建阶段,咱们以 node:alpine 基础镜像开始。基本上,咱们要作的就是使用 NodeJS 安装依赖项。最后,以生产环境为目的使用 npm run build 构建应用。

今后刻起,构建阶段就结束了。对于随后开始的运行阶段,使用 nginx 做为基础镜像。而后,咱们将构建阶段中 npm run build 命令的结果,也就是 构建产物(诸如 index.htmlmain.js 等文件),拷贝到 nginx 服务器目录中。这时候,除了咱们拷贝的构建产物以外,构建阶段产生的其它全部文件和目录都将被抛弃,并不会归入最终镜像。

在最后一个步骤,咱们能够启动 nginx 以伺服 React 应用。

3. 创建 React 应用

先生成一个简单的 React 应用。

要快速开始的话,咱们先安装 create-react-app 包,它能够快速生成一个 ReactJS 应用。如下面的命令全局安装:

npm install -g create-react-app
复制代码

一旦安装完成,就能够用其生成项目。在终端中进入想要创建项目的目录,并执行如下命令。

create-react-app docker-react-app
复制代码

这将建立一个名为 docker-react-app 的应用,用于咱们的例子。

4. 建立多阶段的 Dockerfile

如今能够建立咱们的 Dockerfile 以支持多阶段 Docker 构建过程了。 注意该文件要放置在项目根目录下

react application dockerfile
供参考的项目目录结构

接下来,在 Dockerfile 中添加如下内容:

#构建阶段
FROM node:alpine as builder
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
RUN npm run build

#运行阶段
FROM nginx
COPY --from=builder /app/build /usr/share/nginx/html
复制代码

下面详细解释这两个阶段。

构建阶段

步骤 1 – 以 node:alpine 做为基础镜像。同时咱们将该阶段定名为 builder。这将帮助咱们在其后引用这个阶段。

步骤 2 – 接下来,为应用指定工做目录。这也是构建产物将要被建立的位置。

步骤 3 – 将 package.json 文件拷贝到工做目录。npm 须要该文件以安装所需依赖项。注意咱们只拷贝了 package.json 文件以确保对于随后因为代码更改而发生的构建,不会使 docker 镜像缓存失效(译注:对于 COPY 和 ADD 命令,会计算镜像内的文件和构建目录文件的校验和,而后作比较来判断本层是否有改动;若是只改了 src 的文件但依赖项没变,就能够利用这层的缓存从而加速构建)。

步骤 4 – 在下一步中,使用 npm install 命令安装依赖项。也就是安装了被 .dockerignore 忽略的 node_modules 目录。

步骤 5 – 而后,将其它文件拷贝到工做目录,也就是包含了应用真正代码的那些文件。

步骤 6 – 下一步,执行 npm run build 命令。该命令将准备好 React 应用的生产环境构建产物。也就是说,该命令会生成用来伺服客户端的 index.html 文件和 main.js 文件。

运行阶段

步骤 1 – 以 nginx 基础镜像开始运行阶段。Nginx 是一个很是流行的 web-server,是伺服静态文件的理想工具。

步骤 2 – 接着,咱们从 builder 阶段拷贝构建产物到 nginx 所需的位置。注意咱们经过 –from=builder tag 引用了 构建阶段,并从构建阶段的工做目录拷贝了 /app/build

这样咱们就完成了 Docker 多阶段构建的 Dockerfile

这里的一个重点是对于 nginx 不须要显式的 RUN 命令。nginx 基础镜像自己会在 80 端口启动 web-server(译注:实际项目中明确写好启动命令仍是比较常见的,参考 github.com/tonylua/vue… )。

5. 测试 React 应用

为了测试 React 应用,先如下面的命令,基于多阶段 Dockerfile 构建一个镜像:

docker build -t docker-react-app .
复制代码

在第一次执行时这会费一点时间,由于全部的基础镜像和依赖项都会被下载。

一旦构建完成,运行下面的命令来运行它:

docker run -p 8080:80 docker-react-app
复制代码

这里基本就是运行了镜像并将 nginx 的 80 端口映射到了咱们本机上的 8080 端口。

咱们没在命令行窗口中看到太多可视化的输出。可是,当咱们打开浏览器并访问 http://localhost:8080 ,将看到如下 React 应用运行界面:

docker multi stage react app

总结

在本文中,咱们使用 Docker 多阶段构建 过程成功运行了一个 Nginx server 上的 React 应用。

咱们将构建的过程分为了构建阶段和运行阶段。应用在构建过程当中被建立后,将其产出拷贝到运行阶段并抛弃无用的部分。这大大地减小了镜像的整体积。



--End--

查看更多前端好文
请搜索 fewelife 关注公众号

转载请注明出处

相关文章
相关标签/搜索