鏡像加速
創(chuàng)建一臺(tái)安裝有Docker環(huán)境的Linux虛擬機(jī)嘲玫,指定機(jī)器名稱為study,同時(shí)配置Docker加速器地址。
docker-machine create --engine-registry-mirror=https://8su7gtbj.mirror.aliyuncs.com -d virtualbox default
查看機(jī)器的環(huán)境配置涡尘,并配置到本地忍弛。然后通過(guò)Docker客戶端訪問(wèn)Docker服務(wù)。
docker-machine env default
eval "$(docker-machine env test)"
docker info
- windows環(huán)境下很多docker指令需要在指令前加winpty
常用指令
查看machine ip
- docker-machine ip <machine-name>
docker exec 命令進(jìn)入容器考抄,修改其內(nèi)容
參數(shù):
- -it :這是兩個(gè)參數(shù),一個(gè)是 -i :交互式操作蔗彤,一個(gè)是 -t 終端川梅。我們這里打算進(jìn)入bash執(zhí)行一些命令并查看返回結(jié)果,因此我們需要交互式終端然遏。
- -rm :這個(gè)參數(shù)是說(shuō)容器退出后隨之將其刪除贫途。默認(rèn)情況下,為了排障需求待侵,退出的容器并不會(huì)立即刪除丢早,除非手動(dòng) docker rm 。
查看對(duì)容器的儲(chǔ)存層所做的修改
- docker diff <machine-name>
保存對(duì)容器所做的修改 docker commit
注意盡量不要使用docker commit對(duì)鏡像修改進(jìn)行保存秧倾,而是使用dockerfile進(jìn)行構(gòu)建
避免造成鏡像后期很難進(jìn)行修改和維護(hù)怨酝。
基本語(yǔ)法
docker commit [選項(xiàng)] <容器ID或容器名> [<倉(cāng)庫(kù)名>[:<標(biāo)簽>]]
docker commit \
--author "Tao Wang <twang2218@gmail.com>" \
--message "修改了默認(rèn)網(wǎng)頁(yè)" \
webserver \
nginx:v2
其中 --author 是指定修改的作者,而 --message 則是記錄本次修改的內(nèi)容那先。這點(diǎn)和 git
版本控制相似农猬,不過(guò)這里這些信息可以省略留空。
我們可以在 docker images 中看到這個(gè)新定制的鏡像
查看版本不同
docker history nginx:v2
Dockerfile
dockerfile就是記錄在基礎(chǔ)鏡像之上進(jìn)行構(gòu)建過(guò)程的腳本文件售淡,使后期鏡像更好去維護(hù)斤葱,并且過(guò)程更好去追溯。
Dockerfile指令
-
FROM 指定基礎(chǔ)鏡像
以一個(gè)鏡像為基礎(chǔ)揖闸,在其上進(jìn)行定制揍堕。基礎(chǔ)鏡像是必須指定的汤纸。而 FROM 就是指定基礎(chǔ)鏡
像衩茸,因此一個(gè) Dockerfile 中 FROM是必備的指令,并且必須是第一條指令蹲嚣。除了選擇現(xiàn)有鏡像為基礎(chǔ)鏡像外递瑰,Docker 還存在一個(gè)特殊的鏡像,名為 scratch 隙畜。這個(gè)鏡像
是虛擬的概念抖部,并不實(shí)際存在,它表示一個(gè)空白的鏡像议惰。
FROM scratch
...
如果以 scratch 為基礎(chǔ)鏡像的話慎颗,意味著你不以任何鏡像為基礎(chǔ),接下來(lái)所寫(xiě)的指令將作
為鏡像第一層開(kāi)始存在。
-
RUN 執(zhí)行命令
一個(gè)run指令代表建立一層鏡像俯萎,所以不要一條指令run一次傲宜。
一定要確保每一層只添加真正需要添加的東西,任何無(wú)關(guān)的東西都應(yīng)該清
理掉夫啊。
Dockerfile 支持 Shell 類的行尾添加 \ 的命令換行方
式函卒,以及行首 # 進(jìn)行注釋的格式。
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
-
COPY 復(fù)制文件
源文件的各種元數(shù)據(jù)都會(huì)保留撇眯。比如讀报嵌、寫(xiě)、執(zhí)
行權(quán)限熊榛、文件變更時(shí)間等锚国。
COPY <源路徑>... <目標(biāo)路徑>
COPY ["<源路徑1>",... "<目標(biāo)路徑>"]
COPY ./package.json /app/
COPY 指令將從構(gòu)建上下文目錄中 <源路徑> 的文件/目錄復(fù)制到新的一層的鏡像內(nèi)的 <目標(biāo)路
徑> 位置。比如:
COPY package.json /usr/src/app/
<源路徑> 可以是多個(gè)玄坦,甚至可以是通配符血筑,其通配符規(guī)則要滿足 Go 的 filepath.Match 規(guī)
則,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目標(biāo)路徑> 可以是容器內(nèi)的絕對(duì)路徑煎楣,也可以是相對(duì)于工作目錄的相對(duì)路徑( 工作目錄可以
用 WORKDIR 指令來(lái)指定) 豺总。目標(biāo)路徑不需要實(shí)現(xiàn)創(chuàng)建,如果目錄不存在會(huì)在復(fù)制文件前先行
創(chuàng)建缺失目錄
-
ADD 更高級(jí)的復(fù)制文件
如果 <源路徑> 為一個(gè) tar 壓縮文件的話转质,壓縮格式為 gzip , bzip2 以及 xz 的情況
下园欣, ADD 指令將會(huì)自動(dòng)解壓縮這個(gè)壓縮文件到 <目標(biāo)路徑> 去。
在 COPY 和 ADD 指令中選擇的時(shí)候休蟹,可以遵循這樣的原則沸枯,所有的文件復(fù)制均使用
COPY 指令,僅在需要自動(dòng)解壓縮的場(chǎng)合使用 ADD 赂弓。
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
...
-
CMD 容器啟動(dòng)命令
CMD 指令是用于指定默認(rèn)的容器主進(jìn)程的
啟動(dòng)命令的绑榴。
shell 格式: CMD <命令>
exec 格式: CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]
參數(shù)列表格式: CMD ["參數(shù)1", "參數(shù)2"...] 。在指定了 ENTRYPOINT 指令后盈魁,用 CMD 指
定具體的參數(shù)翔怎。
如果使用 shell 格式的話,實(shí)際的命令會(huì)被包裝為 sh -c 的參數(shù)的形式進(jìn)行執(zhí)行杨耙。比如:
CMD echo $HOME
在實(shí)際執(zhí)行中赤套,會(huì)將其變更為:
CMD [ "sh", "-c", "echo $HOME" ]
直接執(zhí)行 nginx 可執(zhí)行文件,并且要求以前臺(tái)形式運(yùn)行珊膜。比如:
CMD ["nginx" "-g" "daemon off;"]
-
ENTRYPOINT 入口點(diǎn)
當(dāng)存在 ENTRYPOINT 后容握, CMD 的內(nèi)容將會(huì)作為參數(shù)傳給
ENTRYPOINT ,而這里 -i 就是新的 CMD 车柠,因此會(huì)作為參數(shù)傳給 curl
FROM ubuntu:16.04
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
docker run myip -i
-
ENV 設(shè)置環(huán)境變量
設(shè)置環(huán)境變量剔氏,無(wú)論是后面的其它指令塑猖,如 RUN ,還是運(yùn)行時(shí)的
應(yīng)用谈跛,都可以直接使用使用這里定義的環(huán)境變量羊苟。
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
例子:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.ta
r.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
&& tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=
1 \
&& rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
下列指令可以支持環(huán)境變量展開(kāi):
ADD 、 COPY 感憾、 ENV 蜡励、 EXPOSE 、 LABEL 阻桅、 USER 巍虫、 WORKDIR 、 VOLUME 鳍刷、 STOPSIGNAL 、 ONBU
ILD 俯抖。
ARG 構(gòu)建參數(shù)
格式: ARG <參數(shù)名>[=<默認(rèn)值>]
構(gòu)建參數(shù)和 ENV 的效果一樣输瓜,都是設(shè)置環(huán)境變量。所不同的是芬萍, ARG 所設(shè)置的構(gòu)建環(huán)境的
環(huán)境變量尤揣,在將來(lái)容器運(yùn)行時(shí)是不會(huì)存在這些環(huán)境變量的。但是不要因此就是用 ARG 保存密
碼之類的信息柬祠,因?yàn)?docker history 還是可以看到所有值的北戏。
Dockerfile 中的 ARG 指令是定義參數(shù)名稱,以及定義其默認(rèn)值漫蛔。該默認(rèn)值可以在構(gòu)建命令
docker build 中用 --build-arg <參數(shù)名>=<值> 來(lái)覆蓋嗜愈。VOLUME 定義匿名卷
構(gòu)建鏡像
docker build [選項(xiàng)] <上下文路徑/URL/->
-f ../xxx 可以將指定文件作為Dockerfile
在 Dockerfile 文件所在目錄執(zhí)行:
$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM nginx
---> e43d811ce2f4
Step 2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
---> Running in 9cdc27646c7b
---> 44aa4490ce2c
Removing intermediate container 9cdc27646c7b
Successfully built 44aa4490ce2c
鏡像構(gòu)建上下文( Context)
docker build 命令最后有一個(gè) . 。 . 表示當(dāng)前目錄莽龟,而 Dockerfile
就在當(dāng)前目錄蠕嫁,因此不少初學(xué)者以為這個(gè)路徑是在指定 Dockerfile 所在路徑,這么理解其
實(shí)是不準(zhǔn)確的毯盈。
如果在 Dockerfile 中這么寫(xiě):
COPY ./package.json /app/
這并不是要復(fù)制執(zhí)行 docker build 命令所在的目錄下的 package.json 剃毒,也不是復(fù)制
Dockerfile 所在目錄下的 package.json ,而是復(fù)制 上下文( context) 目錄下的
package.json 搂赋。
因此赘阀, COPY 這類指令中的源文件的路徑都是相對(duì)路徑。這也是初學(xué)者經(jīng)常會(huì)問(wèn)的為什么
COPY ../package.json /app 或者 COPY /opt/xxxx /app 無(wú)法工作的原因脑奠,因?yàn)檫@些路徑已經(jīng)
超出了上下文的范圍基公,Docker 引擎無(wú)法獲得這些位置的文件。如果真的需要那些文件捺信,應(yīng)該
將它們復(fù)制到上下文目錄中去酌媒。
現(xiàn)在就可以理解剛才的命令 docker build -t nginx:v3 . 中的這個(gè) . 欠痴,實(shí)際上是在指定上下
文的目錄, docker build 命令會(huì)將該目錄下的內(nèi)容打包交給 Docker 引擎以幫助構(gòu)建鏡像秒咨。
.dockerignore可以將上下文目錄中的文件忽略喇辽,語(yǔ)法與git中的.gitignore一樣
其它 docker build 的用法
docker build 支持從URL構(gòu)建:
$ docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
docker build https://github.com/twang2218/gitlab-ce-zh.git\#:8.14
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM gitlab/gitlab-ce:8.14.0-ce.0
8.14.0-ce.0: Pulling from gitlab/gitlab-ce
aed15891ba52: Already exists
773ae8583d14: Already exists
...
用給定的 tar 壓縮包構(gòu)建:
$ docker build http://server/context.tar.gz
如果所給出的 URL 不是個(gè) Git repo,而是個(gè) tar 壓縮包雨席,那么 Docker 引擎會(huì)下載這個(gè)包菩咨,
并自動(dòng)解壓縮,以其作為上下文陡厘,開(kāi)始構(gòu)建抽米。
容器
- 新建并啟動(dòng)
所需要的命令主要為 docker run
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
-t 選項(xiàng)讓Docker分配一個(gè)偽終端( pseudo-tty) 并綁定到容器的標(biāo)準(zhǔn)輸入上,-i則讓容器的標(biāo)準(zhǔn)輸入保持打開(kāi)糙置。
-啟動(dòng)已終止容器
可以利用 docker start 命令云茸,直接將一個(gè)已經(jīng)終止的容器啟動(dòng)運(yùn)行。
容器的核心為所執(zhí)行的應(yīng)用程序谤饭,所需要的資源都是應(yīng)用程序運(yùn)行所必需的标捺。除此之外,并
沒(méi)有其它的資源揉抵⊥鋈荩可以在偽終端中利用 ps 或 top 來(lái)查看進(jìn)程信息。