内容简介:原文: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 应用所需要完成的事情。
如上所示,整个过程被分为 构建阶段 和 运行阶段 。
在构建阶段,我们以 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 构建过程了。 注意该文件要放置在项目根目录下 。
接下来,在 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 应用运行界面:
总结
在本文中,我们使用 Docker 多阶段构建 过程成功运行了一个 Nginx server 上的 React 应用。
我们将构建的过程分为了构建阶段和运行阶段。应用在构建过程中被创建后,将其产出拷贝到运行阶段并抛弃无用的部分。这大大地减少了镜像的总体积。
--End--
查看更多前端好文
请搜索 fewelife 关注公众号
转载请注明出处
以上所述就是小编给大家介绍的《[译] 面向 React 和 Nginx 的 Docker 多阶段构建》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 构建面向整合服务网格的开放 API
- 用面向对象编程思想构建用户调查的理论基础
- [译] 面向 React 和 Nginx 的 Docker 多阶段构建
- 中国金茂构建面向地产业务的云管平台,强化IT服务交付与安全性
- 面向Python,面向对象(基础)
- 面向Python,面向对象(基础3)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JAVA核心技术(卷1)
Cay S. Horstmann、Gary Cornell / 杜永萍、邝劲筠、叶乃文 / 机械工业出版社 / 2008-6 / 98.00元
《JAVA核心技术(卷1):基础知识(原书第8版)》是《Java核心技术》的最新版,《Java核心技术》出版以来一直畅销不衰,深受读者青睐,每个新版本都尽可能快地跟上Java开发工具箱发展的步伐,而且每一版都重新改写了的部分内容,以便适应Java的最新特性。本版也不例外,它反遇了Java SE6的新特性。全书共14章,包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理......一起来看看 《JAVA核心技术(卷1)》 这本书的介绍吧!