全文采用的是阿里云的ESC服务器,系统是CentOS 7

示例项目是NodeJS编写,本文主要是Docker的使用,在文章前2/3都是Docker命令介绍,最后我们会完成一个自动化的示例。

准备

注册账号

  1. GitHub账号

    发布项目到GitHub

  2. Travis-CI账号

    监听GitHub上项目改变,将其打包发布到DockerHub

  3. DockerHub账号

    Travis-CI将项目发布到DokcerHub时需要登陆DockerHub账号

以上账号自行注册

关于如何让Travis-CI监听到GitHub上项目的改变,请参考这篇文章

安装环境

  1. Git环境

  2. 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.comcloud.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打造自动化流水线的更多相关文章

  1. .NET Core+Selenium+Github+Travis CI => SiteHistory

    前言 总是三分钟热度的我折腾了一个可以每天自动截取指定网站页面并保存到Github的项目SiteHistory,感觉挺好(每次都这样). 想知道YouTube今天的首页长啥样么?点此查看 想知道You ...

  2. [学习笔记]使用Docker+Jenkin自动化流水线发布.Net应用

    ​使用Docker容器方案可以快速安全地将项目部署到客户的服务器上,作为公司项目,需要解决两个问题: 1. 需要搭建一个私有的Docker仓库,以便安全的存储镜像 2. 需要一套自动化发布方案,实现代 ...

  3. github Travis CI 持续集成

    一个项目如何保证代码质量是开发中非常重要的环节,对于开源项目来说更是如此,因为开源项目要面对的是来自不同水平开发者提交的代码.所以围绕开源做持续集成(Continuous Integration)变得 ...

  4. 【Hexo】使用Hexo+github pages+travis ci 实现自动化部署

    目录 一.说明 二.成品展示 三.前期准备 本地安装 node.js 本地安装 git github 账号 创建仓库 travis ci 账号 四.安装 Hexo 五.使用 hexo 搭建博客 六.部 ...

  5. 博客 | 基于Travis CI实现Hexo在Github和Coding的同步自动化部署

    文章目录 完成Hexo主题安装和配置 基于Travis CI实现同步部署 参考内容 相关链接 待补充 完成Hexo主题安装和配置 如果您还没有安装Hexo环境,请参考Hexo文档安装,也给出这样两篇博 ...

  6. Jenkins与Docker的自动化CI/CD实战

    Jenkins与Docker的自动化CI/CD实战 互联网Java架构 2018-09-19 15:46:13 一.发布流程设计 工作流程: 开发人员提交代码到Git版本仓库:Jenkins人工/定时 ...

  7. github pages与travis ci运作原理

    当说到自动部署的时候,我很反感那些一上来就balabala说怎么操作的博文文章,照着别人的做法有样学样,经常会因为与自己项目实际情况不符而出现各种问题. 比如说github和travis,首先应该搞明 ...

  8. 基于Travis CI实现 Gitbook在 Github 和 Coding 的同步部署

    前言 最近发现自己的博客在使用vpn的情况下打开很慢,百度站点也抓取失败,于是将自己的博客借助hexo-deploy 插件很容易同步部署到了coding上.只需要在你的hexo配置文件_config. ...

  9. 利用Travis CI 让你的github项目持续构建

    Travis CI 是目前新兴的开源持续集成构建项目,它与jenkins,GO的很明显的特别在于采用yaml格式,简洁清新独树一帜.目前大多数的github项目都已经移入到Travis CI的构建队列 ...

随机推荐

  1. Java 中的foreach(增强for循环)

    foreach概述 增强for循环:底层使用的是送代器,使用for循环的格式,简化了送代器的书写,foreach是JDK1.5之后出现的新特性 使用增强for循环 遍历集合 /** * 遍历集合 * ...

  2. 一个动态扩展表格控件列和行的 jQuery 插件

    一个动态扩展表格控件列和行的 jQuery 插件 不过这并不影响使用鸭! 看这里:https://github.com/zhuwansu/table-ext.js 一个简单的示范 html <t ...

  3. 关于在读取excel的文件时候,放在服务器上就报路径错误

    就是指定这个路径:C:\Program Files (x86)\IIS Express 因为在上传到服务器的时候,服务器读取的是在服务器上的路径,所以正确的思路应该是 把上传的Excel存在服务器上, ...

  4. 6、python基本数据类型之序列类型

    前言:python的基本数据类型可以分为三类:数值类型.序列类型.散列类型,本文主要介绍序列类型及其通用操作. 一.序列类型 1)字符串(str):用单引号('),双引号("),三引号(三单 ...

  5. golang中基本类型存储大小和转换

    Go语言的基本类型有: bool string int.int8.int16.int32.int64 uint.uint8.uint16.uint32.uint64.uintptr byte // u ...

  6. Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析

    前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘. 本篇我们将介绍redis的最后一种数据类型: zset 的相关实现. ...

  7. mysql--->innodb引擎什么时候表锁什么时候行锁?

    mysql innodb引擎什么时候表锁什么时候行锁? InnoDB基于索引的行锁 InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁 ...

  8. Intellij IDEA使用(一)项目模板类型

    概述 IDEA默认打开后,会出现欢迎页面,可以选择打开Project的方式. 对于新建的Project,一般会选择[Create New Project],对于界面中,众多的Project类型,有时候 ...

  9. (笔记)常用Llinu命令(一)

    Linux资源 鸟哥Linux:http://linux.vbird.org/linux_basic/ Linux命令大全:https://man.linuxde.net/ 目录切换 cd usr: ...

  10. STM8 关闭PWM输出后的电平输出问题解决

    STM系列的单片机PWM输出如果被关断比如用TIM1_CtrlPWMOutputs进行停止输出后,电平的高低处于不确定的状态. 他取决于: 1.GPIO初始化的特性 2.关断那一刻时的电平 3.CCM ...