使用 Docker & DaoCloud 来创建你的自动化持续发布流程
文章目录
Docker 作为近几年非常热门的技术,来看看到底有什么优势值得我们去尝试。
前言
Docker 是近几年非常热门的技术之一,相信你在工作或者学习中总能听到这项技术,现如今 Docker 容器化技术的使用已经在各大厂商已经非常普遍,作为前端,或许你编写的应用是跑到服务器的 Docker 容器当中,然而你并不知道,因为许多公司已经将其“封装”为一个黑盒,完善的 DevOps 工具让你只专注与自己领域的开发,你并不需要知道项目是在哪里构建、在哪里运行,作为一个自我驱动型的工程师,拓展自己的技术广度还是很有必要的,本篇文章将会介绍 Docker 的基本使用方式以及如何创建一个持续发布流程。
Docker 入门
什么是 Docker
Docker 是 Linux 容器的一种封装,提供简单易用的容器使用接口,Docker 将应用程序打包在一个文件(镜像)中,运行这个文件,就会生产一个虚拟的操作系统(容器),程序运行在容器中,就像运行在真实的物理机中,使用 Docker 相比传统的虚拟机有很多优势:
- 启动快: 运行一个容器就相当于运行宿主机底层系统中的一个进程,也就相当于启动宿主机中的进程,而不是要启动一个完整的操作系统,因此速度会非常快。
- 占用资源少:虚拟机由于是完整的操作系统,需要占用大量资源,容器只需要占用“需要”的资源,不占用没有使用到的资源,并且多个容器可以共享宿主机中的资源,因此其占用的资源相比于虚拟机要少很多。
- 体积小:容器只需要打包“用到”的组件,而虚拟机是整个操作系统的打包,所以体积上容器要小很多。
几个关键的部分
作为入门实践,我们只需要关心几个关键的部分便能上手实现我们想要的功能:
镜像(Image)
镜像是一个文件,如果你重装过系统,我们需要下载该系统的镜像,那么 Docker 中的镜像就是用来装“系统”(Container)的文件包,其中包含了虚拟环境运行最原始文件系统的内容。
Dockerfile
上面我们说的镜像是一个文件包,不同的需求我们需要定制不同的镜像,通常我们使用 Dockerfile 来构建镜像,Dockerfile 中包含一些构建镜像的命令,比如有下载某个软件包、复制某些文件、对项目进行打包、更改 nginx 的配置等等,总之我们的目的是构建一份“拿来即用”的“装机”文件包。
容器(Container)
容器可视为一个完整的操作系统,容器由镜像创建而成,可以在容器当中做一切当前操作系统能做的事情,比如运行一个 Node.js 脚本、运行一个 nginx 服务器为客户端提供服务。
宿主机(Host)
宿主机是你购买的云服务器或者你本地 pc,这是 Docker 运行的宿主,宿主机中包含许多镜像与容器,容器之间是完全隔离开来的。
用一张图来表示其几个关键部分的关系:

简单实战
这个章节讲解一个最简单的 Docker 实践,我们将构建一个 Nginx 服务器,并且用来处理一个 index.html 静态 html 文件,访问对应的 ip 与 端口,便能访问到这个静态 html 页面。
安装 Docker
假如在本地 PC 端安装,直接点下面链接,便能下载最新稳定版本的安装包:
MacOS : https://download.docker.com/mac/stable/Docker.dmg
Windows: https://download.docker.com/win/stable/Dock…
如果是在 Linux 系列系统上安装,这篇教程中提供了详细的说明:史上最全(全平台)docker安装方法!
创建 Dockerfile 及 其他文件
- 首先我们创建一个文件夹:
docker-test
1 | mkdir docker-test |
- 然后其目录下创建两个文件:
Dockerfile、index.html
1 | touch Dockerfile index.html |
- 编写
index.html
1 | <!DOCTYPE html> |
这是作为访问静态页面的 html 文件。
- 编写
Dockerfile
1 | FROM nginx |
第一步: FROM nginx 表示该镜像是基于官方的 nginx 来构建的,这里就相当于下载了一个包含 nginx 服务且“拿来即用”的镜像。
第二步: COPY xxx xxx 表示将当前项目中的 index.html 复制到 nginx 默认的初始页位置。
第三步:EXPOSE 80 表示将容器 80 端口暴露出来, 允许外部连接这个端口。
这里我们完成了一个镜像需要的文件包,下一步,我们将基于该文件包,构建一个可以真正运行的镜像。
构建镜像
有了 Dockerfile 文件以后,我们就能使用 Docker 的命令: docker image build 来构建镜像了。
1 | docker image build -t docker-test:v1 . |
上面命令中,-t 参数用来制定镜像的名称,冒号后面是镜像的标签,如果不指定,默认的标签就是 latest,最后我们一定要注意,这句命令中,最后还有一个.,这里表示的是当前路径,也就是 Dockerfile 所在的路径。
运行该命令后,我们将会得到一下输出:
1 | Step 1/3 : FROM nginx |
我们可以看到,输出信息的每个 Step 都对应着 Dockerfile 中的每个指令,这也方便我们查看构建信息与 debug,构建完成后,我们在命令航中输入:
1 | docker image ls |
我们会看到刚刚构建的镜像已经在列表当中:
1 | REPOSITORY TAG IMAGE ID CREATED SIZE |
到这里已经表示我们完成了整个镜像的构建,下一步我们将会运行该镜像,启动一个容器。
运行容器
现在到了整个链路中最后一步, 创建并运行容器。
在命令行中输入 docker container create 命令来创建一个容器:
1 | docker container create -p 3303:80 docker-test:v1 |
命令中 -p 表示 port ,还记得我们 Dockerfile 中的 EXPOSE 80 指令吗,上面的 80 端口,指的是容器中的 80 端口,而不是宿主机的端口,假设想要访问到容器中的 80 端口,我们需要做一个 宿主机—> 容器 的端口映射,-p 3303:80 表示的是将宿主机的 3303 端口映射到容器的 80端口,这时候我们便能通过宿主机的 3303 端口访问到容器的 80 端口。命令中的 docker-test:v1 指的是用哪个镜像来创建容器,命令执行完毕后,会输出一条容器ID:
接着我们运行 docker container ls -a 来查看所有(-a)的容器:
1 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
我们看到,该容器的 STATUS 是 Created 状态,还未处于运行状态,我们输入 docker container start CONTAINER ID 来运行容器:
1 | docker container start 95696808d7e4 |
这个时候,访问:http://localhost:3303/ ,便能访问到 index.html 静态文件了,这个时候我们再运行 docker container ls -a:
1 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
可以看到,STATUS 已经转变为 Up,我们设置的端口映射 PORTS 也转变为 0.0.0.0:3303->80/tcp。
到这里,我们已经完成了 Docker 的基本实践,下面,我们将会进阶地实践基于 Docker 的自动发布流程。
持续发布
上面我们已经完成了 Docker 的基本实践,这一章中我会带着读者利用第三方平台 DaoCloud 创建一个持续发布流程。
场景分析
假设我们需要将一个前端项目部署在云服务器中,并且使用了 Docker 容器化技术,当应用需要更新时,我们需要进行以下步骤:
- 将代码 push 到 Github / Gitlab 中。
- 登录云服务器
- git clone 最新的代码
- 执行打包(这一步也能在本地开发环境完成)
- 构建 Docker 镜像
- 创建并运行容器
频繁发布项目的话,这些操作复杂且耗时不说,而且容易误操作,这个时候我们就需要一个自动化的发布流程,当我们只需要将测试无误后的代码,push 到特定的分支,服务器变能自动地运行上述的 2.3.4.5.6 步骤,我们称之为 持续发布 流程(workflow)。
DaoCloud
作为简单的个人应用,我们不必自己的研发一套这样的持续发布系统,目前已经有比较成熟且操作简单的免费第三方 DevOps 工具供我们个人项目使用(公司一般不会轻易使用第三方的 Devops 工具,主要原因还是担忧代码泄露),作为个人项目,我们使用 DaoCloud 作为个人 DevOps 平台。
创建新的项目
首先我们在 Github 创建一个仓库 docker-publish-demo,git clone 到本地后,使用 vue 或者 react CLI 工具创建一个新的项目:
1 | create-react-app docker-publish-demo |
并且在项目中,创建一个 Dockerfile 文件:
1 | FROM node:8.16-slim |
第一步:基于 node 镜像来进行后续的构建步骤,因为 React 项目需要 node 环境来进行打包
第二步:我们下载了 nginx 以便我们创建静态文件服务
第三步:WORKDIR /app 中,我们创建了一个工作目录
第四步: COPY package.json /app/package.json 将项目中的 package.json 拷贝到 /app 中
第五步:RUN npm i 安装依赖
第六步:COPY . /app 将其所有文件(包含node_modules)拷贝到 /app中
第七步:进行打包,并且将打包好的静态文件移到 nginx 配置文件中
第八步:暴露 80 端口
第九步:将 nginx 在前台运行,避免容器启动后就退出
最后,我们根据上面章节的步骤在本地试一试 Dockerfile 是否能成功构建镜像且能运行容器。
1 | docker image build -t docker-publish:v1 . |
假设一切都没问题后,我们将代码 push 到远程仓库中,接着就开始创建我们的自动化持续发布流程。
1 | git add . |
在 DaoCloud 上创建自动构建发布流程
创建 DaoCloud 账号后,我们进入 DaoCloud 控制台
- 进入控制台,点击创建项目

- 新用户需要绑定 Github 的账号,获取到需要绑定的 repo,绑定 Github 后,选择需要构建的 repo

- 进入项目,点击流程定义

- 删除测试阶段以及发布阶段

- 编辑任务


这里我们设置当代码 push 到 master 分支后,开始执行构建,这一步将会在远程仓库中设置一个 webhooks,当 repo 满足上述条件后,将会触发该 webhooks:

由于是第一次构建,我们点击手动触发,这时候 DaoCloud 会拉取 Github 中的源码,在 DaoCould 的 runner (执行环境)中构建镜像。
- 创建应用

选择左边应用 Tab 栏,点击创建应用,选择之前构建的镜像。

填写应用信息,选择运行环境,这里我选择自己的云服务器(因为要对外服务)。
- 设置容器信息后,点击立即部署。

- 设置自动发布

- 更改项目源码,push 到远程仓库,触发 DaoCloud 进行构建镜像。
这里我们勾选自动发布,当有新的镜像构建完成后,创建新的容器并且替换上一版容器,这样便能完成自动构建及发布流程,最后,我们用一张图来总结上述整个流程:

总结
本篇博客,我们学习了 Docker 的基本使用方法,实践了如何构建镜像、创建及运行容器,基于这些知识,我们利用第三方 Devops 工具 DaoCloud 创建了个人项目的自动构建发布流程,使得我们只需要专注功能的实现,将这些粗活杂活交给自动化流程,节省了我们大量的时间,整个开发流程也更为现代化。
refs: