使用GitHub+Travis-CI+Docker打造自动化流水线
全文采用的是阿里云的ESC服务器,系统是CentOS 7
示例项目是NodeJS编写,本文主要是Docker的使用,在文章前2/3都是Docker命令介绍,最后我们会完成一个自动化的示例。
准备
注册账号
GitHub账号
发布项目到GitHub
Travis-CI账号
监听GitHub上项目改变,将其打包发布到DockerHub
DockerHub账号
Travis-CI将项目发布到DokcerHub时需要登陆DockerHub账号
以上账号自行注册
关于如何让Travis-CI监听到GitHub上项目的改变,请参考这篇文章
安装环境
Git环境
Docker环境
安装请参考官方文档
安装完成后,运行下面的命令,验证是否安装成功。
$ docker version
# 或者
$ docker info
Docker 需要用户具有 sudo 权限,为了避免每次命令都输入
sudo
,可以把用户加入 Docker 用户组(如果你是root用户的话就不需要了)$ sudo usermod -aG docker $USER
Docker 是服务器----客户端架构。命令行运行
docker
命令的时候,需要本机有 Docker 服务。如果这项服务没有启动,可以用下面的命令启动,这是Linux下启动服务方式。# service 命令的用法
$ sudo service docker start # systemctl 命令的用法
$ sudo systemctl start docker
正文
了解Docker
首先学习下Docker
的两个核心知识点
container
(容器)和image
(镜像)
Docker
的整个生命周期由三部分组成:镜像(image
)+容器(container
)+仓库(repository
)
每台宿主机(电脑),他下载好了Docker
后,可以生成多个镜像,每个镜像,可以创建多个容器。发布到仓库(比如DockerHub)时,以镜像为单位。可以理解成:一个容器就是一个独立的虚拟操作系统,互不影响,而镜像就是这个操作系统的安装包。想要生成一个容器,就用安装包(镜像)生成一次,这就是Docker
的核心概念。
# 列出本机的所有 image 文件。
$ docker image ls
# 删除 image 文件
$ docker image rm [imageName]
image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。
image
国内连接 Docker 的官方仓库很慢,还会断线,需要将默认仓库改成国内的镜像网站
推荐使用官方镜像 registry.docker-cn.com 。下面是 CentOS 系统的默认仓库修改方法,其他系统的修改方法参考官方文档。
打开/etc/default/docker
文件(需要sudo
权限),在文件的底部加上一行,如果没有该文件可以自己创建。
DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
然后,重启 Docker 服务。
$ sudo service docker restart
现在就会自动从镜像仓库下载 image 文件了。
container
image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
# 列出本机正在运行的容器
$ docker container ls
# 列出本机所有容器,包括终止运行的容器
$ docker container ls --all
上面命令的输出结果之中,包括容器的 ID。很多地方都需要提供这个 ID,
使用docker container kill
命令可终止容器运行
$ docker container kill [containID]
终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm
删除。
$ docker container rm [containerID]
运行上面的命令之后,再使用docker container ls --all
命令,就会发现被删除的容器文件已经消失了。
Dockerfile 文件
学会使用 image 文件以后,接下来的问题就是,如何可以生成 image 文件?如果你要推广自己的软件,势必要自己制作 image 文件,这就需要用到 Dockerfile 文件。它是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件。
下面通过一个实例,介绍什么是 Dockerfile 文件。
实例
下面我以 这个项目 为例,介绍什么是 Dockerfile 文件,实现让用户在 Docker 容器里面运行 Koa 框架。
在你的服务器上克隆该项目(如果没有Git环境记得安装)
$ git clone https://github.com/mufengsm/travis-ci
$ cd travis-ci
.dockerignore文件
.git
node_modules
npm-debug.log
上面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不要
Dockerfile文件
# 该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
FROM node:8.4
# 将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
COPY ./ /app
# 指定接下来的工作路径为/app。
WORKDIR /app
# 在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
RUN npm install --registry=https://registry.npm.taobao.org
# 将容器 3000 端口暴露出来, 允许外部连接这个端口。
EXPOSE 3000
# 这一行表示等运行image时在shell中自动输入的命令,不用我们自己再去node文件了。
CMD node hello.js
现在我们服务器上有Dokcer环境,我们通过下面的命令创建image文件
# -t参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。
$ docker image build -t travis-ci ./
# 或者
$ docker image build -t travis-ci:0.0.1 ./
如果运行成功,就可以看到新生成的 image 文件travis-ci
了。
$ docker image ls
生成容器
docker container run
命令会从 image 文件生成容器。
# 3000端口是上面Dockerfile文件中暴露的,8000端口是自定义的可以通过外网访问
# -p参数:容器的 3000 端口映射到本机的 8000 端口
# -it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器
# travis-ci:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)
# /bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell
# /bin/bash也属于CMD命令他会覆盖我们Dockerfile文件中的CMD命令,两者只能选一
$ docker container run -p 8000:3000 -it travis-ci /bin/bash
# 或者
$ docker container run -p 8000:3000 -it travis-ci:0.0.1 /bin/bash
如果一切正常,运行上面的命令以后,就会返回一个命令行提示符。
[你的服务器名称]:/app#
这表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符。执行下面的命令。
node hello.js
这时,Koa 框架已经运行起来了。打开浏览器,访问 [你的域名/ip]:8000,网页显示"hello world"
这个例子中,Node 进程运行在 Docker 容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)。
现在,在容器的命令行,按下 Ctrl + c 停止 Node 进程,然后按下 Ctrl + d (或者输入 exit)退出容器。此外,也可以用docker container kill
终止容器运行。
# 列出所有容器,不加 -a 仅列出正在运行的,像退出了的或者仅仅只是创建了的就不列出来
$ docker ps -a
# 在本机的另一个终端窗口,列出当前运行的容器,查出容器的 ID
$ docker container ls
# 停止指定的容器运行
$ docker container kill [containerID]
容器停止运行之后,并不会消失,用下面的命令删除容器文件。
# 查出容器的 ID
$ docker container ls --all
# 删除指定的容器文件
$ docker container rm [containerID]
CMD 命令
容器启动以后,需要手动输入命令node hello.js
。我们可以把这个命令写在 Dockerfile 里面,这样容器启动以后,这个命令就已经执行了,不用再手动输入了。
FROM node:8.4
COPY ./ /app
WORKDIR /app
# RUN
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
# CMD
CMD node hello.js
上面有RUN命令和CMD命令,RUN
命令与CMD
命令的区别在哪里?简单说,RUN
命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD
命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN
命令,但是只能有一个CMD
命令。
注意,指定了CMD
命令以后,docker container run
命令就不能附加命令了(比如前面的/bin/bash
),否则它会覆盖Dockerfile中的CMD
命令。现在,启动容器可以使用下面的命令。
# 这里多了一个--rm,意思是在容器终止运行后自动删除容器文件。
$ docker container run --rm -p 8000:3000 -it travis-ci:0.0.1
发布image
手动发布
首先,去 hub.docker.com 或 cloud.docker.com 注册一个账户。然后,用下面的命令登录。
$ docker login
接着,为本地的 image 标注用户名和版本。
$ docker image tag [image名称] [你的用户名]/[仓库名]:[标签]
# 例子
$ docker image tag travis-ci:0.0.1 rope/travis-ci:0.0.1
也可以不标注用户名,重新构建一下 image 文件即可。
# 记得进入项目目录后再操作
$ docker image build -t [username]/[repository]:[tag] ./
最后,发布 image 文件。
$ docker image push [username]/[repository]:[tag]
发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。
自动发布
我们使用gitHub+travis+docker
来形成一套完整的自动化流水线
只要我们push新的代码到gitHub上,自动帮我们构建出新的代码发布到DockerHub,然后我们拉取新的镜像即可
首先我们先进入 Travis CI 官网配置,注册绑定自己的gitHub账号,然后在左侧将自己需要git push
后自动构建镜像的仓库加入可参考这篇文章
我们继续使用上面用到的travis-ci项目,为了验证我们下面的操作是成功的可以将项目中的hello.js显示的hello world改成其他内容。
查看 .travis.yml 文件
language: node_js
node_js:
- '12'
services:
- docker
before_install:
- npm install
script:
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
- docker build -t mufengsm/travis-ci:latest .
- docker push mufengsm/travis-ci:latest
注意 :mufengsm/travis-ci
应该换成你的用户名/包名,再push
代码
每次push
代码到GitHub,Travis-CI都会下载,然后根据package.json
文件下载所需包,再登陆DockerHub账户,再打包并发布到DockerHub,这样你下载的镜像就是有最新的代码。
打开travis-ci中所监听GitHub项目的设置页面,然后添加两个环境变量,这个用户名和密码和你的DockerHub账户是对应的:
DOCKER_USERNAME和DOCKER_PASSWORD
特别提示:这里的Docker
容器,想要后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如tcp,ping,node
),就是会自动退出的,通过 docker ps -a
可以看到容器关闭的原因
当配置成功,代码被推送到GitHub
上后,travis-ci
帮我们自动构建发布新镜像
一定要学会使用: docker ps -a
查看容器的状态
至此,发布,自动构建镜像已经完成
拉取新的镜像
正式开始拉取镜像,启动容器
我们刚才发布的镜像名称是:mufengsm/travis-ci
清除镜像和容器
如果在此之前你创建了很多镜像和容器,一个个删除又太麻烦,下面的命令可以帮到你。
# docker中 启动所有的容器命令
docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)
#docker中 关闭所有的容器命令
docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)
#docker中 删除所有的容器命令
docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)
#docker中 删除所有的镜像
docker rmi $(docker images | awk '{print $3}' |tail -n +2)
#tail -n +2 表示从第二行开始读取
然后使用:
$ docker image pull mufengsm/travis-ci:latest
拉取镜像,这时候需要下载,拉取完成后,使用docker images
可以看到mufengsm/travis-ci:latest
镜像已经存在了
我们使用
# --rm参数,在容器终止运行后自动删除容器文件。
$ docker container run --rm -p 8000:3000 -it mufengsm/travis-ci:latest
创建这个镜像的容器,并且绑定在端口号8000
上
浏览器输入 [你的域名/ip]:8000
发现,访问成功。
最后
我们再梳理下整个流程,创建项目,创建Dockerfile文件,创建travis.yml文件,发布到GitHub,Travis-CI监听项目,自动打包发布到DockerHub,拉去新的镜像,再运行。
参考文章
https://segmentfault.com/a/1190000020676601
http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html
使用GitHub+Travis-CI+Docker打造自动化流水线的更多相关文章
- .NET Core+Selenium+Github+Travis CI => SiteHistory
前言 总是三分钟热度的我折腾了一个可以每天自动截取指定网站页面并保存到Github的项目SiteHistory,感觉挺好(每次都这样). 想知道YouTube今天的首页长啥样么?点此查看 想知道You ...
- [学习笔记]使用Docker+Jenkin自动化流水线发布.Net应用
使用Docker容器方案可以快速安全地将项目部署到客户的服务器上,作为公司项目,需要解决两个问题: 1. 需要搭建一个私有的Docker仓库,以便安全的存储镜像 2. 需要一套自动化发布方案,实现代 ...
- github Travis CI 持续集成
一个项目如何保证代码质量是开发中非常重要的环节,对于开源项目来说更是如此,因为开源项目要面对的是来自不同水平开发者提交的代码.所以围绕开源做持续集成(Continuous Integration)变得 ...
- 【Hexo】使用Hexo+github pages+travis ci 实现自动化部署
目录 一.说明 二.成品展示 三.前期准备 本地安装 node.js 本地安装 git github 账号 创建仓库 travis ci 账号 四.安装 Hexo 五.使用 hexo 搭建博客 六.部 ...
- 博客 | 基于Travis CI实现Hexo在Github和Coding的同步自动化部署
文章目录 完成Hexo主题安装和配置 基于Travis CI实现同步部署 参考内容 相关链接 待补充 完成Hexo主题安装和配置 如果您还没有安装Hexo环境,请参考Hexo文档安装,也给出这样两篇博 ...
- Jenkins与Docker的自动化CI/CD实战
Jenkins与Docker的自动化CI/CD实战 互联网Java架构 2018-09-19 15:46:13 一.发布流程设计 工作流程: 开发人员提交代码到Git版本仓库:Jenkins人工/定时 ...
- github pages与travis ci运作原理
当说到自动部署的时候,我很反感那些一上来就balabala说怎么操作的博文文章,照着别人的做法有样学样,经常会因为与自己项目实际情况不符而出现各种问题. 比如说github和travis,首先应该搞明 ...
- 基于Travis CI实现 Gitbook在 Github 和 Coding 的同步部署
前言 最近发现自己的博客在使用vpn的情况下打开很慢,百度站点也抓取失败,于是将自己的博客借助hexo-deploy 插件很容易同步部署到了coding上.只需要在你的hexo配置文件_config. ...
- 利用Travis CI 让你的github项目持续构建
Travis CI 是目前新兴的开源持续集成构建项目,它与jenkins,GO的很明显的特别在于采用yaml格式,简洁清新独树一帜.目前大多数的github项目都已经移入到Travis CI的构建队列 ...
随机推荐
- Java8 通关攻略
点赞+收藏 就学会系列,文章收录在 GitHub JavaEgg ,N线互联网开发必备技能兵器谱 Java8早在2014年3月就发布了,还不得全面了解下 本文是用我拙劣的英文和不要脸的这抄抄那抄抄,熬 ...
- cogs 176. [USACO Feb07] 奶牛聚会 dijkstra
176. [USACO Feb07] 奶牛聚会 ★☆ 输入文件:sparty.in 输出文件:sparty.out 简单对比时间限制:3 s 内存限制:16 MB 译: zqzas N ...
- cogs 619. [金陵中学2007] 传话 Tarjan强连通分量
619. [金陵中学2007] 传话 ★★ 输入文件:messagez.in 输出文件:messagez.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 兴趣小 ...
- Spring学习记录5——数据库事务基础知识
何为数据库事务 “一荣共荣,一损共损”这句话很能体现事务的思想,很多复杂的事务要分步进行,但它们组成了一个整体,要么整体生效,要么整体失效.这种思想反映到数据库上,就是多条SQL语句,要么全部成功,要 ...
- 跨源请求cors和jsonp
0.产生跨域的原因 浏览器的同源策略 什么是浏览器的同源策略? src开发 ajax禁止 解决方法 jsonp 通过src绕过浏览器的同源策略 缺点:只发送GET请求 cors 通过设置相应头 分类 ...
- 用HttpURLConnection来完成HTTP发送报文接收报文!
public String sendMsg(String url, byte[] PostData) { String content = null; URL urls = null; try { u ...
- windows下生成文件目录树
1.命令提示: tree /? 2.显示当前目录下的目录树(不显示文件) tree 3.递归显示目录结构(显示文件,常用于项目说明) tree /F 4.将显示的内容重定向到txt tree > ...
- GP工作室—Alpha版本发布1
目录 GP工作室-Alpha版本发布1 一.简介 1.1作业要求 1.2团队成员 二.软件下载安装说明 五.项目总结 @(Gold Point团队の项目计划) GP工作室-Alpha版本发布1 一.简 ...
- springboot中的那些连接池
hello~各位读者新年好! 回想起前几天在部署springboot项目到正线时,线上环境要求jdk7,可项目是基于jdk8开发的,springboot也是用的springboot2以上的版本,可以说 ...
- WebAPI接口开发实践
背景 在团队两年多陆续负责了几个项目的开发上线已经代码的review,特别是对老项目的重构过程中,发现之前的API设计是没有任何规范和约定的,不同的开发同学有不同的习惯,因此需要一套规范去约定,现在分 ...