- dokcer的基本組成
- 鏡像
相當(dāng)于掛在了root文件系統(tǒng)的Linux旭等。
- 容器
鏡像與容器的關(guān)系,就像是面向?qū)ο笾械念惡蛯?shí)體一樣继谚。鏡像是靜態(tài)定義的鹃唯,容器是鏡像運(yùn)行時的實(shí)體爱榕。容器可以被創(chuàng)建、啟動坡慌、停止黔酥、刪除、暫停等操作洪橘。
容器的實(shí)質(zhì)是進(jìn)程跪者。但是與直接宿主執(zhí)行的進(jìn)程不同,容器進(jìn)程運(yùn)行屬于自己的獨(dú)立的命名空間熄求。
- 倉庫
Dockerfile的使用
Dockerfile是一個文本文件
- 如我們在某個目錄創(chuàng)建一個Dockerfile文件渣玲。
vi Dockerfile - Dockerfile最基本的格式如下:
FROM nginx
RUN echo "<h1>Hello world</h1>" /usr/share/nginx/html/index.html
- 指令說明
- FROM 指定鏡像 基礎(chǔ)鏡像是必須要指定的。作用就是在此鏡像的基礎(chǔ)上進(jìn)行定制抡四。在Dockerfile文件中柜蜈,F(xiàn)ROM是必備的命令仗谆,而且是第一條命令指巡。
- eg
FROM centos
- 此外,除了選擇現(xiàn)有鏡像的基礎(chǔ)上隶垮,Docker還存在一個特殊的鏡像藻雪,名為scratch,這個鏡像是虛擬的概念狸吞,并不實(shí)際存在勉耀,他表示一個空白的鏡像
FROM scratch
...
- RUN 執(zhí)行命令 指煎,它是用來執(zhí)行命令行命令的,由于命令行強(qiáng)大的能力便斥,RUN指令在定制鏡像時是最常用的命令之一至壤。
- RUN命令后跟著的有兩種格式:
- 1、Shell格式:RUN <命令>
RUN echo "hello world"
-2枢纠、 exec格式:RUN ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"]像街,這更像是函數(shù)調(diào)用中的格式。
如果RUN執(zhí)行了多條命令晋渺,則應(yīng)該按照如下方式書寫镰绎,而不是每條命令都使用RUN執(zhí)行一次。因?yàn)閷訑?shù)限制木西。
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
### 構(gòu)建鏡像
- 首先創(chuàng)建一個Dockerfile 文件畴栖,vi Dockerfile,然后加入最簡單的命令:
FROM nginx
RUN echo "hello docker"
保存退出。
- 構(gòu)建鏡像,在Dockerfile文件的當(dāng)前目錄下執(zhí)行
docker build -t nginx:v2 .
- 等待執(zhí)行完畢
`說明:我們指定了鏡像名 -t nginx:v2`
- 最后八千,運(yùn)行該容器
docker run -d -p 8085:80 nginx:v2
- 在瀏覽器中輸入localhost:8085即可看到輸出吗讶。
- 刪除鏡像
docker rmi -f 鏡像名
- docker build構(gòu)建命令的格式為:
docker build [選項(xiàng)] <上下文路徑/URL/>
### 構(gòu)建上下文路徑
- docker build命令最后面有個 . ,表示當(dāng)前路徑叼丑,在當(dāng)前路徑中尋找Dockerfile文件关翎。
> 這就引入了上下文的概念。當(dāng)構(gòu)建的時候鸠信,用戶會指定構(gòu)建鏡像上下文的路徑纵寝,docker build 命令得知這個路徑后,會將路徑下的所有內(nèi)容打包星立,然后上傳給 Docker 引擎爽茴。這樣 Docker 引擎收到這個上下文包后,展開就會獲得構(gòu)建鏡像所需的一切文件绰垂。
- 關(guān)于上下文
> 如果在 Dockerfile 中這么寫:
```COPY ./package.json /app/```
這并不是要復(fù)制執(zhí)行 docker build 命令所在的目錄下的 package.json室奏,也不是復(fù)制 Dockerfile 所在目錄下的 package.json,而是復(fù)制 上下文(context) 目錄下的 package.json劲装。
因此胧沫,COPY 這類指令中的源文件的路徑都是相對路徑。這也是初學(xué)者經(jīng)常會問的為什么 COPY ../package.json /app 或者 COPY /opt/xxxx /app 無法工作的原因占业,因?yàn)檫@些路徑已經(jīng)超出了上下文的范圍绒怨,Docker 引擎無法獲得這些位置的文件。如果真的需要那些文件谦疾,應(yīng)該將它們復(fù)制到上下文目錄中去南蹂。
現(xiàn)在就可以理解剛才的命令 docker build -t nginx:v3 . 中的這個 .,實(shí)際上是在指定上下文的目錄念恍,docker build 命令會將該目錄下的內(nèi)容打包交給 Docker 引擎以幫助構(gòu)建鏡像六剥。
如果觀察 docker build 輸出晚顷,我們其實(shí)已經(jīng)看到了這個發(fā)送上下文的過程:
$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
...
理解構(gòu)建上下文對于鏡像構(gòu)建是很重要的,避免犯一些不應(yīng)該的錯誤疗疟。比如有些初學(xué)者在發(fā)現(xiàn) COPY /opt/xxxx /app 不工作后该默,于是干脆將 Dockerfile 放到了硬盤根目錄去構(gòu)建,結(jié)果發(fā)現(xiàn) docker build 執(zhí)行后策彤,在發(fā)送一個幾十 GB 的東西权均,極為緩慢而且很容易構(gòu)建失敗。那是因?yàn)檫@種做法是在讓 docker build 打包整個硬盤锅锨,這顯然是使用錯誤叽赊。
一般來說,應(yīng)該會將 Dockerfile 置于一個空目錄下必搞,或者項(xiàng)目根目錄下必指。如果該目錄下沒有所需文件,那么應(yīng)該把所需文件復(fù)制一份過來恕洲。如果目錄下有些東西確實(shí)不希望構(gòu)建時傳給 Docker 引擎塔橡,那么可以用 .gitignore 一樣的語法寫一個 .dockerignore,該文件是用于剔除不需要作為上下文傳遞給 Docker 引擎的霜第。
那么為什么會有人誤以為 . 是指定 Dockerfile 所在目錄呢葛家?這是因?yàn)樵谀J(rèn)情況下,如果不額外指定 Dockerfile 的話泌类,會將上下文目錄下的名為 Dockerfile 的文件作為 Dockerfile癞谒。
這只是默認(rèn)行為,實(shí)際上 Dockerfile 的文件名并不要求必須為 Dockerfile刃榨,而且并不要求必須位于上下文目錄中弹砚,比如可以用 -f ../Dockerfile.php 參數(shù)指定某個文件作為 Dockerfile。
當(dāng)然枢希,一般大家習(xí)慣性的會使用默認(rèn)的文件名 Dockerfile桌吃,以及會將其置于鏡像構(gòu)建上下文目錄中。