blog icon indicating copy to clipboard operation
blog copied to clipboard

开发基于Docker封装的一个快速部署工具

Open axetroy opened this issue 5 years ago • 0 comments

在工作中,部署前端应用,基本上大家都认同通过 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 [email protected] -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

完了,就这么得简单.

我们来分析下,它到底做了什么?

  1. dockposer build

Docker build 类似, 根据 Dockerfile 构建本地镜像

  1. dockposer push

Docker push 类似, 把本地镜像推送到托管服务器

  1. dockposer deploy

把本地镜像,部署到指定的服务器。

这时候我们需要一个配置文件,不然工具怎么知道部署到哪里

配置文件默认为 dockercomposer.host.json, 格式如下

{
  "name": "测试服",
  "path": "/www",
  "host": "192.168.0.1",
  "port": 22,
  "username": "root",
  "password": "root"
}

那么它是怎么工作的呢? 总共就一下几个步骤:

  1. dockposer.host.json中读取服务器配置
  2. 使用 ssh 协议连接到远程服务器
  3. 在远程服务器中运行命令 docker pull <镜像名>:<版本号>
  4. cd 到 host.path 并打开 docker-compose.yaml,将 <镜像名>:<旧版本号>更新为 <镜像名>:<新版本号>
  5. 在远程服务器中运行命令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!

axetroy avatar Mar 02 '19 06:03 axetroy