安裝
首先在Docker的官方網(wǎng)站下下載相應(yīng)的版本研铆,由于默認(rèn)宿主機(jī)均為Mac褂乍,所以直接下載Mac版本环壤,其中Docker-Compose(Docker官方的Orchestration項目之一思币,主要負(fù)責(zé)快速在集群中部署應(yīng)用)已經(jīng)默認(rèn)安裝在Mac版本的Docker中一死,所以無需再額外下載肛度。
基本使用(Dockerfile)
docker build
假設(shè)基本已經(jīng)知道了Docker的基本知識,直接進(jìn)入主體投慈。
首先承耿,單個鏡像是基于Dockerfile來生成的,Dockerfile可以認(rèn)為是描述這個鏡像的腳本伪煤,在其上下文環(huán)境中加袋,使用docker build就可以運(yùn)行Dockerfile生成鏡像。比如在文件test中抱既,Dockerfile也是在這個文件中职烧,運(yùn)行build
docker build .
其中 (.) 代表著就是dockerfile所在的上下文環(huán)境。 (.) 不可缺少。 可以將上下文理解為傳入docker build中的參數(shù)蚀之,不一定是(.) 蝗敢。也可以是路徑,甚至是URL足删∈偾矗基本語法如下
#選項可以在官方文檔中查閱到
docker build [選項] <上下文路徑/URL/->
其他build用法如下,還可以直接用Git repository來構(gòu)建
$ docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14 docker build https://github.com/twang2218/gitlab-ce-zh.git\#:8.14 Sending build context to Docker daemon 2.048 kB
Step 1 : FROM gitlab/gitlab-ce:8.14.0-ce.0
8.14.0-ce.0: Pulling from gitlab/gitlab-ce
aed15891ba52: Already exists
773ae8583d14: Already exists
...
這行命令指定了構(gòu)建所需的 Git repo
壹堰,并且指定默認(rèn)的 master
分支拭卿,構(gòu)建目錄為 /8.14/
, 然后 Docker
就會自己去 git clone
這個項目贱纠、切換到指定分支峻厚、并進(jìn)入到指定目錄后開始構(gòu)建。
具體Dockerfile中命令如下
# 這行代表著我們制作的鏡像是基于官方的nodejs最新版本的谆焊,由FROM開頭惠桃,冒號之后代表的是版本號,如果不填寫辖试,會默認(rèn)為最新版(latest)
FROM node:latest
# 這行定義的是維護(hù)人和維護(hù)人郵箱辜王,由MAINTAINER開頭
MAINTAINER lossp “richard.xxmxx@gmail.com”
# 第一行是定義運(yùn)行創(chuàng)造/home/Service命令
#第二行是定義工作目錄為/home/Servive
RUN mkdir -p /home/Service
WORKDIR /home/Service
#第一行是從上下文環(huán)境中的/home/Service 復(fù)制文件,copy命令的源路徑都是相對路徑
#第二行是執(zhí)行npm install 命令
COPY . /home/Service
RUN npm install
# 將端口3000暴露出來罐孝,可以供外界訪問呐馆,或者映射到宿主機(jī)的端口上去
EXPOSE 3000
CMD [ "npm", "start" ]
FROM
FROM - 其中FROM命令是必須的,但是不一定需要基于某一個鏡像莲兢,可以從0開始構(gòu)建汹来,此時就需要使用scratch,scratch代表著一個空白的鏡像改艇。此時基本命令就是
FROM scratch
MAINTAINER
MAINTAINER - 就是將維護(hù)人信息添加到腳本文件中收班,不一定需要,可有可無谒兄。
RUN
RUN - RUN命令是用來執(zhí)行基本命令的摔桦,基本格式有兩種,第一種是Shell格式承疲,RUN <命令>邻耕;
RUN npm install
第二種是exec格式,如下
RUN ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"]
第二種更像是函數(shù)中的調(diào)用格式燕鸽。
由于Dockerfile每一個命令都會建立一層兄世,RUN也不例外。
FROM debian:jessie
RUN apt-get update
RUN apt-get install -y gcc libc6-dev make
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" RUN mkdir -p /usr/src/redis
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install
類似上述例子绵咱,一共構(gòu)建了7層鏡像碘饼,這是完全沒有意義的熙兔,而且很多運(yùn)行時不需要的東西,都被裝進(jìn)了鏡像里艾恼,比如編譯環(huán)境住涉、更新的軟件包等等。結(jié)果就是產(chǎn)生非常臃腫钠绍、非常 多層的鏡像舆声,不僅僅增加了構(gòu)建部署的時間,也很容易出錯柳爽。
正確的編寫應(yīng)該如下例子
FROM debian:jessie
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \ && mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps
首先媳握,之前所有的命令只有一個目的,就是編譯磷脯、安裝redis可執(zhí)行文件蛾找。因此沒有必要建立 很多層,這只是一層的事情赵誓。因此打毛,這里沒有使用很多個 RUN
對一一對應(yīng)不同的命令,而是 僅僅使用一個RUN
指令俩功,并使用 &&
將各個所需命令串聯(lián)起來幻枉。將之前的7層,簡化為了1層诡蜓。其中每行命令后的 \ 代表著換行熬甫,使dockerfile的RUN命令更具有可讀性。
此外蔓罚,命令的最后一行還有一個 --auto-remove
命令椿肩,這個為清理工作的命令,刪除了編譯所需要的軟件脚粟,清理下載以及展開的文件覆旱,并且還清理了apt
緩存文件蘸朋。由于鏡像是一層一層構(gòu)建的核无,每一層的多余東西并不會在下一層中被刪除掉,到后面藕坯,鏡像會越來越大团南。因此清理這些沒有用處的東西很有必要。
COPY
COPY - copy命令的源路徑都是相對路徑炼彪,比如
COPY ./package.json /app/
這并不是要復(fù)制執(zhí)行 docker build
命令所在的目錄下的 package.json
吐根,也不是復(fù)制 Dockerfile
所在目錄下的 package.json
,而是復(fù)制 上下文(context) 目錄下的 package.json
辐马。
一般來說拷橘,應(yīng)該會將 Dockerfile
置于一個空目錄下,或者項目根目錄下。如果該目錄下沒 有所需文件冗疮,那么應(yīng)該把所需文件復(fù)制一份過來萄唇。如果目錄下有些東西確實不希望構(gòu)建時傳 給 Docker
引擎,那么可以用.gitignore
一樣的語法寫一個.dockerignore
术幔,該文件是用于 剔除不需要作為上下文傳遞給 Docker
引擎的另萤。
這只是默認(rèn)行為,實際上 Dockerfile
的文件名并不要求必須為 Dockerfile
诅挑,而且并不要求 必須位于上下文目錄中四敞,比如可以用 -f ../Dockerfile.php
參數(shù)指定某個文件作為Dockerfile
CMD
CMD - CMD容器啟動命令。CMD命令和RUN命令相似拔妥,也是兩種格式忿危,分別為shell命令格式和exec命令格式。
Docker 不是虛擬機(jī)没龙,容器就是進(jìn)程癌蚁。既然是進(jìn)程,那么在啟 動容器的時候兜畸,需要指定所運(yùn)行的程序及參數(shù)努释。CMD 指令就是用于指定默認(rèn)的容器主進(jìn)程的 啟動命令的。
在exec命令格式上咬摇,一般會被解析成json數(shù)組格式伐蒂,需要用雙引號,不能使用單引號!!!
Docker-compose
Compose的定位是定義和運(yùn)行多個 Docker 容器的應(yīng)用(Defining and running multi- container Docker applications)肛鹏。
由于Dockerfile對于僅僅是單個鏡像而言逸邦,而在正常的開發(fā)環(huán)境中,我們需要多個容器協(xié)調(diào)合作來完成某一個工作在扰,比如一個web項目缕减,除了web本身以外,還需要均衡負(fù)載芒珠,數(shù)據(jù)庫等桥狡。
compose恰好能滿足這樣的要求,compose允許用戶通過一個docker-compose.yml模版文件來定義互相關(guān)聯(lián)的容器皱卓,來組成為一個項目裹芝。
compose中有如下兩個重要的概念
---服務(wù)(Service): 一個應(yīng)用的容器,實際上可以包括若干運(yùn)行相同鏡像的容器實例
---項目(project): 由一組關(guān)聯(lián)的應(yīng)用容器組成的一個完整業(yè)務(wù)單元娜汁,在 docker- compose.yml 文件中定義嫂易。
compose默認(rèn)的管理對象是項目,通過子命令對項目中的一組容器的生命周期進(jìn)行便攜管理掐禁。
下面是具體例子說明
Dockerfile
version: "2.0"
services:
ubuntu:
image: ubuntu:16.04
restart: always
ports:
- "1234:1234"
nodejs:
image: mynodeapp
restart: always
ports:
- "3000:3000"
nginx:
image: nginx
restart: always
ports:
- "8080:80"
redis:
image: redis:latest
restart: always
ports:
- "6379:6379"
mysql:
image: mysql:5.7
restart: always
ports:
- "27017:27017"
由于其中mysql與redis沒有進(jìn)行詳細(xì)配置怜械,因此并不能完全工作颅和,只是作為展示用,其中image代表著基本哪些基本鏡像缕允∪谒洌可以將image
替換為build
,build
相關(guān)鏡像灼芭,然后基于這個鏡像有额。每一個容器必須定一個image或者build。
以下為命令上訴例子命令解釋彼绷,更多命令參照官方文檔
---ports: 暴露端口信息巍佑,使用宿主端口:容器端口 (HOST:CONTAINER)
格式,或者僅僅指定容器的端口(宿主將會隨機(jī) 選擇端口)都可以
(當(dāng)使用 HOST:CONTAINER
格式來映射端口時寄悯,如果你使用的容器端口小于 60 并且沒放 到引號里萤衰,可能會得到錯誤結(jié)果,因為 YAML 會自動解析 xx:yy 這種數(shù)字格式為 60 進(jìn)制猜旬。 為避免出現(xiàn)這種問題脆栋,建議數(shù)字串都采用引號包括起來的字符串格式)
---volumes: 對于此命令,在上述例子中沒有洒擦,但是對于容器之間共享數(shù)據(jù)是不可獲取的椿争,數(shù)據(jù)卷所掛載路徑設(shè)置∈炷郏可以設(shè)置宿主機(jī)路徑 ( HOST:CONTAINER )
或加上訪問模式 ( HOST:CONTAINER:ro )
秦踪。volumes 關(guān)鍵字相當(dāng)于 docker run
的-v
參數(shù),用于配置數(shù)據(jù)卷掸茅。這里與之前的做法一 樣椅邓,將 app 目錄通過綁定掛載的方式掛載到容器,以便讓我們能夠從主機(jī)修
運(yùn)行docker-compose
項目的時候使用如下命令
docker-compose up
Docker-compose的大致工作流程如下
---up: 啟動所有在 Compose 文件中定義的容器昧狮,并且把它們的日志信息匯集一起景馁。通常會使 用 -d 參數(shù)使 Compose 在后臺運(yùn)行
---build: 重新建造由 Dockerfile 構(gòu)建的鏡像。除非鏡像不存在逗鸣,否則 up 命令不會執(zhí)行構(gòu)建的動作合住,因此需要更新鏡像時便使用這個命令
---ps: 獲取由 Compose 管理的容器的狀態(tài)信息
---run: 啟動一個容器,并運(yùn)行一個一次性的命令慕购。被連接的容器會同時啟動聊疲,除非用了 --no- deps 參數(shù)
---logs: 匯集由 Compose 管理的容器的日志茬底,并以彩色輸出
---stop: 停止容器沪悲,但不會刪除它們
結(jié)語
首先如果要定制自己的鏡像,首先流程想清楚--->Dockerfile腳本編寫--->在iterm中運(yùn)行docker build -t <name> .
--->運(yùn)行docker run -d -p 3000:3000 <name>
---->打開瀏覽器輸入localhost:3000即可
上述僅僅是示例流程阱表,對于單個image而言殿如。
如果是采用docker-compose方式
相關(guān)本地鏡像的構(gòu)建贡珊,采用單個dockerfile然后build方式---->相關(guān)需求梳理,比如redis涉馁,mysql等---->編寫docker-compose腳本门岔,確定各個容器依賴關(guān)系---->docker-compose up運(yùn)行----->瀏覽器打開相應(yīng)端口