工程化-前端自动化部署

参考链接:

docker + webhook 从零实现前端自动化部署

前言

什么是 CI / CD

CI_CD

CI(Continuous Integration 持续集成):一种通过自动化测试持续验证代码库状态的方法。最好通过与版本控制集成来实现。

CD(Continuous Delivery / Deployment 持续交付/部署):一种成功通过 CI 后定期部署的方法,来确保交付。

为什么需要自动化部署

使发布软件更快更健壮。

主要做的工作流程:

  1. 自动 lint;
  2. 自动类型检测;
  3. 自动单元测试;
  4. 自动构建到 docker 镜像中;
  5. 自动部署,发布 docker 镜像;

如果就在本地的话,可以除了最后一步自动部署不做。

解决的问题

  • 打包耗时

  • 特殊环境隔离

  • 打包环境的差异,linux 和 windows 的编码格式不同。

    环境的差异,导致编码格式不同,当重新编译时,会重新编译未修改文件,造成打包耗时,上线后需要重新下载新的打包文件(hash值已经改变,会认为是需要下载新的文件不使用缓存,虽然文件内容没有改变)。

自动化流程工具

  1. Jenkins (https://jenkins.io)

  2. Gitlab CI/CD (https://gitlab.com)

  3. Github Actions (https://github.com/features/actions)

  4. Travis CI (https://travis-ci.org)

  5. Drone (https://www.drone.io)

之前公司使用的是 gitea(项目托管) + drone 搭配

简易的 CI 系统

参考链接:http://aosabook.org/en/500L/a-continuous-integration-system.html

CI

自动化部署流程

自动化部署流程

Docker

官网: https://www.docker.com/

文档:https://docs.docker.com/get-started/

参考文章:docker 入门教程 - 阮一峰

Docker 可以灵活的创建/销毁/管理多个“服务器”,这些“服务器”被称为 容器 (container)

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

为什么要用 Docker

  • 环境统一。利用镜像统一开发环境和生产环境,避免因为环境因素导致的问题。
  • 便于回滚。版本控制,如果环境出现了问题,可以回滚到之前版本。
  • 环境隔离。
  • 高效并节省资源。作用类似服务器 / 虚拟机,可以直接在 Docker 中布置特殊环境且不包含操作系统。

用途

  • 提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
  • 提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。
  • 组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。
  • 版本管理。

Docker 安装 & 实践

windows 安装链接:https://docs.docker.com/desktop/windows/install/

操作指南:https://docs.docker.com/get-started/overview/

image 仓库:https://hub.docker.com/

安装好后进行检测是否安装成功:

docker version # 查看版本信息
docker info # 查看docker状态

Docker是服务器-客户端架构。命令运行docker命令时,需要本机有Docker服务。

# service 命令用法
service docker start
# systemctl 命令用法
systemctl start docker

image (镜像) 文件:Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

容器文件:image 生成的容器实例,本身也是一个文件。一旦容器生成,就会同时存在两个文件,image 文件和容器文件。

image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。

docker image ls # 列出本机的所有 image 文件
docker image rm [imageName] # 删除某个 image 文件

docker container ls # 列出本机正在运行的容器
docker container ls --all # 列出本机所有容器
docker container rm [containerID] # 删除容器文件
运行 image

拉取 image 到本地

Docker for Windows docker pull 镜像到哪里去了

docker image pull library/hello-world
# 或 Docker官方的 image 都在library组里,是默认组,可省略
docker image pull hello-world

# 拉取成功后 查看镜像
docker image ls

运行 image 文件,会生成一个正在运行的容器实例。docker container run 命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。每次运行都会新建容器。

docker container run hello-world

# 运行已经运行过的container
docker container start [containerID] # 用来启动已经生成、已经停止运行的容器文件

如果 image 提供的是服务,如 Ubuntu系统 docker container run -it ubuntu bash,则需要手动终止服务 docker

container kill [containId]

docker_run
制作 docker 容器

Dockerfile 文件: 配置 image 的文件。docker 会更具该文件生成二进制的 image 文件。

项目下新建 .dockerignore 文件,配置不需要打包的文件名。

新建 Dockerfile 文件,内容:

FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
WORKDIR /app:指定接下来的工作路径为/app。
RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。

在当前目录下,创建 image 文件:

docker image build -t [dockerName] . # 默认标签是 latest
# 或
docker image build -t [dockerName]:[tag] .

运行成功后查看新生成的 image 文件:

docker image ls

生成容器

docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
  • -p参数:容器的 3000 端口映射到本机的 8000 端口。
  • -it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
  • koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
  • /bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。

Node 进程运行在 Docker 容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)

可以在 run 后加 –rm 配置,在容器终止运行后自动删除容器文件。

可以在 Dockerfile 文件中设置 CMD 命令,但是就不能使用 /bin/bash 了,会覆盖配置的 CMD 命令。

在容器中运行项目

app_run

ctrl + c:停止 Node 进程

ctrl + d / exit:退出容器 或者在另一个终端中使用命令 docker countainer kill [containerID] 进行终止服务。

发布 image

需要在 docker 网站上注册账户

# 登录注册号的账户
docker login

# 为本地的 image 标注用户名和版本(可选)
docker image tag [imageName] [username]/[repository]:[tag]
# 例如:
docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1

# 重新构建一下 image 文件
docker image build -t [username]/[repository]:[tag] .

# 发布 image 文件
docker image push [username]/[repository]:[tag]

Docker 其他命令

# 终止容器运行,相当于向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号
# 和 kill 命令的差别是 可以进行一段收尾操作后再杀死容器,避免操作丢失
docker container stop [containerID]

# 查看 docker 容器的输出 即容器里面 Shell 的标准输出
docker container logs [containerID]

# 进入一个正在运行的 docker 容器 进入容器后可以使用 shell 命令
docker container exec -it [containerID] /bin/bash

# 用于从正在运行的 Docker 容器里面,将文件拷贝到本机
docker container cp [containID]:[/path/to/file] . # 拷贝到当前目录

更多阅读

Docker 微服务教程 - 阮一峰