全文采用的是阿里云的ESC服务器,系统是CentOS 7html
示例项目是NodeJS编写,本文主要是Docker的使用,在文章前2/3都是Docker命令介绍,最后咱们会完成一个自动化的示例。node
GitHub帐号linux
发布项目到GitHubgit
Travis-CI帐号github
监听GitHub上项目改变,将其打包发布到DockerHubdocker
DockerHub帐号shell
Travis-CI将项目发布到DokcerHub时须要登录DockerHub帐号npm
以上帐号自行注册json
关于如何让Travis-CI监听到GitHub上项目的改变,请参考这篇文章ubuntu
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
的两个核心知识点
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 仓库。
国内链接 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 文件了。
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
命令,就会发现被删除的容器文件已经消失了。
学会使用 image 文件之后,接下来的问题就是,如何能够生成 image 文件?若是你要推广本身的软件,势必要本身制做 image 文件,这就须要用到 Dockerfile 文件。它是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件。
下面经过一个实例,介绍什么是 Dockerfile 文件。
下面我以 这个项目 为例,介绍什么是 Dockerfile 文件,实现让用户在 Docker 容器里面运行 Koa 框架。
在你的服务器上克隆该项目(若是没有Git环境记得安装)
$ git clone https://github.com/mufengsm/travis-ci $ cd travis-ci
.git node_modules npm-debug.log
上面代码表示,这三个路径要排除,不要打包进入 image 文件。若是你没有路径要排除,这个文件能够不要
# 该 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]
容器启动之后,须要手动输入命令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
首先,去 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,拉去新的镜像,再运行。
参考文章