基于 Docker 打造前端持续集成开发环境

写在前面:

这不是一篇有新意的文章,因为这篇文章半年前我就发布在其他平台上过,为什么在知乎上旧文新发?

除了想要把发布在其他地方的文章统一放到知乎上之外,还源于我最近在面试一些前端工程师时的一些疑惑,发现很多应聘高级前端岗的开发者对 JS 各种奇技淫巧了如指掌,但是对项目开发流程的末端技术却大多不清楚,比如曾经面试过一个有多年前端开发经验的工程师,其栈内技术非常扎实,但当我问到他们是如何部署前端应用时,这位同学完全不知道,甚至从未关心过相关技术。这让我非常惊讶。

在我们前端研发结束之后,还会有测试,部署,流量监控等等流程...在我的理解里,前端工程师首先得是工程师,那么合格的工程师应该对工程的整个生命周期,包括对自己写出来的代码最终如何被用户访问,以及如何产生价值的整个过程都有较好的理解。

本文虽然内容非常简单,但是却给了前端开发者们对 CI,CD 探索的一个新思路:使用 Docker

之后我可能会在前端项目开发流程的末端技术上输出一个系列文章,这篇旧文章就当是开篇吧。


本文将以一个标准的 Vue 项目为例,完全抛弃传统的前端项目开发部署方式,基于 Docker 容器技术打造一个精简的前端持续集成的开发环境。

前置知识:

1. CI(持续集成):阮一峰老师的关于 CI 的介绍

2. Docker: Docker 快速入门

目标:

1. 代码无需在本地构建

2. 自动化测试、构建,和发布,只需将代码推上 Github 即可自动完成一次发布流程

3. 标准化交付,且版本易管理,可轻松回退版本

现在开始进入主题

第一步: 初始化 Vue 项目(使用vue官方脚手架 vue-cli)

1. 初始化 vue 项目:vue init webpack vue-docker-demo

2. 在项目根目录下编写 Dockerfile

<img src="https://pic4.zhimg.com/v2-90c500babcd4ee652bb62257a143f39f_b.jpg" data-caption="" data-size="normal" data-rawwidth="1828" data-rawheight="1150" class="origin_image zh-lightbox-thumb" width="1828" data-original="https://pic4.zhimg.com/v2-90c500babcd4ee652bb62257a143f39f_r.jpg"/>

Dockerfile 内容如下(如果是构建其他项目,比如 angular4,只需安装 angular-cli,将构建参数改成 ng build 即可,非常简单易懂)

FROM node:6.10.3-slim
RUN apt-get update \ && apt-get install -y nginx
WORKDIR /app
COPY . /app/
EXPOSE 80
RUN npm install \
&& npm run build \
&& cp -r dist/* /var/www/html \
&& rm -rf /app
CMD ["nginx","-g","daemon off;"]

3. 初始化 git, 连接并将代码推送到 Github 仓库,

<img src="https://pic2.zhimg.com/v2-2e8ce10d0b3158a247622914544ac7c9_b.jpg" data-caption="" data-size="normal" data-rawwidth="2700" data-rawheight="1640" class="origin_image zh-lightbox-thumb" width="2700" data-original="https://pic2.zhimg.com/v2-2e8ce10d0b3158a247622914544ac7c9_r.jpg"/>

第二步:使用 DaoCloud 搭建 Devops 流程

(也可以使用其他公有云服务,差别不大,本文将以简单易操作并且对个人开发者免费的 DaoCloud 为例)

1. 注册一个 DaoCloud 账号

2. 用户中心 -> 代码托管,授权可访问你的 Github 仓库

<img src="https://pic4.zhimg.com/v2-db839ea6e09a87650f797680e7cd5843_b.jpg" data-caption="" data-size="normal" data-rawwidth="2868" data-rawheight="1646" class="origin_image zh-lightbox-thumb" width="2868" data-original="https://pic4.zhimg.com/v2-db839ea6e09a87650f797680e7cd5843_r.jpg"/>

2. 在 Devops 项目中新建一个项目,并选择 Github 中对应刚才新创建的项目

<img src="https://pic3.zhimg.com/v2-2ba58925caccccf1a7a7fbc2d9d07a5e_b.jpg" data-caption="" data-size="normal" data-rawwidth="2880" data-rawheight="1652" class="origin_image zh-lightbox-thumb" width="2880" data-original="https://pic3.zhimg.com/v2-2ba58925caccccf1a7a7fbc2d9d07a5e_r.jpg"/>

3. 先手动构建一个镜像版本,便于下面用这个镜像版本创建一个应用

<img src="https://pic1.zhimg.com/v2-59aaa436eac5dba1ce5c0e6833ca0c04_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1189" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic1.zhimg.com/v2-59aaa436eac5dba1ce5c0e6833ca0c04_r.jpg"/>

<img src="https://pic2.zhimg.com/v2-1bc0b67f4d885f3871b529c6f5e247fd_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1120" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic2.zhimg.com/v2-1bc0b67f4d885f3871b529c6f5e247fd_r.jpg"/>

4. 连接自有主机(没有自有主机的,也可以使用云端测试环境)

tips:可以去购买 vultr 等主机,按照指示流程完成主机接入,大概很简单的三四步操作,注意在完成主机连接后,需要手动在主机上启动 docker(service docker start)

<img src="https://pic2.zhimg.com/v2-a697d07c557a619af70cc0db2a34d211_b.jpg" data-caption="" data-size="normal" data-rawwidth="2868" data-rawheight="1632" class="origin_image zh-lightbox-thumb" width="2868" data-original="https://pic2.zhimg.com/v2-a697d07c557a619af70cc0db2a34d211_r.jpg"/>

<img src="https://pic1.zhimg.com/v2-87e21e0d184ce9fa053e928c6e25461c_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1645" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic1.zhimg.com/v2-87e21e0d184ce9fa053e928c6e25461c_r.jpg"/>

太酷了,我们已经将我们的主机接入了 DaoCloud,接下来就来完成最有意思的一步。

5. 创建一个应用

进入【镜像仓库】选择刚才手动构建出来的镜像,并部署最新版本到自由主机或者云端测试环境

<img src="https://pic3.zhimg.com/v2-b36349b66e0e08a0d6d34e3b1552d3a2_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1212" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic3.zhimg.com/v2-b36349b66e0e08a0d6d34e3b1552d3a2_r.jpg"/>

<img src="https://pic1.zhimg.com/v2-5a8eff0efaffd2b3b27d57376e32e8b8_b.jpg" data-caption="" data-size="normal" data-rawwidth="2879" data-rawheight="1376" class="origin_image zh-lightbox-thumb" width="2879" data-original="https://pic1.zhimg.com/v2-5a8eff0efaffd2b3b27d57376e32e8b8_r.jpg"/>

稍等片刻,便可以点击“立即部署”

<img src="https://pic1.zhimg.com/v2-3a2d4ea538d85614223158a13dd718e0_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1656" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic1.zhimg.com/v2-3a2d4ea538d85614223158a13dd718e0_r.jpg"/>

等待完成镜像拉取,待容器列表中的容器起来后,通过地址查看我们部署的应用

<img src="https://pic2.zhimg.com/v2-f6554599e061417fb8fe76fffdbf6b85_b.jpg" data-caption="" data-size="normal" data-rawwidth="2872" data-rawheight="1646" class="origin_image zh-lightbox-thumb" width="2872" data-original="https://pic2.zhimg.com/v2-f6554599e061417fb8fe76fffdbf6b85_r.jpg"/>

<img src="https://pic4.zhimg.com/v2-3e8ef328d3f0b2468d673bc243ea7baf_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1798" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic4.zhimg.com/v2-3e8ef328d3f0b2468d673bc243ea7baf_r.jpg"/>

太棒了,我们已经可以访问到我们刚才部署的应用了,也表示我们已经将我们的镜像部署到我们的自有主机上去了,此时进入主机查看容器运行情况,可以看到有一个正在运行中的容器,正是我们刚刚部署的,一切都是完美的。

<img src="https://pic2.zhimg.com/v2-cfa9d58e652dc08b925e8e6e226ad865_b.jpg" data-caption="" data-size="normal" data-rawwidth="1860" data-rawheight="600" class="origin_image zh-lightbox-thumb" width="1860" data-original="https://pic2.zhimg.com/v2-cfa9d58e652dc08b925e8e6e226ad865_r.jpg"/>

完成到这里,我们可以说已经完成了 99% 的工作,但是还非常重要的最后 1%,那就是真正的自定义持续集成流程,让一切都自动化起来,现在让我们回到刚才 Devops 项目的【流程定义】中去

6.定义自动构建,自动发布任务

回到 Devops 项目里对自动化流程进行定义

<img src="https://pic2.zhimg.com/v2-7abb752067869801a4bbd28b27c08015_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1646" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic2.zhimg.com/v2-7abb752067869801a4bbd28b27c08015_r.jpg"/>

首先我们来定义一下自动构建任务,我们设定规则是只有在有新 tag 时才执行构建任务,构建时查找根目录下的 Dockerfile,并以此构建镜像

<img src="https://pic4.zhimg.com/v2-b7112e2ce3948ec04fea37b35c60f6fb_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1364" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic4.zhimg.com/v2-b7112e2ce3948ec04fea37b35c60f6fb_r.jpg"/>

<img src="https://pic2.zhimg.com/v2-1c3a7501306c17b59d0ba7df3a15b5a1_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1478" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic2.zhimg.com/v2-1c3a7501306c17b59d0ba7df3a15b5a1_r.jpg"/>

其次,我们再来定义自动发布任务,当构建任务完成时自动触发自动发布任务,并发布到自有主机的应用上去

<img src="https://pic4.zhimg.com/v2-de29135d39af71de8ab09e03f40f0223_b.jpg" data-caption="" data-size="normal" data-rawwidth="2880" data-rawheight="1407" class="origin_image zh-lightbox-thumb" width="2880" data-original="https://pic4.zhimg.com/v2-de29135d39af71de8ab09e03f40f0223_r.jpg"/>

<img src="https://pic3.zhimg.com/v2-7ecf40516f0ccd0e82bc654563dd570a_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1532" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic3.zhimg.com/v2-7ecf40516f0ccd0e82bc654563dd570a_r.jpg"/>

<img src="https://pic3.zhimg.com/v2-707c2a9f0389cbf3eea7ef7383c5cde2_b.jpg" data-caption="" data-size="normal" data-rawwidth="2874" data-rawheight="1318" class="origin_image zh-lightbox-thumb" width="2874" data-original="https://pic3.zhimg.com/v2-707c2a9f0389cbf3eea7ef7383c5cde2_r.jpg"/>

至此,我们已经完成了,所有流程控制工作,去测试一下整个流程是否能走通?

第三步: 测试整个流程

回到我们本地,修改一下文本内容,提交,并推送到远端,并且打下我们的第一个版本tag 1.0.0,并将 tag 推送到远端

<img src="https://pic1.zhimg.com/v2-6ac133192634428d15417154409d7808_b.jpg" data-caption="" data-size="normal" data-rawwidth="2879" data-rawheight="1647" class="origin_image zh-lightbox-thumb" width="2879" data-original="https://pic1.zhimg.com/v2-6ac133192634428d15417154409d7808_r.jpg"/>

可以看到,与此同时,我们打 tag 的操作触发了我们定义的 CI 流程

<img src="https://pic3.zhimg.com/v2-b58abc0edf8517a865fd3746dba90a5a_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="736" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic3.zhimg.com/v2-b58abc0edf8517a865fd3746dba90a5a_r.jpg"/>

稍等片刻,可以看到我们的应用更新了,对应的版本就是我们刚刚推上去的 1.0.0

<img src="https://pic3.zhimg.com/v2-c77f7c4f80d5521e1a16f8b9cd2c344a_b.jpg" data-caption="" data-size="normal" data-rawwidth="2878" data-rawheight="1781" class="origin_image zh-lightbox-thumb" width="2878" data-original="https://pic3.zhimg.com/v2-c77f7c4f80d5521e1a16f8b9cd2c344a_r.jpg"/>

我们还可以对应用的版本进行切换,回退等操作

<img src="https://pic4.zhimg.com/v2-83b67891504ccfacf5fc4c12f19ad083_b.jpg" data-caption="" data-size="normal" data-rawwidth="2877" data-rawheight="1648" class="origin_image zh-lightbox-thumb" width="2877" data-original="https://pic4.zhimg.com/v2-83b67891504ccfacf5fc4c12f19ad083_r.jpg"/>

至此,我们在只编写了一个 Dockerfile 配置文件,没有编写脚本的情况下,成功地搭建了一套前端的持续集成开发环境,之后我们只需要专心编写我们的业务代码就好了,打一个 Tag 便可以轻松地完成自动部署上线。

如有问题,请随时联系我,谢谢。

基于 Docker 打造前端持续集成开发环境的更多相关文章

  1. 基于Linux系统ipython和集成开发环境Pycharm的安装

    1.简介 Python是一门跨平台的开源.免费的.解释型.面向对象.带有动态语义的脚本语言,同时也支持伪编译以进行优化和提高运行速度,还支持使用py2exe工具将Python程序转换为exe可执行程序 ...

  2. RubyMine(基于IntelliJ IDEA的Ruby集成开发环境)快捷键

    常用快捷键: 一级必会Ctrl+Alt+G:弹出GenerateCtrl+Alt+L:格式化代码Alt+F1:切换视图(Project, Structure, etc.).Alt+F2:弹出预览窗口, ...

  3. Python开发入门与实战8-基于Java的集成开发环境

    8. 基于Java的Python的集成开发环境 目前为止我们所有的代码和例子都是通过Notepad文本编辑器来实现的,实际项目开发中这种编码模式效率较低(大虾除外),使用IDE集成开发环境常常大幅度的 ...

  4. 用前端姿势玩docker【四】基于docker快速构建webpack的开发与生产环境

    目录 用前端姿势玩docker[一]Docker通俗理解常用功能汇总与操作埋坑 用前端姿势玩docker[二]dockerfile定制镜像初体验 用前端姿势玩docker[三]基于nvm的前端环境构建 ...

  5. 基于 Jenkins 快速搭建持续集成环境--转

    源地址:http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/ 持续集成是一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础 ...

  6. 构建基于Jenkins + Github的持续集成环境

    搭建持续集成首先要了解什么是持续集成,带着明确的目标去搭建持续集成环境才能让我们少走很多弯路.持续集成(Continuous integration)简称CI,是一种软件开发的实践,可以让团队在持续集 ...

  7. CentOS 7 部署Gitlab+Jenkins持续集成(CI)环境

    持续集成概述及运行流程 : 持续集成概述 :持续集成(Continuous integration)持续集成是指开发者在代码的开发过程中 ,可以频繁的将代码部署集成到主干,并进行自动化测试  开发→代 ...

  8. PHP 集成开发环境比较

    专注了这么些年技术,没有养成记录和积累的习惯.如今乐于开源和分享经验,却停笔踌躇,不知该从何处说起.开通博客也有一段时间了,也没能写出一篇像样的文章,其实这篇文章也是被我拉壮丁似的用来练手的.思前想后 ...

  9. linux集成开发环境

    Linux操作系统的种种集成开发环境 随着Linux的逐渐兴起,已经有为数众多的程序在上面驰骋了,许多开发环境(Development Environment)也应运而生.好的开发环境一定是集成了编辑 ...

  10. Linux操作系统的种种集成开发环境

    Linux操作系统的种种集成开发环境 随着Linux的逐渐兴起,已经有为数众多的程序在上面驰骋了,许多开发环境(Development Environment)也应运而生.好的开发环境一定是集成了编辑 ...

随机推荐

  1. math库常用函数+产生随机数总结

    math库常用函数+产生随机数总结 1.对x开平方 double sqrt(x)://返回值为double类型,输入的x类型随意,只要是数的类型 2.求常数e的x次方 double exp(x);// ...

  2. 从零用VitePress搭建博客教程(5) - 如何自定义页面模板、给页面添加独有的className和使页面标题变成侧边目录?

    接上一节:从零用VitePress搭建博客教程(4) – 如何自定义首页布局和主题样式修改? 上一节其实我们也简单说了自定义页面模板,这一节更加详细一点说明,开始之前我们要知道在vitePress中, ...

  3. umich cv-6-1 循环神经网络基本知识

    这节课中介绍了循环神经网络的第一部分,主要介绍了循环神经网络的基本概念,vanilla循环网络架构,RNN的一些应用,vanilla架构的问题,更先进的rnn架构比如GRU和LSTM 循环神经网络基本 ...

  4. 持续进化,快速转录,Faster-Whisper对视频进行双语字幕转录实践(Python3.10)

    Faster-Whisper是Whisper开源后的第三方进化版本,它对原始的 Whisper 模型结构进行了改进和优化.这包括减少模型的层数.减少参数量.简化模型结构等,从而减少了计算量和内存消耗, ...

  5. Hyper-V中的虚拟机(Centos)安装FTP服务

    linux上是否装上了ftp服务命令: rpm -qa | grep vsftpd ,若没有安装(无显示版本号)则进行下一步 安装ftp服务,命令: yum -y install ftp vsftpd ...

  6. [WPF]标记扩展(Markup Extension)

    XAML是基于XML的语言,其遵循并扩展了XML的语法规则.其中一项扩展就是标记扩展(Markup Extension),比如我们经常使用的绑定Binding和x:Type. 什么是标记扩展 标记扩展 ...

  7. vue中export default function 和 export function 的区别

    export default function 和 export function 的区别 // 第一种 export default function crc32() { // 输出 // ... ...

  8. mysql数据库数据同步几种通用方法?

    MySQL数据库数据同步的几种通用方法包括以下几个方面: 一.基于主从同步 主从同步是 MySQL 数据库最为常见和基本的同步方式,即其中一台 MySQL 服务器作为主服务器(Master),另外一台 ...

  9. C#/.NET/.NET Core优秀项目和框架2023年11月简报

    前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(公众号每周至少推荐两个优秀的项目和框架当然节假日除外),公众号推文有项目和框架的介绍.功能特点以及部分截图等(打不开或 ...

  10. MongoDB 6.0 单实例基于用户角色实现授权登录

    现代数据库系统能够存储和处理大量数据.因此,由任何一个用户单独负责处理与管理数据库相关的所有活动的情况相对较少.通常,不同的数据库用户需要对数据库的某些部分具有不同级别的访问权限:某些用户可能只需要读 ...