在工作中,部署前端应用,基本上大家都认同通过 Docker 来部署是最佳实践.
至于为什么,大家可以通过搜索相关的文章.
那么今天就来讲一讲我遇到过哪些痛点以及如何解决的:
部署繁琐
基本上工作流都是这样:
# 本地
docker build xxx
docker push xxx
# 服务器
docker pull xxx
docker run xxx # 或者 docker-compose up
这样的工作流在本地
与远程服务器
之前切换. 浪费了很多时间,影响效率
与前端工作流不太匹配
比较正规的流程,部署是要git tag
的.
而前端还需要更改package.json
的版本号
这样的事npm version xxx
包办了
接下来我们模拟一次补丁修复,发布版本并且部署在服务器
# 升级版本号
$ npm version patch # 假设版本1.0.1
# 构建应用
$ npm run build
# 打包镜像
$ docker build <镜像名>:1.0.1
# 推送镜像到托管服务器
$ docker push <镜像名>:1.0.1
# 连接到远程服务器
$ ssh root@192.168.0.1 -p 2022
# 进入到项目目录
$ cd /www
# 修改`docker-compose.yml`中的版本号
# 更改 <镜像名>:<旧版本号> ---> <镜像名>:1.0.1
$ vi docker-compose.yml
# 拉取新的镜像
$ docker pull <镜像名>:1.0.1
# 开启服务
$ docker-compose down && docker-compose up -d
发现问题了吗,是不是非常繁琐.
作为一枚程序猿,这样的操作是无法忍受的.
就不能打包镜像之后,自动部署到指定的服务器吗?
于是我写了这么一个工具
dockposer
一个基于 docker-compose, 简化部署流程的命令行工具
还是上面那个场景, 我们用 dockposer
来操作一遍
$ npm version patch # 假设版本1.0.1
$ npm run build
$ dockposer build <镜像名>:{NPM_PACKAGE_VERSION}
$ dockposer push <镜像名>:{NPM_PACKAGE_VERSION}
$ dockposer deploy <镜像名>:{NPM_PACKAGE_VERSION}
{NPM_PACKAGE_VERSION} 是一个变量,当运行命令时,自动替换成
package.json
的版本号
这样我们不用显示的指定构建某个版本, 遵循 NPM 版本即可
或者添加到NPM脚本中
{
...
"scripts": {
...
+ "build": "dockposer build your_tag_name:{NPM_PACKAGE_VERSION}",
+ "push": "dockposer push your_tag_name:{NPM_PACKAGE_VERSION}",
+ "deploy": "dockposer deploy your_tag_name:{NPM_PACKAGE_VERSION}"
}
}
npm run build
npm run push
npm run deploy
完了,就这么得简单.
我们来分析下,它到底做了什么?
- dockposer build
与 Docker build
类似, 根据 Dockerfile
构建本地镜像
- dockposer push
与 Docker push
类似, 把本地镜像推送到托管服务器
- dockposer deploy
把本地镜像,部署到指定的服务器。
这时候我们需要一个配置文件,不然工具怎么知道部署到哪里
配置文件默认为 dockercomposer.host.json
, 格式如下
{
"name": "测试服",
"path": "/www",
"host": "192.168.0.1",
"port": 22,
"username": "root",
"password": "root"
}
那么它是怎么工作的呢? 总共就一下几个步骤:
- 从
dockposer.host.json
中读取服务器配置 - 使用 ssh 协议连接到远程服务器
- 在远程服务器中运行命令 docker pull <镜像名>:<版本号>
- cd 到
host.path
并打开docker-compose.yaml
,将<镜像名>:<旧版本号>
更新为<镜像名>:<新版本号>
- 在远程服务器中运行命令
docker-compose down && docker-compose up -d
以重新启动。
这样就做到了不需要切换到服务器环境,也能够部署在服务端
Q & A
Q: 自动化部署工具这么多,你为什么不用,偏要自己造?
A: 我知道的几个自动化部署工具都需要在服务端也安装它们的工具. 而我这个命令行不用
Q: 为什么不支持部署到多个服务器?
A: 云服务商都提供了集群部署. 不要自己瞎折腾. 起初写这个只是为了我方便部署到测试服
Q: 部署不应该集成到 CI 吗? 谁会这样手动部署?
A: 小团队小项目折腾不起. 考虑下人员配置,不是每个人都玩得溜. 在人员少,能力都不是特别强的情况下,加上各种行业标配反而是一种累赘
Q: 我的场景跟你差不多,也用 Docker 部署,没有集群,我能运用到生成环境吗?
A: 目前来讲,依旧不建议,我也只是运用到测试服务, 一个是还没稳定,第二是万一有点什么事,手动部署还可以补救
Q: 还有哪些不尽人意的地方?
主要是部署这一块,现在只是单纯的更改服务端的
docker-compose.yml
文件然后运行. 更复杂的是,项目的一个配置文件要不要也一起更新?比如 nginx+node 的模式, nginx 的配置文件更新不更新? 还要根据不同的环境,更新不同的配置文件. 太复杂,不符合我的初衷
项目地址: https://github.com/axetroy/dockposer
end!
大牛们的评论:朕有话说
还没有人评论哦,赶紧抢沙发!