全文采用的是阿里雲的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,拉去新的鏡像,再運行。
參考文章