前端为什么要用 docker?

5,555 阅读8分钟

相信很多前端同学或多或少都听说过 docker,但是却对它有着深深地误解,以为 docker 技术跟我们前端并没什么关系。

其实并不是这样,我们前端也能使用 docker 技术来帮我们提升效率。(毕竟有人说,前端无所不能啊~)

docker是什么?

docker 是一个容器化的平台。它是最近几年流行的一项技术,用于构建和发布应用程序

看到这儿你就明白了,docker 并不是只为后端人员服务的,甚至它都不挑语言,不管你是 nodejs、java 还是 php......它都能为你所用。

构建和发布,前端同学首先联想到的就是那个“老夫一把梭”的方案——前端项目本地压缩后,html 文件存入 redis,其他 css、js、图片等资源直接上传 CDN。

或者是更干脆一点,直接所有前端项目资源压缩后都传到 CDN。然后在网关或者后端服务的服务器上借住 Nginx 将默认端口代理到 html 文件的 CDN 地址。

我承认,如果是无服务的纯前端项目确实用不上 docker 这种高雅的技术。毕竟杀鸡焉用宰牛刀。

但是作为一个有经验的前端,我们或多或少都接触过 nodejs 项目。无论是 express、egg 还是 nuxt、next 项目,我们或许都经历过从最初的直接把 node 项目怼到服务器上运行,到后来逐渐开始使用 pm2 来管理多个 node 服务进程的过程。

构建部署这块我是没少遇过坑,docker 技术的出现我感觉就是专门为了解决这些坑的。

docker跟虚拟机有什么区别?

docker 跟虚拟机有点像,这个我们不得不承认。看下面这张图——

从这个图上我们可以很容易看出,虚拟机和 docker 从某种意义上讲都是隔离的思想,但是他们隔离的东西并不一样。虚拟机是利用内存分配隔离了整个操作系统层面的,而 docker 只是隔离应用程序层面的。

下面这个图是我从网上找的图,更详细的对比了两者的区别:

虚拟机启动过程缓慢,且占用了一套不必要的系统资源所需要的内存。而Docker可以进行秒启动,因为Docker跳过了系统初始化可以直接使用当前系统。

总结一下就是,docker 技术比虚拟机在应用级隔离、弹性伸缩、快速拓展方面更加突出。

docker 技术的优势

Docker 的思想是集装箱思想,具有持续集成、版本控制、可移植性、隔离性和安全性等优势。

docker 的设计思想是将代码及其依赖的运行环境打包成一个包,这个包官方称为镜像(可以理解为某一个集装箱)。然后去服务器上从远程(docker 仓库)拉下这个包,运行这个镜像,就产生来了一个容器这个容器相当于在服务器上场景再现,重新还原出了你代码之前打包时的状态。

如果你本地已经压缩过代码,那么当服务器拉下这个镜像并依据这个镜像运行这个容器后,这个容器里就会包含你之前压缩过的代码及其之前安装的一切环境,如 nodejs、redis、nginx、pm2 等。

这样咱们程序员最怕的上线过程就变成了:将一套你在本地弄好的代码+运行环境,直接搬到了服务器上运行即可。整个过程轻松、直观,比德芙还丝滑。

docker 的流行绝非偶然。因为它具有的持续集成、版本控制、可移植性、隔离性和安全性等优势给传统意义上的构建部署带来了革命性的意义。

前端使用 docker 有哪些好处?

docker 优势众多,我们也可以用它来给我们前端开发赋能。

前端使用 docker 有哪些好处呢?我根据自己使用 docker 的一些经验梳理了一下:

1. 部署高效,且利于项目迁移

node 项目传统的部署步骤(基于Jenkins的那套):

  1. Jenkins构建机上拉取项目代码
  2. npm install、npm run build 及上传静态资源到 CDN
  3. 将构建物传递给目标服务器的指定目录
  4. 去目标服务器的指定目录启动 node 服务完成部署

node 项目使用 docker 容器化后的部署步骤:

  1. 在本地先拉取一个 nodejs 的基础镜像,并以此镜像启动一个容器
  2. 在该容器里 npm install、npm run build 及上传静态资源到 CDN,并将该容器打包上传到远程镜像仓库
  3. 去服务器拉起该镜像,启动 node 服务即可访问到你想要的node 服务和对应的前端资源

特别是对于项目迁移,已经使用 docker 技术的项目,迁移起来根本不费事。因为已经将代码和运行环境带包成了一个整体,迁到哪个服务器上就去哪个服务器拉这个已经制作好的镜像就好了。

2. 标准化了运行环境,部署更加稳定可靠

docker 技术最大的优点就是为各个不同的代码环境(或服务器)磨平了环境差异,为你的代码提供了开发-测试-生产一模一样的运行环境。

这个在 docker 技术出现之前是几乎很难做到的,因为造成造成你代码运行环境不一致的因素太多了,比如操作系统种类、操作系统版本、node 版本、node modules 包的版本(总有些包没有被锁死版本)及一些基础依赖包如 Nginx、pm2、redis 等的版本。

按照我个人以往的经验,经常会遇到同一份代码本地运行没问题,但是到了测试或线上却出现了莫名其妙的问题。有的甚至在构建过程中都会直接出错,而我本地却没有这种情况。

这是我们挠破头都不愿意看到的情况。时间应该浪费在美好的事物上,而不是陷入在给不同环境找差异的苦恼之中。

而 docker 的出现恰好就是为了解决这个问题而生的,它标准化了运行环境,使用镜像包的形式将不同的代码和运行环境固定成了一个整体,就像将所有货物打包成了一个集装箱一样。

它致力于所见即所得,即你在本地所见到的就应该是你上线后应该得到的。这种部署方式稳定且可靠,确实不要太酷!

如果说 Git 等代码管理工具统一了各个环境分支的代码,那么 docker 相当于统一了各个环境代码的运行环境。

3. 更易于持续交付和部署(CI/CD)

现代化软件开发强调持续集成和交付,这就要求我们构建和部署的过程要非常高效。

Docker 部署配合 GitLab CI 的方式让我们的部署流程更加的自动化、简单化和高效。

这完全是 devOps 的思想。CI/CD 创造了一种实时反馈回路机制,持续地传输小型迭代更改,从而加速更改,提高质量。CI 环境通常是完全自动化的,通过 git 推送命令触发自动构建和打包新镜像,然后推送到 Docker 镜像库,最后使用 Python 脚本自动拉取该新镜像,并启动 node 服务。

这整个过程一条龙服务,从你提交代码合到对应测试分支之后,你就再也不用再考虑任何事了。一切都是高效、自动化的,交付速度提高至少好几倍。

4. 运维更加高效,秒级回滚

如果理解了镜像包的概念,秒级回滚这个就不难理解了。你每打一个镜像就相当于一个版本。

如果你上线后突然发现有问题或者发了不该发的代码,这个时候你只需要找到之前稳定的镜像包并在服务器上重新拉取,运行对应的服务就可以了。

看到这儿,前端为什么要使用 docker 这个问题也不用我回答了。甚至你此刻都想摸摸自己日益高涨的发际线,并轻叹一声,哥哥以后上线再也不用加班熬夜了!

没错,根据我的个人经验,对于我们前端 node 服务项目,使用 docker 容器化部署真的是受益良多。自从用上了docker,我就离不开它了!


(docker 相关的操作本文还没有详细说明,想要迫不及待亲自实践 docker 技术的可以根据这个文档来 yeasy.gitbook.io/docker_prac… :)