1. 程式人生 > >Docker-DockerFile的使用

Docker-DockerFile的使用

在使用DockerFile定製映象之前,我們先來了解一下映象的構成:映象是容器的基礎,每次執行docker run命令的時候都會指定哪個映象作為容器執行的基礎。在之前的栗子中,我們使用的映象都是來著Docker Hub的映象。直接使用這些映象為基礎執行容器可以一定程度上滿足我們的需求,可是當這些映象都無法直接滿足需求時,我們就需要定製映象!

docker commit構建

現在我們以定製一個Web伺服器為例:

root@ubuntu:~# docker run --name webserver -d -p 80:80 nginx
f0a2ad681b692642be0b825631d8716ae3d8c1fb5ad48148362331df3fae9775

此時,我們在瀏覽器中訪問本機地址,例如以本機為例192.168.0.89,如圖:

image

這條命令會以Nginx為映象建立並啟動一個容器,映射了80埠,這樣我們可以在瀏覽器中訪問這個Nginx伺服器!假設,我們現在不喜歡這個歡迎頁面的樣式,想把它改為“Hello Docker!”,我們可以使用docker exec命令,進入容器,修改器內容:

root@ubuntu:~# docker exec -it webserver bash
root@f0a2ad681b69:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
root@f0a2ad681b69:/# exit

此時,我們再重新整理瀏覽器的話,發現內容已經發生了改變,如圖:

image

改變了容器的檔案,也就是說,改變了容器的儲存層,我們可以使用docker diff來檢視檔案的修改情況:

root@ubuntu:~# docker diff webserver
C /root
A /root/.bash_history
C /run
A /run/nginx.pid
C /usr/share/nginx/html/index.html
C /var/cache/nginx
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var
/cache/nginx/proxy_temp A /var/cache/nginx/scgi_temp A /var/cache/nginx/uwsgi_temp

現在,我們定製好了變化,希望能將其儲存下來形成映象。要知道,我執行一個容器的時候,我們對任何檔案的修改操作都會記錄在容器的儲存層裡。Docker提供了一個docker commit命令,可以將容器的儲存層儲存為映象。docker commit的語法格式為:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

下面,我們將上面那個容器儲存為映象,命令如下:

root@ubuntu:~# docker commit --author "ycx <[email protected]>" --message "修改了Nginx歡迎頁面" webserver nginx:v1.0
sha256:1b6b342acb5e91a5da9a564818e94ec1041f7a152b249075f109b0c259d580f0

--author指定修改的作者,--message為記錄本次修改的內容,webserver為容器名,也可以傳入容器ID,nginx:v1.0為倉庫名和標籤。儲存成功之後,會返回一個摘要!接下來,我們使用docker image ls命令來檢視當前宿主機上所有的映象:

root@ubuntu:~# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1.0                1b6b342acb5e        5 seconds ago       109MB
nginx               latest              5699ececb21c        5 days ago          109MB

我們剛剛儲存的映象已經出現在上面了!!!

我們還可以使用docker history命令來檢視映象內的歷史記錄,接下來,我們檢視以下剛剛儲存的映象內的歷史記錄,如下:

docker history nginx:v1.0
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
1b6b342acb5e        4 minutes ago       nginx -g daemon off;                            97B                 修改了Nginx歡迎頁面
5699ececb21c        5 days ago          /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B                  
<missing>           5 days ago          /bin/sh -c #(nop)  STOPSIGNAL [SIGTERM]         0B                  
<missing>           5 days ago          /bin/sh -c #(nop)  EXPOSE 80/tcp                0B                  
<missing>           5 days ago          /bin/sh -c ln -sf /dev/stdout /var/log/nginx…   22B                 
<missing>           5 days ago          /bin/sh -c set -x  && apt-get update  && apt…   53.7MB              
<missing>           5 days ago          /bin/sh -c #(nop)  ENV NJS_VERSION=1.15.0.0.…   0B                  
<missing>           5 days ago          /bin/sh -c #(nop)  ENV NGINX_VERSION=1.15.0-…   0B                  
<missing>           5 days ago          /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B                  
<missing>           5 days ago          /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           5 days ago          /bin/sh -c #(nop) ADD file:28fbc9fd012eef727…   55.3MB 

如果有興趣的朋友,再用docker history命令來檢視以下nginx:latest映象內的歷史記錄,對比以下會發現,nginx:v1.0多了一層我們剛剛提交的那一層!!!

新的映象定製好了之後,我們再以這個映象為基礎,執行一個容器,如下:

root@ubuntu:~# docker run --name webserver2 -it -d -p 81:80 nginx:v1.0
092f8e20bc6cf6c73c79bd66b9cd0f26cc81ddba153db90107e477c5f558ed91

這裡,我們將新啟動的容器命名為webserver2,並且對映到81埠。此時,我們再次在瀏覽器輸入192.168.0.89:81時,會發現與之前修改後的效果是一樣的,如圖:

image

使用docker commit命令雖然可以幫助理解映象分層儲存的概念,但是實際開發中並不推薦這樣使用!!!它有下面這幾點危害:

  • 首先,如果你仔細觀察docker diff webserver的結果,你會發現除了僅僅被我們修改的/usr/share/nginx/html/index.html檔案,還有很多檔案被改動或添加了。這還僅僅只是最簡單的操作,如果是安裝軟體包、編譯構建,那會有大量無關的內容被新增進來,如果不小心清理,那將會導致映象極為臃腫
  • 使用docker commit命令執行的操作都是黑箱操作,生成的映象也被稱之為黑箱映象!換言之,除了映象的製作人之外,其他使用該映象的人根本無從得知執行過什麼命令,怎麼生成的映象。而且,即使是製作該映象的本人,過了一段時間之後也許也無法記得具體執行什麼操作!這種黑箱映象的維護工作是非常痛苦的!!!
  • 根據映象分層的概念,除當前層外,之前的每一層都是不會被修改的,換句話說,任何的修改結果只會在當前層進行標記、刪除、修改,而不會改動到上一層。而使用docker commit命令製作映象,以及後期的修改,每一次的操作都會讓映象更加臃腫一次。而且所刪除的上一層的東西並不會丟失,會如影隨形的跟著這個映象。

使用DockerFile構建

我們可以把每一層的安裝、修改、構建、操作的命令都寫入一個指令碼,用這個指令碼來構建、定製映象,那麼之前我們提及的無法重複的問題、映象構建透明性的問題、體積的問題都會解決,這個指令碼就是DockerFile!下面,我們將上面的映象構建改成用DockerFile來進行:

  • 使用vi編輯器,開啟一個空白檔案Dockerfile
FROM nginx
RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
  • Dokcerfile檔案同級目錄下,使用docker build命令進行構建:
docker build -t nginx:v1.1 .
  • 此時,我們再使用docker image ls命令來檢視當前宿主機下的映象列表時,剛剛生成的nginx:v1.1已經出現在上面:
root@ubuntu:~/DockerFiles# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1.1                a473544051ce        4 seconds ago       109MB
nginx               latest              5699ececb21c        6 days ago          109MB

這裡我們使用docker build命令來進行構建映象,其命令格式為:

docker build [OPTIONS] PATH | URL | -

在這裡,我們指定了最終映象的名稱nginx:v1.1-t為執行映象的名稱,千萬不要忽略結尾處的.,它表示當前目錄。構建成功後,我們可以像之前一樣在指定基礎映象之後,建立並啟動一個容器。

映象構建上下文

在上面的構建命令中,會看到在docker build命令的結尾處有一個.,表示當前目錄,而Dockerfile就在當前目錄,因此不少初學者以為這個就是指定Dockerfile所在路徑,這麼理解其實是不準確的。如果對應上面的命令格式,你就會發現,這其實是在指定上下文路徑。

Docker在執行時分為Docker引擎和客戶端工具。Docker引擎提供了一組REST API,被稱為Docker Remote API,而Docker命令這樣的客戶端工具,則是通過Docker Remote API來與Docker 引擎進行互動,從而完成各種功能的。雖然,表面上我們是在本機上完成各種Docker功能,但是實際上我們是通過Docker Remote API與Docker引擎互動,在Docker引擎中完成的各種功能。正是因為這種C/S設計,使得我們操作遠端伺服器的Docker引擎變得輕而易舉。

當我們進行映象構建時,並非所有定製都會通過RUN命令完成,經常我們需要將一些本地檔案複製至映象,比如通過COPY指令、ADD指令等。可是映象的構建是在Docker引擎中完成的,我們該如何將本地的檔案上傳到Docker引擎中呢?這就引入上下文概念,當映象構建時會指定上下文路徑,docker build得知這個路徑時,會將該路徑下的所有內容打包,上傳給Docker引擎。這樣Docker引擎接收到這個上下文包之後,展開就會獲得構建映象的一切所需檔案。如果你在Dockerfile中,這樣寫:

COPY ./package.json /app/

這並不是複製docker build執行命令所在路徑下的package.json,也不是Dockerfile所在目錄下的package.json,而是複製上下文路徑下的package.json。因此,COPY這類指令中的原始檔路徑都是相對路徑,這也就是為什麼一些初學者中常遇到的問題:COPY /opt/xxx /app無法工作的原因,因為這已經超出了上下文的範圍,Docker引擎無法獲得這些位置的路徑。如果真的需要這些檔案,應該將其複製到上下文路徑當中。

通常情況下,如果不額外指定Dockerfile的話,會將上下文路徑當中名稱為Dockerfile的檔案作為Dockerfile。正因為這樣,一些小夥伴因為定義的名稱並非是Dockerfile,而導致上面的構建命令執行不通!這只是預設行為,實際上Dockerfile的檔名並不要求必須是Dockerfile,也並不要求必須將Dockerfile檔案置於上下文目錄當中,你可以新增-f引數來指定Dockerfile的檔案,例如:

[email protected]:~/DockerFiles/docker# docker build -f ../DockerNginx -t nginx:v1.2 .
Sending build context to Docker daemon  1.583kB
Step 1/2 : FROM nginx
 ---> 5699ececb21c
Step 2/2 : RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Using cache
 ---> a473544051ce
Successfully built a473544051ce
Successfully tagged nginx:v1.2

此時,我們再來看一下,當前存在的映象列表:

root@ubuntu:~# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1.1                a473544051ce        3 days ago          109MB
nginx               v1.2                a473544051ce        3 days ago          109MB
nginx               latest              5699ececb21c        10 days ago         109MB

可以,看到,剛剛我們構建的映象已經存在在上面了。而我們的Dockerfile檔案,名稱也並不是叫Dockerfile,並且檔案也並不是在上下文路徑當中!!!

docker build其他用法

  • 從遠端倉庫中進行構建

這裡,我從我的GitHub中建立了一個倉庫,並簡單寫了一個Dockerfile,下面我們就就嘗試從遠端倉庫中進行構建:

[email protected]:~# docker build https://github.com/Mr-ycx/docker.git#:test -t nginx:v1.3
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx
 ---> 5699ececb21c
Step 2/2 : RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 25ea95c42a08
Removing intermediate container 25ea95c42a08
 ---> fa8d8e64f43f
Successfully built fa8d8e64f43f
Successfully tagged nginx:v1.3

下面,我們再次使用docker image ls命令來列出,當前宿主機上存在的映象:

root@ubuntu:~# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1.3                fa8d8e64f43f        3 minutes ago       109MB
nginx               v1.1                a473544051ce        3 days ago          109MB
nginx               v1.2                a473544051ce        3 days ago          109MB
nginx               latest              5699ececb21c        10 days ago         109MB
ubuntu              12.04               5b117edd0b76        15 months ago       104MB

docker build指定了構建所需的Git Repository,並且指定預設的master分支,構建目錄為/test/。然後Docker會自己去git clone這個專案,然後切換到指定分支,最後進入指定目錄下進行構建。

  • 用遠端tar壓縮包進行構建

這裡,我自己新建一個了Web專案,將製作好的壓縮包置於編寫好的介面中提供下載。下面我們就嘗試從遠端的壓縮檔案中進行構建:

[email protected]:~# docker build http://192.168.0.89:5000/docker.tar -t nginx:v1.4
Step 1/2 : FROM nginx to Docker daemon  10.24kB://192.168.0.89:5000/docker.tar [==================================================>]  10.24kB/10.24kB
 ---> 5699ececb21c
Step 2/2 : RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Using cache
 ---> fa8d8e64f43f
Successfully built fa8d8e64f43f
Successfully tagged nginx:v1.4

下面,我們再次使用docker image ls命令來列出,當前宿主機上存在的映象:

root@ubuntu:~# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1.3                fa8d8e64f43f        31 minutes ago      109MB
nginx               v1.4                fa8d8e64f43f        31 minutes ago      109MB
nginx               v1.1                a473544051ce        3 days ago          109MB
nginx               v1.2                a473544051ce        3 days ago          109MB
nginx               latest              5699ececb21c        10 days ago         109MB
ubuntu              12.04               5b117edd0b76        15 months ago       104MB

如果給出的URL不是一個Git Repository,而是一個tar壓縮包,那麼Docker會自己去下載這個壓縮包,將其展開並在裡面將其作為上下文,進行構建。

值得注意的是,那麼Docker會自己去下載這個壓縮包並解壓,並以解壓至的目錄為上下文目錄!!!假如你的Dockerfile檔案在某個資料夾下面,或者你的Dockerfile檔名不為Dockerfile,那麼需使用-f命令指定Dockerfile檔案,否則將無法定位到,如下:

[email protected]:~# docker build http://192.168.0.89:5000/docker2.tar -f ./docker2/Dockerfile -t nginx:v1.5
Step 1/2 : FROM nginx to Docker daemon  10.24kB://192.168.0.89:5000/docker2.tar [==================================================>]  10.24kB/10.24kB
 ---> 5699ececb21c
Step 2/2 : RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Using cache
 ---> fa8d8e64f43f
Successfully built fa8d8e64f43f
Successfully tagged nginx:v1.5
  • 讀取Dockerfile進行構建

我們可以將一個檔案的內容讀取出來,而後將其當成Dockerfile進行構建,假設有這樣一個檔案DockerInfo,內容如下:

FROM nginx
RUN echo '<h1>Hello Docker!</h1>' > '/usr/share/nginx/html/index.html'

現在,我們以讀取檔案內容,然後進行構建的方式來構建映象:

[email protected]:~# docker build -< DockerInfo -t nginx:v1.6
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx
 ---> 5699ececb21c
Step 2/2 : RUN echo '<h1>Hello Docker!<h1>' > '/usr/share/nginx/html/index.html'
 ---> Running in a9bff86a9e6c
Removing intermediate container a9bff86a9e6c
 ---> 69e0d5145220
Successfully built 69e0d5145220
Successfully tagged nginx:v1.6

也可以使用如下命令進行構建:

cat DockerInfo | docker build - -t nginx:v1.7

值得注意的是,這種讀取文字檔案內容,然後將其當成Dockerfile來進行構建的方式,由於是直接讀取出文字檔案的內容,它沒有上下文,因此這種方式不可以使用將本地檔案COPY至映象之類的事情

  • 用本地tar壓縮包進行構建

在上面,我們介紹了使用遠端tar壓縮包進行構建的方式,既然可以使用遠端tar壓縮包,那麼就一定可以使用本地壓縮包進行構建,如下:

[email protected]:~# docker build - < docker.tar -t nginx:v1.8
Sending build context to Docker daemon  10.24kB
Step 1/2 : FROM nginx
 ---> 5699ececb21c
Step 2/2 : RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Using cache
 ---> fa8d8e64f43f
Successfully built fa8d8e64f43f
Successfully tagged nginx:v1.8

如果檔案格式是 gzip 、 bzip2 以及 xz 的話,將會使其為上下文壓縮包,將其展開並在裡面將其作為上下文。同樣,假如你的Dockerfile檔案在某個資料夾下面,或者你的Dockerfile檔名不為Dockerfile,那麼需使用-f命令指定Dockerfile檔案,否則將無法定位到

相關推薦

docker dockerfile ubuntusshd

docker dockerfile ubuntusshd #Dockerfile FROM ubuntu:14.04 MAINTAINER gaogd<[email protected]/* */> RUN rm -rf /var/lib/apt/lists RUN cp /etc/

docker--Dockerfile--java

local pri -- lan tin nta bash doc nload # AlpineLinux with a glibc-2.26-r0 and Oracle Java 7FROM alpine:3.6 MAINTAINER Anastas Dancha &l

Docker Dockerfile 指令

zip 所在 time 14.04 docker 影響 就是 com mkdir -p Dockerfile 指令 CMD CMD指令用於指定一個容器啟動時要運行的命令。這有點兒類似於RUN指令,只是RUN指令是指定鏡像被構建時要運行的命令,而CMD是指定容器被啟動時要運行

docker-dockerfile使用

from 維護 gpo path with 添加 work usr stub 使用 centos基礎鏡像, 構建dockerfile-ngix 簡單說, 就是把需要做的東西寫下來, 然後build的時候, 自動運行 一般包含:    基礎鏡像信息 維護者信息 鏡像操作指令

Docker-Dockerfile格式

url daemon 掛載點 自動分配 ins mysq 活著 pos IT 1、FROM //指定基於那個基礎鏡像 格式FROM<image>或者FROM<image>:<tag> 例如: FROM centos FROM centos

docker-dockerfile

之前簡單說過一些,現在來個正式一點的 註釋 # 老規矩,註釋嘛,這個就是 # 前面這個開頭的就是註釋了 # 發現c++的註釋好亮,以後就用這個了 FROM # from必須是dockerfile

docker——Dockerfile(一)

Dockerfile是一個文字格式的配置檔案,使用者可以使用Dockerfile來快速建立自定義的映象。Dockerfile由一行行命令語句組成,並支援以#開頭的註釋行。一般而言,Dockerfile分為四部分:基礎映象資訊、維護者資訊、映象操作指令和容器啟動時執行的命令。 一、Dockerfile指令說明

Docker Dockerfile打包SpringBoot專案為映象並部署

前面學習了Docker,今天來打包個專案Demo測試一下Docker在實際生產環境的使用。 先找一個你本地能執行的SpringBoot專案 安裝了Maven(這裡用Maven構建jar包)

docker Dockerfile詳解

如何使用 Dockerfile用來建立一個自定義的image,包含了使用者指定的軟體依賴等。當前目錄下包含Dockerfile,使用命令build來建立新的image,並命名為edwardsbean/centos6-jdk1.7: docker build -t ed

docker Dockerfile生成映象

1、隨便一個目錄下,建檔案,名為Dockerfile,一個有可以ssh登入的映象 #base images FROM centos #author email MAINTAINER pengpanting [email protected] #modify th

docker——Dockerfile建立映象

1 FROM centos 2 3 MAINTAINER yaolin 4 5 COPY jdk1.7.0_79 jdk1.7.0_79 6 ADD websocket.jar app.jar 7 8 ENV JAVA_HOME=/jdk1.7.0_79 9 ENV PATH=$JA

docker dockerFile 引數解釋,及生成jdk+tomcat映象例項

Dockfile是一種被Docker程式解釋的指令碼,Dockerfile由一條一條的指令組成,每條指令對應Linux下面的一條命令。Docker程式將這些Dockerfile指令翻譯真正的Linux命令。Dockerfile有自己書寫格式和支援的命令,Docker程式解

centos7 docker Dockerfile 生成映象

 這裡我們直接上Dockerfile(注意Dockerfile的名字,D必須大寫,build的時後會自動去指定的目錄下查詢)  #lhy/centos:ssh # #by:V FROM centos:centos6.6               MAINTAINE

docker dockerfile 部署java web

1、準備環境 1 、安裝了docker 環境 ; 2 、下載了ubuntu 映象 ; 2、編寫dockerfile 2.1 : root使用者登入在系統根目錄下建立資料夾test,命令如:mkdir test,並且切換到該目錄下:c

docker~Dockerfile方式生成控制檯和Api專案的映象

回到目錄 一些理論知識 將控制檯程式和API程式部署到docker,然後執行它,這個首先要解決的問題就是如何在linux平臺執行C#程式碼,哈哈,很古老的問題,事實上,對於這種問題早在幾年前就已經有了解決方案,那就是在linux上安裝mono開發環境,然後使用mono就可以執行C#程式碼了,而如果你的C

docker~Dockerfile優化程式的部署

回到目錄 一些理論 我們都知道docker這個容器工具可以幫助我們快速進行環境的部署,這對於運營人員來說,無疑是個福音,而這個工作大叔認為不應該是運營人員乾的,而是由開發人員來做,因為只有你知道你乾的是什麼,你幹了它,就應該要部署它,或者把部署的過程寫成一個指令碼,讓運營人員去執行,就可以了,這也許就是

docker~Dockerfile方式建立映象HelloWorld

回到目錄 Dockerfile可以便捷的建立一個image,它可以在一個映象基礎上,去構建另一個映象,這也許就是它的特色,也是docker的本意! 我們下載一個mono的映象 docker pull mono 然後,我們在本地磁碟去建立一個Dockerfile檔案,讓它在這個mono基礎上,

Docker Dockerfile

mail 指定 htm 而且 man 信息 volume 端口 mman 一、什麽是 Dockerfile 比如我想制作一個鏡像,這個鏡像安裝了 lnmp 、redis 、elk 等各種軟件,制作流程會是這樣: ① 先下載一個基礎鏡像,如 centos② 使用這個鏡像啟

Docker--DockerFile與映象

一:Dockerfile介紹     Dockerfile是一個用於引導docker映象生成過程的檔案,遵循其特定的語法,我們便可以建立一個自己的映象。     Docker在預設情況下,如果不額外指定 Dockerfile 的話,會將上

Docker-DockerFile的使用

在使用DockerFile定製映象之前,我們先來了解一下映象的構成:映象是容器的基礎,每次執行docker run命令的時候都會指定哪個映象作為容器執行的基礎。在之前的栗子中,我們使用的映象都是來著Docker Hub的映象。直接使用這些映象為基礎執行容器可以一