前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dockerfile 中的 multi-stage 特性,Vue 项目多阶段构建实战

Dockerfile 中的 multi-stage 特性,Vue 项目多阶段构建实战

作者头像
Hopetree
发布2022-09-26 17:57:51
9060
发布2022-09-26 17:57:51
举报
文章被收录于专栏:tendcode

最近在写一个 Vue 项目,并已经实现 Docker 镜像构建和容器化部署,之前也分享过一篇文章关于 Vue 项目的静态资源打包和镜像构建。但是之前在镜像构建之前是需要使用 npm 进行项目打包生产 dist 文件之后才能进行镜像构建,不过最近我在使用 Jenkins pipeline 的时候突然想到了 Dockerfile 的多阶段构建,完全可以使用这个特性直接构建出镜像。

多阶段构建场景

所谓的多阶段构建,就是当有的服务是需要编译环境进行编译或者打包,然后才能将构建产物移到运行环境中的多个阶段的构建形式。

比如这篇文章所提到的 Vue 项目的构建,Vue 的项目无论是简单还是复杂,最终都是会形成一个静态资源文件夹,这个文件夹里面的内容才是需要放到运行环境中使用的。同样的,Java 项目一般也是需要需要进行编译打包,形成各种包然后才会进行构建。

说的简单一点,就是当一个项目从项目代码到构建成 Docker 镜像的过程需要在不同的环境中进行的场景,那就属于多阶段构建。

多阶段构建实战

本篇文章就来分享一下我这个 Vue 项目的多阶段构建实战,其实这不仅仅能代表我这一个项目,而是可以代表所有 Vue 类型的项目的构建思路。

单阶段构建步骤

由于多阶段构建的依据其实也是单阶段构建,只是把多个步骤集中到一个 Dockerfile 里面而已,所以要实现多阶段构建,首先需要明确真个构建需要做的事情,理清步骤才能开始构建。

一个 Vue 项目从项目代码到形成镜像,主要分两个步骤,第一步是将源代码构建出静态资源文件,第二步就是选择基础镜像,将静态资源移动到基础镜像,构建镜像。

由于 Vue 是需要 node 环境才能镜像打包的,所以第一步骤需要一个 node 环境,之前我是在构建镜像的环境中安装了 node 环境的,然后进行打包,执行步骤比较简单:

代码语言:javascript
复制
npm install
npm run build

执行完上面的 npm 命令之后,就会在项目代码中生成 dist(默认目录)静态资源包,然后就可以执行 Dockerfile 镜像镜像构建,下面是我之前的 Dockerfile 文件的内容:

代码语言:javascript
复制
FROM nginx:latest
ARG from_dir=dist
ARG to_dir=/usr/share/nginx/html

COPY ${from_dir} ${to_dir}

其实这个目录也就是一个文件夹的移动操作,非常简单,但是 dist 目录是需要提前镜像打包产生的。

可以看到,上面的两个步骤,使用了不同的环境,打包静态资源的时候是在 node 环境,而最终的运行环境是 nginx 基础镜像中,所以这很符合多阶段构建的场景。

多阶段构建步骤

Dockerfile 中的 multi-stage 特性允许在一个 Dockerfile 引用多个基础镜像,可以对每个引用的镜像进行单独的操作,然后可以将每个镜像中的文件等内容进行传递。

直接来看 Dockerfile 文件:

代码语言:javascript
复制
FROM node:latest AS stage
WORKDIR /opt/build
COPY . .
RUN npm config set registry https://registry.npm.taobao.org/ && \
    npm install && \
    npm audit fix && \
    npm run build

FROM nginx:latest
COPY --from=stage /opt/build/dist /usr/share/nginx/html

可以看到这个 Dockerfile 是有用两个 FROM 命令的,第一个从 node 基础镜像进行构建,执行的步骤就是 npm 的打包,执行完成之后就会在镜像中生成 dist 资源文件夹了,这个时候就开始从 nginx 基础镜像进行构建,需要执行的目录就是从第一个镜像中把生成的目录复制过来即可。

这里就涉及到两个“语法糖”,第一个是 FROM baseimage AS xxx 这个很好理解,就是将这个构建步骤打个标记,用 xxx 来代表,后面可以用这个名词来表示这个阶段,第二个是 COPY --from=xxx 这个 --from 参数表示的就是从某个构建阶段的镜像中复制,而不是从本地,这个也即是多阶段构建的精髓所在,就是镜像之前可以传递文件。

构建结果

查看一下多阶段构建和单阶段构建出的镜像的大小:

代码语言:javascript
复制
[alex@CentOS-2 ~]$ docker images
REPOSITORY                                         TAG                 IMAGE ID            CREATED             SIZE
registry.cn-shenzhen.aliyuncs.com/tendcode/hao     latest              9f7e793c7d5e        3 hours ago         110MB
hao                                                test                f5ceb0cf0f52        29 hours ago        110MB

总结:可以看到,仅仅一个 Dockerfile 就可以完成从项目代码到最终形成镜像的过程,可谓是非常方便,而且非常的直观,可以让人清楚的知道在项目从代码到镜像的过程中到底经历了些什么。

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处 本文链接:https://cloud.tencent.com/developer/article/2123525 许可协议:署名-非商业性使用 4.0 国际许可协议

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年8月18日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多阶段构建场景
  • 多阶段构建实战
    • 单阶段构建步骤
      • 多阶段构建步骤
        • 构建结果
        相关产品与服务
        容器镜像服务
        容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档