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

栏目: IT技术 · 发布时间: 4年前

内容简介:原文:http://progressivecoder.com/docker-multi-stage-build-for-running-react-application-on-nginx-server/Docker 多阶段构建(Multi-Stage)是一种创建生产环境 Docker 镜像的极佳途径。

原文:http://progressivecoder.com/docker-multi-stage-build-for-running-react-application-on-nginx-server/

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

如果你是一位 Docker 新手,强烈推荐你先阅读“理解 Docker 基础”一文 (http://progressivecoder.com/understanding-the-basics-of-docker/)。另一“从头为 NodeJS 应用创建 Dockerfile” (http://progressivecoder.com/creating-a-dockerfile-for-nodejs-application-from-scratch/) 也很有意思。

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

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

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

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

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

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

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

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

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

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

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

从此刻起,构建阶段就结束了。对于随后开始的运行阶段,使用 nginx 作为基础镜像。然后,我们将构建阶段中  npm run build 命令的结果,也就是  构建产物 (诸如  index.html 和  main.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 和 Nginx 的 Docker 多阶段构建

接下来,在 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(译注:实际项目中明确写好启动命令还是比较常见的,参考 https://github.com/tonylua/vue-cli-3-preset/blob/master/template/Dockerfile )。

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 应用运行界面:

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

总结

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

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

--End--

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

查看更多前端好文

请搜索 fewelife 关注公众号

转载请注明出处


以上所述就是小编给大家介绍的《[译] 面向 React 和 Nginx 的 Docker 多阶段构建》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Swift编程权威指南(第2版)

Swift编程权威指南(第2版)

[美] Matthew Mathias、[美] John Gallagher / 陈晓亮 / 人民邮电出版社 / 2017-6 / 89.00元

Big Nerd Ranch是美国一家专业的移动开发技术培训机构,本书是其培训教材。书中系统讲解了在iOS和macOS平台上,使用苹果的Swift语言开发iPhone、iPad和Mac应用的基本概念和编程技巧。主要围绕使用Swift语言进行iOS和macOS开发,结合大量代码示例,教会读者利用高级iOS和macOS特性开发真实的应用。一起来看看 《Swift编程权威指南(第2版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码