Dockerfile詳解以及Flask項目Dockerfile示例

1 Dockerfile介紹

Dockfile是一種被Docker程序解釋的腳本柬采,Dockerfile由一條一條的指令組成欢唾,每條指令對應(yīng)Linux下面的一條命令。Docker程序?qū)⑦@些Dockerfile指令翻譯真正的Linux命令警没。Dockerfile有自己書寫格式和支持的命令匈辱,Docker程序解決這些命令間的依賴關(guān)系,類似于Makefile杀迹。Docker程序?qū)⒆x取Dockerfile,根據(jù)指令生成定制的image押搪。相比image這種黑盒子树酪,Dockerfile這種顯而易見的腳本更容易被使用者接受,它明確的表明image是怎么產(chǎn)生的大州。有了Dockerfile续语,當(dāng)我們需要定制自己額外的需求時,只需在Dockerfile上添加或者修改指令厦画,重新生成image即可疮茄,省去了敲命令的麻煩。

2 Dockerfile語法介紹

Dockerfile的注釋以“#”開始根暑,每一行都是一個指令

一般情況下力试,Dockerfile由4部分組成:

  • 基礎(chǔ)鏡像信息(Base Image)
  • 維護(hù)者信息(maintainer)
  • 鏡像操作指令(Commands to update the base image)
  • 容器啟動指令(Commands when creating a new container)

必須說明的是,如果使用Dockerfile來構(gòu)建鏡像排嫌,需要確定

  • Dockerfile的第一條有效信息必須是基礎(chǔ)鏡像信息
  • 維護(hù)者信息緊隨其后
  • 鏡像操作指令則在維護(hù)者信息之后
  • 最后是鏡像啟動指令

2.1 Dockerfile 指令

Dockerfile的指令一般采用的格式,其中INSTRUCTION是Dockerfile的關(guān)鍵字,包括FROM, MAINTAINER, RUN等腺逛,下面進(jìn)行詳細(xì)介紹

INSTRUCTION arguments

2.1.1 FROM

Dockerfile的第一條必須是FROM指令唤冈,用來指定要制作的鏡像繼承自哪個鏡像,格式如下

FROM <image>
FROM <image>:<tag>

例如需要構(gòu)建一個采用mongodb的數(shù)據(jù)庫鏡像颇象,用以下指令

FROM mongo:3.2

2.1.2 MAINTAINER

用來指定維護(hù)者信息伍伤,格式為

MAINTAINER <name>

例如我自己的維護(hù)者信息

MAINTAINER xixy10@foxmail.com

2.1.3 RUN

該指令用于執(zhí)行shell命令,當(dāng)解析Dockerfile時遣钳,遇到RUN指令扰魂,Docker會將該指令翻譯為如下,其中xxxxxx為RUN后面的shell命令

/bin/sh -c "XXXXXX"

格式為

RUN <command>
RUN <"executable","param1","param2"...>

例如需要安裝相關(guān)軟件及創(chuàng)建文件夾

RUN mkdir /Code
RUN pip install -r requirements.txt

2.1.4 EXPOSE

該指令將容器中的端口號暴露出來耍贾,也可以通過"docker run -p" 命令實現(xiàn)和服務(wù)器端口的映射

格式為

EXPOSE <PORT>[<PORT>...]

例如容器中部署了web應(yīng)用阅爽,需要將8080端口和80端口暴露出來

EXPOSE 80 8080

2.1.5 EXPOSE

該指令指定啟動容器時執(zhí)行的命令,每個Dockerfile只能有一條CMD指令荐开,如果指定了多條付翁,只有最后一條會被執(zhí)行。

如果用戶啟動容器時指定了運行的命令晃听,則會覆蓋CMD指定的命令

格式為

CMD ["executable","param1","param2"] #使用exec執(zhí)行百侧,推薦方式
CMD command param1 param2 #在/bin/sh中執(zhí)行砰识,提供給需要交互的應(yīng)用
CMD [“param1”,"param2"] #提供給ENTRYPOINT的默認(rèn)參數(shù)

例如啟動容器時要求啟動服務(wù)器

CMD python app.py

2.1.6 ENTRYPOINT

設(shè)置指令,指定容器啟動時執(zhí)行的命令佣渴,可以多次設(shè)置辫狼,但是只有最后一個有效

格式如下所示

ENTRYPOINT ["executable", "param1", "param2"] (like an exec, the preferred form)
ENTRYPOINT command param1 param2 (as a shell)

該指令的使用分為兩種情況,一種是獨自使用辛润,另一種和CMD指令配合使用膨处。

當(dāng)獨自使用時,如果你還使用了CMD命令且CMD是一個完整的可執(zhí)行的命令砂竖,那么CMD指令和ENTRYPOINT會互相覆蓋只有最后一個CMD或者ENTRYPOINT有效真椿。

# CMD指令將不會被執(zhí)行,只有ENTRYPOINT指令被執(zhí)行  
CMD echo “Hello, World!”  
ENTRYPOINT ls -l

另一種用法和CMD指令配合使用來指定ENTRYPOINT的默認(rèn)參數(shù)乎澄,這時CMD指令不是一個完整的可執(zhí)行命令突硝,僅僅是參數(shù)部分;ENTRYPOINT指令只能使用JSON方式指定執(zhí)行命令置济,而不能指定參數(shù)解恰。

FROM ubuntu  
CMD ["-l"]  
ENTRYPOINT ["/usr/bin/ls"]

2.1.7 VOLUME

創(chuàng)建一個可以從本地主機(jī)或者其他容器掛載的掛載點(目錄),一般用來存放數(shù)據(jù)庫或者需要永久保存的數(shù)據(jù)浙于,該目錄可以被容器本身使用护盈,也可以共享給其他容器使用。我們知道容器使用的是AUFS路媚,這種文件系統(tǒng)不能持久化數(shù)據(jù)黄琼,當(dāng)容器關(guān)閉后,所有的更改都會丟失整慎。當(dāng)容器中的應(yīng)用有持久化數(shù)據(jù)的需求時可以在Dockerfile中使用該指令脏款。

如果和host共享目錄,Dockerfile中必須創(chuàng)建一個掛載點裤园,然后在啟動容器的時候撤师,通過以下指令來進(jìn)行掛載

docker run -v $HOSTPATH:$CONTAINERPATH

格式如下所示

VOLUME ["<mountpoint>"]

例如

FROM base  
VOLUME ["/tmp/data"]

運行通過該Dockerfile生成image的容器,/tmp/data目錄中的數(shù)據(jù)在容器關(guān)閉后拧揽,里面的數(shù)據(jù)還存在剃盾。例如另一個容器也有持久化數(shù)據(jù)的需求,且想使用上面容器共享的/tmp/data目錄淤袜,那么可以運行下面的命令啟動一個容器

docker run -t -i -rm -volumes-from container1 image2 bash

container1為第一個容器的ID痒谴,image2為第二個容器運行image的名字

2.1.8 ENV

該指令指定一個環(huán)境變量,會被后續(xù)RUN指令使用铡羡,并在容器運行時保持积蔚,格式為

ENV <key> <value>

container啟動后,可以通過docker inspect查看這個環(huán)境變量烦周,也可以通過在docker run --env key=value時設(shè)置或修改環(huán)境變量尽爆。

假如你安裝了JAVA程序怎顾,需要設(shè)置JAVA_HOME,那么可以在Dockerfile中這樣寫

ENV JAVA_HOME /path/to/java/dirent

2.1.9 ADD指令

該指令將復(fù)制指定的到容器中的漱贱,其中可以是

  • Dockerfile所在目錄的一個相對路徑
  • 一個URL
  • 可以是一個tar文件(會自動解壓為目錄)

指令為

ADD <src> <dest>

所有拷貝到container中的文件和文件夾權(quán)限為0755槐雾,uid和gid為0;

  • 如果是一個目錄幅狮,那么會將該目錄下的所有文件添加到container中募强,不包括目錄;
  • 如果文件是可識別的壓縮格式彪笼,則docker會幫忙解壓縮(注意壓縮格式)钻注;
  • 如果是文件且中不使用斜杠結(jié)束,則會將視為文件配猫,的內(nèi)容會寫入;
  • 如果是文件且中使用斜杠結(jié)束杏死,則會將文件拷貝到目錄下

2.1.10 WORKDIR

設(shè)置指令泵肄,可以多次切換(相當(dāng)于cd命令),對RUN,CMD,ENTRYPOINT生效

格式為

WORKDIR /path/to/workdir

例如

WORKDIR /p1 WORKDIR p2 RUN vim a.txt

2.2 docker build

root@ubuntu:~# docker build --help

Usage: docker build [OPTIONS] PATH | URL | -

Build a new image from the source code at PATH

  -c, --cpu-shares=0    CPU shares (relative weight)
  --cpuset-cpus=        CPUs in which to allow execution (0-3, 0,1)
  -f, --file=           Name of the Dockerfile (Default is 'PATH/Dockerfile')
  --force-rm=false      Always remove intermediate containers
  --help=false          Print usage
  -m, --memory=         Memory limit
  --memory-swap=        Total memory (memory + swap), '-1' to disable swap
  --no-cache=false      Do not use cache when building the image
  --pull=false          Always attempt to pull a newer version of the image
  -q, --quiet=false     Suppress the verbose output generated by the containers
  --rm=true             Remove intermediate containers after a successful build
  -t, --tag=            Repository name (and optionally a tag) for the image

3 示例

我將以前的一個項目的后端用Docker進(jìn)行發(fā)布淑翼,采用兩個容器腐巢,一個用來跑Service,一個專門用來作為數(shù)據(jù)庫(mongodb)玄括,兩個服務(wù)器之間有交互冯丙,Service容器會對Database容器進(jìn)行增刪改查操作

3.1 Database容器

直接拉取mongo服務(wù)器

docker pull mongo:3.2

等待下載完成后,我們就可以在本地鏡像列表里查到REPOSITORY為mongo,標(biāo)簽為3.2的鏡像遭京。

然后運行容器

docker run -p 27017:27017 -v $PWD/db:/data/db -d mongo:3.2

命令說明:

-p 27017:27017 :將容器的27017 端口映射到主機(jī)的27017 端口

-v $PWD/db:/data/db :將主機(jī)中當(dāng)前目錄下的db掛載到容器的/data/db胃惜,作為mongo數(shù)據(jù)存儲目錄

3.2 Service容器

Service容器需要運行Flask應(yīng)用,Dockerfile如下所示

FROM    python:2.7
MAINTAINER      xixy10 "xixy10@foxmail.com"

RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd xixy
RUN     /bin/echo 'xixy:123456' |chpasswd

RUN mkdir /Code
WORKDIR /Code
ADD . /Code/
RUN pip install -r requirements.txt
WORKDIR ./TOP/util
RUN python question_lib_generator.py
WORKDIR ../
EXPOSE 5000
CMD python test.py

然后build產(chǎn)生鏡像

docker build -t xixy/tpo:1.0 .

運行容器

docker run -it -p 5000:5000 xixy/tpo:1.0

然后即可訪問哪雕,API正常運行船殉,運行過程中Service容器會對Database容器進(jìn)行增刪改查,容器間通信會令寫一篇

1.png

轉(zhuǎn)載自https://www.tianmaying.com/tutorial/dockerfile

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斯嚎,一起剝皮案震驚了整個濱河市利虫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌堡僻,老刑警劉巖糠惫,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钉疫,居然都是意外死亡硼讽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門陌选,熙熙樓的掌柜王于貴愁眉苦臉地迎上來理郑,“玉大人蹄溉,你說我怎么就攤上這事∧” “怎么了柒爵?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赚爵。 經(jīng)常有香客問我棉胀,道長,這世上最難降的妖魔是什么冀膝? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任唁奢,我火速辦了婚禮,結(jié)果婚禮上窝剖,老公的妹妹穿的比我還像新娘麻掸。我一直安慰自己,他們只是感情好赐纱,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布脊奋。 她就那樣靜靜地躺著,像睡著了一般疙描。 火紅的嫁衣襯著肌膚如雪诚隙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天起胰,我揣著相機(jī)與錄音久又,去河邊找鬼。 笑死效五,一個胖子當(dāng)著我的面吹牛地消,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播火俄,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼犯建,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瓜客?” 一聲冷哼從身側(cè)響起适瓦,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谱仪,沒想到半個月后玻熙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡疯攒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年嗦随,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡枚尼,死狀恐怖贴浙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情署恍,我是刑警寧澤崎溃,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站盯质,受9級特大地震影響袁串,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呼巷,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一囱修、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧王悍,春花似錦破镰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至渠脉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓶佳,已是汗流浹背芋膘。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留霸饲,地道東北人为朋。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像厚脉,于是被迫代替她去往敵國和親习寸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容