摘要:本文引用至之所以這么牛逼一是在于他強大的生態環境以及他和的新穎的概念鏡像的簡單剖析的我們可以理解為積木一層一層往上搭最后完成一個工程化的大項目在最初實際上只有一個靜態的相當于只能讀所以你所有的改動并不會影響到原來的上只會一層一層的疊加比如
本文引用至: dockerfile
docker 之所以這么牛逼, 一是在于他強大的生態環境, 以及,他container和writable layer 的新穎的概念.
docker鏡像的簡單剖析docker的images,我們可以理解為積木, 一層一層往上搭, 最后完成一個工程化的大項目.
在最初,docker實際上,只有一個靜態的image(Ps: read-only). 相當于只能讀, 所以, 你所有的改動并不會影響到原來的image上, 只會一層一層的疊加, 比如, 你在Ubuntu的image上面, 再接一層nodeJS的image. 實際上的結果是, 兩個image疊加起來.
這里放一張 the Docker book的說明圖:
(Ps: 算啦,估計大家也沒聽懂,還是在下面根據實例,來進行細致的區分吧)
docker 在下載image的時候,會在/var/lib/docker目錄下創建相關的image 目錄. 而運行的container則會放在/var/lib/docker/containers中.
另外,docker中的image,是存儲在docker倉庫. 現在,我們通過快速創建自已的倉庫來仔細了解一下docker是怎樣擁有這樣一個完善的生態的.
docker 倉庫首先, 要想擁有自己的docker 倉庫, 你得有一個自己的docker賬號.so, 那就想apply 一個唄. 在docker hub上面注冊一下自己的賬號就行.
登錄指令在docker中,不僅支持web查看docker中的內容, 而且還支持使用命令行登錄.
// 登錄到docker docker login // 然后輸入賬戶密碼就ok了 // 使用完畢,想要登出 docker logout
實際上,docker會將你的認證信息存放在. ~/.docker/config.json當中。
images 常用命令如果瀏覽了上面的docker倉庫, 會發現在一個repository里面會存在很多images, 比如ubuntu的repository.不同的images發布,代表的都是特定的版本系統. 所以,在拉取的時候,需要額外注意一下你需要的指定docker images.
images的拉取在container中,我們講過,使用docker run的時候, 你會發現如果你的images里面沒有存在指定的image時, docker會主動去docker hub里面找,然后下載,并且自動運行.
// 運行最新版的ubuntu image docker run -t -i ubuntu:latest
如果,你想自己手動下載images的話,可以直接pull
// 手動拉取images docker pull ubuntu:latest // 拉取12.04版本的ubuntu images docker pull ubuntu:12.04
如果在拉取的時候,想知道這個image是否是真正存在的話,就可以使用.docker 提供的搜索指令.
搜索指定docker在docker中,可以使用自帶的search命令,搜索所有含有指定term的image. 相當于js中的search 方法.
// 搜索name中含有demo的image docker search demo // 結果為: 名字. 通常為: author/image_name . 通常搜索的就是這個 // 描述: 就是一段文字描述 NAME DESCRIPTION STARS OFFICIAL AUTOMATED
查到之后,我們就可以使用pull將指定的庫,拉下來了.
創建自己的image上面說過, contianer是copy image運行的進程容器,image是不會變的read-only 塊. 但是,如果我們在container里面, 改動了一些設置,比如,下載了node, 而且,我想要保存我這次改動, 以至于,下次我想重新,啟動該image時, 他已經具備了node.
// 現在我再ubuntu:latest上面安裝了node // 偽代碼 npm install node -g
docker提供了一個非常快捷的方式就是創建自己的docker image. 使用docker commit.
// 查看剛才改動的container ID docker ps -a -q -l // 得到 docker_id, 提交到自己的庫中 docker commit docker_id villainHR/node // 之后會返回新的image id
需要注意,docker commit提交的并不是一個整體的100+MB的ubuntu+node. 他只會將兩個倉庫的差異提交,比如原來image和新的image比起來,就是多了一個npm install node -g命令.
使用DockerfileDockerfile是為了迅速的構建image而出現的. 他與docker commit 的區別在于. 能夠迅速的更替歷史image 命令. 比如,我們以前下載的npm是version 2, 現在想要更換為npm@3的話,則難度就不是一般的了. 但是,如果我們能夠像寫命令一樣將下載的配置命令下載Dockerfile里面, 那么以后我們想要更換版本,就是很方便的啦.
ok, 現在我們來了解一下Dockerfile是怎樣的運行的.
這里,我們利用dockerfile 來搭建一個簡單的webServer. 首先創建一個你自己的dockerfile目錄
mkdir first_docker cd first_docker touch Dockerfile
然后, 確保你有ubuntu:latest image.因為, 接下來我們就是基于它,來搭建我們的server.
# first dockerfile demo FROM ubuntu:latest # 設置該dockerfile的作者和聯系郵箱 MAINTAINER Jimmy "villainhr@gmail.com" # 開始配置環境, 下載apt-get,生成index.html的文件 RUN apt-get update && apt-get install -y nginx RUN echo "first demo" > /usr/share/nginx/html/index.html # 暴露server的port EXPOSE 80
說一下上面的命令內涵.
FROM: 用來指定第一層image, 這是必須有的. 并且指定的image是存在在你的computer中. 相當于是 docker run.
RUN: 這是用來在container中,做出相應的修改. 相當于 修改+docker commit xxx. 給原來的image加上一層layer. 然后, docker會在你commit新一層之后,重新docker run你最新改動過的image
MAINTAINER: 設置作者和聯系郵箱.其實就是docker commit 后面的Name參數. 而且加上了聯系郵箱. 這是在dockerfile 運行完后,會自動添加到image上的.
EXPOSE: 用來給最新的container 設置與外部交流的port
上面簡單的介紹了基本的dockerfile的命令. 不過, 這尼瑪太簡單了,不符合我們一貫追求到底的風格.
這里, 我們在來細說一下RUN這個命令. 實際上, 這應該是dockerfile的關鍵. RUN的原理很簡單, 就是commit + run. 先創建一個新的image 然后 在這個基礎上將原有的container替換為新的,如果某一步的RUN發生錯誤,則container會停在那個階段, 這樣,你可以直接進入該container去查看,你那一步的RUN發生了什么BUG。 另外, 使用RUN的時候, 需要注意, 由于,dockerfile是由上到下解析的, 比如你一開始FROM ubuntu的image, 那么此時的環境是停留在ubuntu的shell中的.
比如:
RUN touch demo.js // 等同于 /bin/sh -c touch demo.js
所以, 如果你調用的image 并沒有shell的話, 那么久需要使用exec調用系統shell 來執行命令.
// 調用系統的shell來運行, 實際上就是 exec xxx xxx xxx. RUN ["npm","install","node"]運行dockerfile
上面的dockerfile文件配置好了之后,就輪到我們運行dockerfile.直接運行docker build即可.
// 注意后面的".", 用來指定搜索dockerfile文件的路徑. docker build -t="jimmy/first_dockerfile" .
說一下docker build的指令吧.
// 基本格式為: docker build -t="repository/name:tag" directory // -t用來指定生成的image的name,比如倉庫,image的名字以及他的tag,如果你不指定tag, 那么docker會自動添加latest代替。 // directory 用來相對于當前運行build的目錄, 搜索指定的dockerfile.當然,你也可以使用絕對路徑了
順利的話,應該就會有, 下列的信息出來.
Sending build context to Docker daemon 2.048 kB Step 1 : FROM ubuntu:latest ---> c5f1cf30c96b Step 2 : MAINTAINER jimmy "villainhr@gmai.com" ---> Running in 078148a5086a ---> 11b061f665d1 Removing intermediate container 078148a5086a Step 3 : RUN cd /var ---> Running in ffd3141e64c8 ---> a4d7c5303b60 Removing intermediate container ffd3141e64c8 Step 4 : RUN touch demo.js ---> Running in c8393a6fcc98 ---> 109b402b9adc Removing intermediate container c8393a6fcc98 Step 5 : EXPOSE 80 ---> Running in 2c064f4bac57 ---> ff7ad58a5d8a Removing intermediate container 2c064f4bac57 Successfully built ff7ad58a5d8a
然后, 你可以使用docker images查看.就會發現多出來一個image.
dockerfile cache上面已經提到過,使用docker build的時候,如果你的dockerfile中的某一步出現問題的話,你生成的image會停留在那一步.當你fix errors時, 重新運行docker build, 此時,docker是不會真的重頭來建一遍的,他會使用你改動line的前一個image,然后以此為基點繼續向下構建.
不過,如果你使用緩存的話,他前面的版本id是不會發生改變的.如果你想完整的得到一個新的ID的話,就可以在build的時候,禁用掉cache.
docker build --no-cache -t="jimmy/first_dockerfile" .
不過,該方法是不推薦的. 因為一個非常棒的cache機制,就被你硬生生的cancel. 而且,這也極力不推薦使用該方法進行cache的取消.以為,有些地方,我們完全可以利用cache來加快速度.這就需要使用到ENV關鍵字.來幫助我們,另外利用cache.
在講解ENV之前,先給大家講解一下docker cache的運行機理.
(是不是感覺很激動~)
實際上,機理就一句話:ID命中. 因為docker在你每次運行一行命令的時候,會自動生成一個id值.
Sending build context to Docker daemon 2.048 kB Step 1 : FROM ubuntu:latest ---> c5f1cf30c96b // 這就是ID值
docker借由這個ID值,來判斷是否有cache鏡像.所以,這里就需要借一下ENV這個比較費的指令,來靈活的幫助我們使用cache.
配置化cacheENV的就是給docker來設置變量的. 基本格式為:
# 一個一個的賦值 ENV key value // demo: ENV name jimmy ENV age 18 # 另外,還可以一起賦值 ENV key=value[...] // demo: ENV name=jimmy age=18
而通過ENV我們就可以完美的告訴docker 從這里開始,你就不能使用cache,自己的重新來.(因為,每條指令都會生成layer并且有獨立的id,一旦你更改的ENV,那么從該指令開始id都會發生改變,也就匹配不到緩存了)
看個demo:
# 第一個dockerfile FROM ubuntu:latest MAINTAINER jimmy "villainhr@gmai.com" ENV REFRESH first # 這里設置的是refresh=first RUN cd /var RUN touch demo.js EXPOSE 80 // 使用docker build ... 后面就會生成一系列新的id和images // 現在修改dockerfile # 第二個dockerfile FROM ubuntu:latest MAINTAINER jimmy "villainhr@gmai.com" ENV REFRESH second # 這里設置的是refresh=second RUN cd /var RUN touch demo.js EXPOSE 80 // 開始運行docker build... 你會發現,從下面語句開始. ENV REFRESH second // 其docker id就已經發生了改變,并且docker 沒有了use cache的提示.說明,下面就沒有命中緩存了. 所以,如果你想在某一段不使用緩存,只需要將ENV后面的value改變即可.
創建完后, 我們可以使用docker history,查看一下剛才創建的image的整個流程.
// 查看image創建的過程 docker history jimmy/first_dockerfile // 輸出的結果為: 2322ddc85cc3 10 hours ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B b39397abc7aa 10 hours ago /bin/sh -c touch demo.js 0 B 3c9a4daf4c42 10 hours ago /bin/sh -c cd /var 0 B b1c2f890a262 10 hours ago /bin/sh -c #(nop) ENV REFRESH=second 0 B 2cf0ee3c373c 10 hours ago /bin/sh -c #(nop) MAINTAINER jimmy "villainhr 0 B
俺的目的,其實是想讓你們看看,docker在每一層是怎么執行的--/bin/sh. 了解了之后,我們就繼續了.
docker container的接口暴露上面通過dockerfile 已經暴露了一個80接口,用來和外部通信。 不過,如果我們沒有使用EXPOSE暴露接口的話, 那應該怎么做呢?
我們可以直接在外部運行docker image, 手動指定暴露的端口.
# 同樣,暴露80端口給外部交互 docker run -d -p 80 --name demo jimmy/node node -jimmy app.js # -d是daemon的意思 # -p 80 表示暴露80的port給外部 # node -jimmy app.js 表示在jimmy/node image里面運行的指令
這里, 我們需要額外了解一下80端口的開啟. docker 其實是在底層上面,虛擬化了存儲. 并且,docker在運行的時候,會自動向主機要一個ip(假的), 相當于,有了自己的host. (這不就一個主機嗎?)
這里我們開啟的80端口,是docker在內部虛擬開啟的, 他會從32768 到 61000端口之間,隨機抽一個映射到docker開啟的80端口上, 依此來和外部進行真正的交互(膜拜///).
# 使用docker ps -l 來查看開啟情況 docker ps -l # 得到: 只截取了一部分. 0.0.0.0:49154->80 tcp # 或者指定查看docker端口開啟情況 docker port c96f2c18bb64 80 // ID也可以使用name代替 # 返回: 0.0.0.0:49154手動指定端口
如果你不想讓docker決定的綁定的接口是哪一個,ok, 你可以自己指定.
# 手動指定端口 # 指定docker的8080連接到container暴露的80端口 docker run -d -p 8080:80 --name demo jimmy/node node -jimmy app.js # 甚至你也可以指定ip+port # 指定docker的127.0.0.1:8080連接container的80 docker run -d -p 127.0.0.1:8080:80 --name demo jimmy/node node -jimmy app.js利用EXPOSE
在寫dockerfile的時候,我們已經了解了,使用EXPOSE可以完美的實現端口的暴露. 但如果,我們在dockerfile里面暴露多個port的話,那么-p的參數,感覺有點雞肋啊喂~
不過,現在我們可以使用-P(注意是大寫). 來手動開啟所有在dockerfile中,通過EXPOSE暴露的端口.
docker run -d -P --name demo jimmy/node node -jimmy app.js外部訪問
通過端口開啟之后,我們就可以間接的訪問docker的路由, 來訪問在docker里面開啟的端口了.
# 假如上面我們通過dockre暴露的端口是34251的話,就可以在docker環境外訪問了. ping localhost:34251dockerfile常用指令 自動化運行CMD
你是不是已經厭煩了使用docker run 來運行命令了呢? 你是不是已經討厭重復的copy命令運行了呢?
那么請使用CMD吧.
CMD的作用是,用來指定當你調其對應的container時, 運行的命令.
比如在dockerfile中,指定/bin/bash.
# 當調起container時,運行/bin/bash docker run -t -i jimmy/ubuntu:latest /bin/bash # 等同于在dockerfile中指定CMD CMD ["/bin/bash"] // 運行docker run docker run -t -i jimmy/ubuntu:latest
不過,如果你在run后面手動指定指令運行的話,會默認覆蓋掉CMD提供的命令.
熟悉了CMD,感覺有種RUN的感覺. 但,這兩者的區別還是很大的
RUN: 一般是用來給image增加layer來完善image, 他一旦執行完,就和后面的運行沒有關系了
CMD: 這個在docker build過程中,是沒有半毛錢關系的. 他只和在調用image時,關系比較大
強制運行ENTRYPOINT這里的ENTRYPOINT和CMD很相似. 可以說,在一定程度上兩者可以互相替代,但,兩者的實際意義相差還是挺大的.
ENTRYPOINT的主要功能是強制執行的環境.
# 指定ENTRYPOINT為/bin/sh ENTRYPOINT ["/bin/sh"] // 然后在build之后,調起container # 我們嘗試在run后面加上參數: docker run -t -i jimmy/demo /bin/bash/ // 不出意外的話,會得到一個bug提示: >> /bin/sh: 0: Can"t open /bin/bash/
所以, ENTRYPOINT的主要功能實際上是,指定了內部運行命令的解析器. 而使用docker run添加的命令,會被當做參數添加給ENTRYPOINT.
# 已經指定了ENTRYPOINT ["/bin/sh"] # 運行docker run docker run -t -i jimmy/demo /bin/bash/ # 實際上相當于(不出錯才怪嘞...) /bin/sh /bin/bash/
另外,我們還可以使用CMD配合ENTRYPOINT寫成默認參數的效果.
# 默認執行 /bin/bash default.sh ENTRYPOINT ["/bin/bash"] CMD ["default.sh"] # 如果你在docker run中指定了參數的話,則CMD會默認被代替 docker run jimmy/demo sam.sh
不過,CMD和ENTRYPOINT都只能在dockerfile里面出現一次.
指定運行目錄WORKDIR既然,我們能夠在dockerfile里面運行指定的命令。 但,有時,我們僅僅是想在不同的目錄中執行不同的命令. 那,在dockerfile中,如何做到靈活的目錄切換呢?
那就得使用docker提供的WORKDIR命令了.
# 在/var/data里面創建data.js WORKDIR /var/data RUN touch data.js # 然后在/etc 下創建data.conf文件 WORKDIR /etc RUN touch data.conf
并且當你在使用docker run時,他也會停留在使用WORKDIR指定的目錄中.
環境變量的設置ENVENV在dockerfile里面的用處,應該算是灰常大的. 什么靈活更新,什么變量設置,什么更改全局變量等. 都是so easy.
那ENV到底是用來干嘛的?
答: 就是用來設置變量的啊喂. 只是他是設置全局變量.
比如像PATH神馬的之類的.
# 設置一個DATA的全局變量. ENV DATA=jimmy
ENV最獨特之處在于,他所設置的變量,會在你運行的時候生效.即,如果你修改了PATH,他也會在container中立即生效.
# 修改環境變量 ENV PATH=$PATH:/user/bin // 現在進入到運行的container中 echo $PATH >> /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/data掛載通用盤VOLUME
在說里面正式的內容之前,我們先來說一下,什么叫做VOLUME. 說人話吧,VOLUME叫做數據卷, 相當于通用盤一樣的東西. 他其實也是一個存儲裝置,我們就把他叫做硬盤吧. 這個硬盤不普通,有>1的外接口.(說人話) 每一個外接口,都可以接入到一個操作系統里面. 即,實現了多個系統的數據共享.
一句話:
VOLUME就是一個數據共享盤
而,docker秉承著,虛擬儲存idea, 想下面idea踐行到底.
wirte once, run anywhere
(感覺,在哪見過)
所以, dockerfile提供了一個VOLUME的指令,能夠讓我們指定數據卷的位置.
# 指定/opt/data為數據卷 VOLUME ["/opt/data"] # 指定多個目錄為數據卷/opt/data, /opt/project VOLUME ["/opt/data","/opt/project"]
當然,關于數據卷的操作,肯定不止掛載這一點,還有遷移,備份等等,相關操作. 具體,可以參考: Docker VOLUME
添加外部文件ADD有時,我們僅僅是想將外部文件copy到container中,docker有辦法嗎?
nonsense
docker 提供了ADD命令,來幫助我們完成文件的添加. 不過,這里ADD有點限制, 即, 你添加的文件或者目錄,只能在docker build運行的目錄下, 因為,這是docker在調起container的時候,只將該目錄放進了daemon(尷尬~)
# 現假設,docker build運行的目錄為: /data // 只能添加指定目錄下 // 將/data/sam.js 添加到image中的/opt/node/sam.js // 如果存在該文件,則不會被覆蓋 ADD sam.js /opt/node/ # 添加文件,還可以使用通配符 // 將所有的js文件,添加到node目錄下 ADD *.js /opt/node/ # 如果destination不是絕對路徑,則相對于最近的WORKDIR // 如果最近的WORKDIR為/var // 則下列添加的路徑為/var/opt/node ADD *.js opt/node/
當文件被添加到指定目錄中時,該文件的權限是755,并且UID和GID都是0.
ADD 還支持url添加,以及文件自動解壓.
# 使用url添加 // 將指定路由的文件放到根目錄當中 ADD http://example.com/foobar / # 自動解壓tar.gz文件 // 將文件解壓過后放在指定目錄中 ADD latest.tar.gz /var/www/wordpress/純粹的COPY
COPY和ADD非常類似. 我們可以做個類比:
ADD 包含 COPY
COPY做的事情比不上ADD, 他比ADD少了解壓縮和URL下載的功能. 不過,他耗費的性能比較少,他只做純粹的添加和下載.他的結構和ADD一毛一樣. 不過, 有一點,COPY的時候,如果遇到目錄不存在的情況下,COPY會自動創建
COPY file.js /opt/data/添加個人信息LABEL
顧名思義,使用LABEL就是給你的image打上獨一無二的標簽.讓別人能夠了解,這個Image是屬于你的. 又或是,用來提醒你自己,這個image現在處于哪一個版本狀態.
# 設置自己的label LABEL owner="jimmy" version="0.0.1"
在創建完image之后, 我們可以使用docker inspect來查看我們已經打的LABEL
docker inspect jimmy/node ... labels:{ owner:"jimmy", version:"0.0.1" } ...
本人覺得, 這個指令其實真的,有時, 母雞用到什么地方去...
并且,書寫的時候,最好多個連著寫,因為這樣只會增加一層image.(image的層數是有限制的)
這是docker提供的另外一個,讓我有點懵逼的命令. 他的實際效果和ENV的區別可以趨近于無。
# 使用ARG定義變量 ARG buildno # 設置默認值 ARG user1=someuser
當然,我們可以在命令中,手動指定替換.
# 在dockerfile定義了默認變量 ARG user=jimy # 在運行時,進行手動替換 docker build --build-arg user=sam -t jimmy/demo .
上面說了ARG和ENV比較類似,不過,里面的區別還是有的. 即, ARG只能用在docker build的階段, 并且不會被保存在image中,這就是和ENV的區別.
模板image之ONBUILD因為dockerfile的構建的層數有限制,所以,這也帶給了我們一些麻煩, 如果搭建的環境過多,則會造成寫到一半,發現dockerfile已經full. 這時候, 就輪到ONBUILD出場了. ONBUILD的作用在于,他可以完美的實現模板image的搭建.
ONBUILD的主要作用在于,他定義的命令,可以在子dockerfile中使用.(md... 好繞口)
# 使用ONBUILD 默認下載Apache ONBUILD RUN apt-get update && apt-get install -y apache2 // 然后運行docker file 會得到下列結果 Step 3 : ONBUILD RUN apt-get update && apt-get install -y apache2 ---> Running in 0e117f6ea4ba ---> a79983575b8 //然后生成一個新的image,我們這里暫且叫他jimmy/demo
接下來,我們再來寫一個dockerfile
# 這里繼承上面的jimmy/demo FROM jimmy/demo:latest ENV SEX=001 // 運行上面的dockerfile,得到: Step 0 : FROM jimmy/demo # Executing 1 build triggers Step onbuild-0 : ADD . /var/www/ ---> 1a018213a59d ---> 1a018213a59d Step 1: ENV SEX=001 ...
細心的童鞋可以發現這一條命令:
Step onbuild-0 : RUN apt-get update && apt-get install -y apache2 ---> 1a018213a59d ---> 1a018213a59d
他居然在這里自動運行了. 所以,我們可以將ONBUILD命令理解為模板命令. 即,子dockerfile里面運行時同樣生效(這里,我沒有說grandchildren的事).
但ONBUILD只能往下延伸一級. 相當于你用ONBUILD定義的命令,有兩次有效次數,一次在build原來Image時,已經用掉了. 所以, 另外一次(在子dockerfile中使用)用掉了之后就無效了. grandchildren dockerfile就沒法使用了.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/26676.html
摘要:和區別讓用戶可以進入查看輸出等等操作,但是并不會另外啟動一個進程如果你用來退出,同時這個信號會默認情況會啟動另外一個進程來進入,這里的操作是在這個進程下的。 走在通往docker的大道上——docker基礎知識匯總 最后編輯時間:2017年03月09日 1.Docker是什么 Docker是一種新的容器化技術,為應用開發和部署提供一站式容器解決方案,能幫助開發者高效快速的構建應用,實...
摘要:源碼解讀系列一好難都跑不起來怎么破了解一下唄閱讀框架源碼第一步搞定環境小伙伴剛接觸的時候會感覺壓力有點大更直觀的說法是難開發組是不贊成難這個說法的的代碼都是實現的而又是世界上最好的語言的代碼閱讀起來是很輕松的開發組會用源碼解讀系列博客深 date: 2018-8-01 14:22:17title: swoft| 源碼解讀系列一: 好難! swoft demo 都跑不起來怎么破? doc...
摘要:源碼解讀系列一好難都跑不起來怎么破了解一下唄閱讀框架源碼第一步搞定環境小伙伴剛接觸的時候會感覺壓力有點大更直觀的說法是難開發組是不贊成難這個說法的的代碼都是實現的而又是世界上最好的語言的代碼閱讀起來是很輕松的開發組會用源碼解讀系列博客深 date: 2018-8-01 14:22:17title: swoft| 源碼解讀系列一: 好難! swoft demo 都跑不起來怎么破? doc...
摘要:將安裝與模塊安裝放在一起的話,則每次修改源代碼,都需要重新安裝,這顯然不合適。使用設置鏡像元數據使用指令,可以為鏡像設置元數據,例如鏡像創建者或者鏡像說明。自從年雙十一正式上線,累計處理了億錯誤事件,付費客戶有金山軟件百姓網等眾多品牌企業。 譯者按: Dockerfile 的語法非常簡單,然而如何加快鏡像構建速度,如何減少 Docker 鏡像的大小卻不是那么直觀,需要積累實踐經驗。這篇...
摘要:安裝完成后,可以用以下命令查看下版本信息。另外,如果要刪除剛運行的兩個容器,可以總結本文從數據持久化開始說起,淺談了和并附送如何用這兩種方式分別搭建環境,并在對比中展示了它們各自的特點。 上一文中提到,每次對容器做了改動,如果不把它 commit 成新的鏡像,在刪除容器后,數據也會丟失,有沒有什么更好的辦法來保存數據呢?使用數據卷就可以解決這個問題。 另外,相對于用 commit 容器...
閱讀 834·2023-04-26 00:13
閱讀 2836·2021-11-23 10:08
閱讀 2455·2021-09-01 10:41
閱讀 2121·2021-08-27 16:25
閱讀 4205·2021-07-30 15:14
閱讀 2367·2019-08-30 15:54
閱讀 867·2019-08-29 16:22
閱讀 2744·2019-08-26 12:13