1. 程式人生 > 實用技巧 >Dockerfile build run

Dockerfile build run

Dockerfile
From: 定製的映象都是基於 FROM 的映象 RUN: 執行命令,在映象構建的時候會執行。有兩種模式 shell格式
RUN <命令列命令>
# <命令列命令> 等同於,在終端操作的 shell 命令。

exec格式

RUN ["可執行檔案", "引數1", "引數2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等價於 RUN ./test.php dev offline

多一個run都會在docker上新建一層,過多層,使映象過大。可以用 && 組合命令。 這樣就只有一個run 就只有一層。

FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上執行會建立 3 層映象。可簡化為以下格式:
FROM centos
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

COPY:

複製指令,從上下文目錄中複製檔案或者目錄到容器裡指定路徑。
COPY [--chown=<user>:<group>] <源路徑1>...  <目標路徑>
COPY [--chown=<user>:<group>] ["<源路徑1>",...  "<目標路徑>"]

[--chown=<user>:<group>]:可選引數,使用者改變複製到容器內檔案的擁有者和屬組。

<源路徑>:原始檔或者源目錄,這裡可以是萬用字元表示式,其萬用字元規則要滿足 Go 的 filepath.Match 規則。例如:

COPY hom* /mydir/
COPY hom?.txt /mydir/

<目標路徑>:容器內的指定路徑,該路徑不用事先建好,路徑不存在的話,會自動建立。

CMD:

CMD 在docker run 時執行。
RUN 是在 docker build。

作用 在容器啟動時候執行預設的程式,程式結束,容器就結束了。cmd指令指定的程式會被docker run命令列引數中指定執行的程式覆蓋

注意 如果DockerFile中有多個cmd,只有最後一個生效。

shell格式

CMD <shell 命令> 

exec格式 推薦使用

CMD ["<可執行檔案或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 該寫法是為 ENTRYPOINT 指令指定的程式提供預設引數

ENTRYPOINT:

類似於 CMD 指令,在容器啟動時候執行預設的程式,程式結束,容器就結束了。但其不會被 docker run 的命令列引數指定的指令所覆蓋,而且這些命令列引數會被當作引數送給 ENTRYPOINT 指令指定的程式。但是, 如果執行 docker run 時使用了 --entrypoint 選項,此選項的引數可當作要執行的程式覆蓋 ENTRYPOINT 指令指定的程式。

優點:在執行 docker run 的時候可以指定 ENTRYPOINT 執行所需的引數。

注意:如果 Dockerfile 中如果存在多個 ENTRYPOINT 指令,僅最後一個生效。

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

可以搭配 CMD 命令使用:一般是變參才會使用 CMD ,這裡的 CMD 等於是在給 ENTRYPOINT 傳參,以下示例會提到。

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定參
CMD ["/etc/nginx/nginx.conf"] # 變參   run命令中可以修改的

不傳引數
$ docker run nginx:test 容器內會預設執行以下命令,啟動主程序。 nginx
-c /etc/nginx/nginx.conf

傳引數
$ docker run  nginx:test -c /etc/nginx/new.conf

容器內會預設執行以下命令
nginx -c /etc/nginx/new.conf

ENV:

設定環境變數,定義了環境變數,那麼在後續的指令中,就可以使用這個環境變數。

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

以下示例設定 NODE_VERSION = 7.2.0 , 在後續的指令中可以通過 $NODE_VERSION 引用:

ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

ARG:

構建引數,與 ENV 作用一至。不過作用域不一樣。ARG 設定的環境變數僅對 Dockerfile 內有效,也就是說只有 docker build 的過程中有效,構建好的映象內不存在此環境變數。

構建命令 docker build 中可以用 --build-arg <引數名>=<值> 來覆蓋。

ARG <引數名>[=<預設值>]

EXPOSE:

宣告映象埠

  • 幫助映象使用者理解這個映象服務的守護埠,以方便配置對映。
  • 在執行時使用隨機埠對映時,也就是 docker run -P 時,會自動隨機對映 EXPOSE 的埠。
EXPOSE <埠1> [<埠2>...]

WORKDIR:

工作目錄

#test
FROM ubuntu
MAINTAINER hello
RUN mkdir /mydir
RUN echo hello world > /mydir/test.txt
WORKDIR /mydir
CMD ["more" ,"test.txt"]

CMD ["more" ,"test.txt"] 中沒有指定test.txt的目錄,就可以直接輸出,原因是制定了工作目錄為/mydir,相當於cd

可以在 docker run命令中用 -w引數覆蓋掉WORKDIR指令的設定。

USER:

用於指定執行後續命令的使用者和使用者組,這邊只是切換後續命令執行的使用者(使用者和使用者組必須提前已經存在)。

USER <使用者名稱>[:<使用者組>]

一個.net core專案的dockefile檔案

FROM hub.xxxxx.cn/public/dotnet-core:v2.2.2
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

WORKDIR /app
EXPOSE 8000
COPY . /app

WORKDIR /app
ENTRYPOINT [ "dotnet", "/app/xxx.dll" ]   

Docker build
引數說明
--build-arg=[] :設定映象建立時的變數;

--cpu-shares :設定 cpu 使用權重;

--cpu-period :限制 CPU CFS週期;

--cpu-quota :限制 CPU CFS配額;

--cpuset-cpus :指定使用的CPU id;

--cpuset-mems :指定使用的記憶體 id;

--disable-content-trust :忽略校驗,預設開啟;

-f :指定要使用的Dockerfile路徑;

--force-rm :設定映象過程中刪除中間容器;

--isolation :使用容器隔離技術;

--label=[] :設定映象使用的元資料;

-m :設定記憶體最大值;

--memory-swap :設定Swap的最大值為記憶體+swap,"-1"表示不限swap;

--no-cache :建立映象的過程不使用快取;

--pull :嘗試去更新映象的新版本;

--quiet, -q :安靜模式,成功後只輸出鏡像 ID;

--rm :設定映象成功後刪除中間容器;

--shm-size :設定/dev/shm的大小,預設值是64M;

--ulimit :Ulimit配置。

--tag, -t: 映象的名字及標籤,通常 name:tag 或者 name 格式;可以在一次構建中為一個映象設定多個標籤。

--network: 預設 default。在構建期間設定RUN指令的網路模式

1、dockerfile檔案路徑 (常用) 使用當前目錄的 Dockerfile 建立映象,標籤為 XXX/CRMAPI:V1。
docker build -t XXX/CRMAPI:v1 . 

使用URLgithub.com/creack/docker-firefox的 Dockerfile 建立映象。

docker build github.com/creack/docker-firefox

也可以通過 -f Dockerfile 檔案的位置:

$ docker build -f /path/to/a/Dockerfile .
2、上下文路徑
docker build -t nginx:test .

最後的 . 是上下文路徑。

上下文路徑,是指 docker 在構建映象,有時候想要使用到本機的檔案(比如複製),docker build 命令得知這個路徑後,會將路徑下的所有內容打包。

解析:由於 docker 的執行模式是 C/S。我們本機是 C,docker 引擎是 S。實際的構建過程是在 docker 引擎下完成的,所以這個時候無法用到我們本機的檔案。這就需要把我們本機的指定目錄下的檔案一起打包提供給 docker 引擎使用。

如果未說明最後一個引數,那麼預設上下文路徑就是 Dockerfile 所在的位置。

注意:上下文路徑下不要放無用的檔案,因為會一起打包傳送給 docker 引擎,如果檔案過多會造成過程緩慢。

官方文件
Docker run
docker run -d -p 8030:8000 --cpus=2 -m 2G --memory-swap=2G --env ASPNETCORE_ENVIRONMENT=release -v /data/pf/logs/errorLogs:/app/wwwroot/errorLogs -v /data/pf/logs/NSLogs:/app/wwwroot/NSLogs -v /data/pf/logs/subscribenbusLogs:/app/wwwroot/subscribenbusLogs --name="xxxxx" hub.xxxx.con/xxxxx:latest