使用GitHub+Travis-CI+Docker打造自動化流水線

全文采用的是阿里雲的ESC服務器,系統是CentOS 7html

示例項目是NodeJS編寫,本文主要是Docker的使用,在文章前2/3都是Docker命令介紹,最後咱們會完成一個自動化的示例。node

準備

註冊帳號

  1. GitHub帳號linux

    發佈項目到GitHubgit

  2. Travis-CI帳號github

    監聽GitHub上項目改變,將其打包發佈到DockerHubdocker

  3. DockerHub帳號shell

    Travis-CI將項目發佈到DokcerHub時須要登錄DockerHub帳號npm

以上帳號自行註冊json

關於如何讓Travis-CI監聽到GitHub上項目的改變,請參考這篇文章ubuntu

安裝環境

  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

img

特別提示:這裏的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,拉去新的鏡像,再運行。


參考文章

http://www.javashuo.com/article/p-phsmqnvs-kd.html

http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html

相關文章
相關標籤/搜索