第四章 使用Docker鏡像和倉(cāng)庫(kù)(二)
回顧:
開(kāi)始學(xué)習(xí)之前,我先pull下來(lái)ubuntu和fedora鏡像
[#9#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker pull fedora
Using default tag: latest
latest: Pulling from library/fedora
9bdb5101e5fc: Pull complete
Digest: sha256:1fa98be10c550ffabde65246ed2df16be28dc896d6e370dab56b98460bd27823
Status: Downloaded newer image for fedora:latest
[#10#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
ebe73f29e6e1: Pull complete
4976a0f2dc03: Pull complete
5c117067c385: Pull complete
001d664e2dd4: Pull complete
Digest: sha256:7eb6ad74ec4fbe56ac194d8760063c88ca362f05a9038f2bc4f09a51849a4a53
Status: Downloaded newer image for ubuntu:latest

4.5.6 Dockerfile 和構(gòu)建緩存
想略過(guò)緩存功能,可以使用 docker build 的 --no-cache 標(biāo)志
sudo docker build --no-cache -t="zhiyewang/static_web" .
4.5.7 基于構(gòu)建緩存的 Dockerfile 模板
FROM ubuntu:14.04
MAINTAINER zhiyewang "zhiye_wang@yeah.net"
ENV REFRESHED_AT 2016-03-16
RUN apt-get -qq update
這里要想重新構(gòu)建 Dockerfile ,只需要將第三行的日期修改以下即可。將會(huì)更新 APT 包的緩
存。
4.5.8 查看新鏡像

查看鏡像如何構(gòu)建出來(lái),可以使用 docker history 命令。可以看到新構(gòu)建的 zhiyewang/stat
ic_web 鏡像的每一層。以及創(chuàng)建這些層的 Dcoekrfile 命令。

4.5.9 從構(gòu)建的新鏡像啟動(dòng)容器
上一節(jié)成功使用 Dockerfile 命令構(gòu)建出 zhiyewang/static_web 這個(gè)鏡像。現(xiàn)在我們來(lái)試試
看鏡像是否工作正常。z
基于新構(gòu)建的鏡像啟動(dòng)一個(gè)新容器。
[#17#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker run -d -p 80 --name stati
c_web zhiyewang/static_web nginx -g "daemon off;"
d4d9024c688d267761dee792e0b0686a6b2d06dcf53e656c98d95408f4894974
這條命令基于方才構(gòu)建的鏡像名字,啟動(dòng)了一個(gè)名為 static_web 的新容器。 同時(shí)指定了 -d 選
項(xiàng),告訴 Docker 以分離的方式在后臺(tái)運(yùn)行。同時(shí)也指定了在新容器中運(yùn)行的命令: nginx -g "
daemon off;"。這將以前臺(tái)的方式啟動(dòng) Nginx。新標(biāo)志 -p 用來(lái)控制 Docker 在運(yùn)行時(shí)應(yīng)該公
開(kāi)哪些網(wǎng)絡(luò)端口給外部(宿主機(jī))。
[#19#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker ps -l
CONTAINER ID IMAGE COMMAND PORTS
d4d9024c688d zhiyewang/static_web "nginx -g 'daemon off" 0.0.0.0:32768->80/tcp
可以看到容器中的 80 端口被映射到宿主機(jī)的 32768 端口。
也可以使用 docker port 查看端口的情況
[#20#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker port d4d9024c688d
80/tcp -> 0.0.0.0:32768
這樣的端口映射方式為隨機(jī)的,我們也可以指定特定的端口映射
將容器的 80 端口綁定到本地宿主機(jī)的 80 端口
sudo docker run -d -p 80:80 --name static_web zhiyewang/static_web nginx -g "daemon off;"
將容器的 80 端口綁定到本地宿主機(jī)的 8080 端口
sudo docker run -d -p 8080:80 --name static_web zhiyewang/static_web nginx -g "daemon off;"
將容器的 80 端口綁定到本地宿主機(jī)的 127.0.0.1 這個(gè) IP 的 80 端口
sudo docker run -d -p 127.0.0.1:80:80 --name static_web zhiyewang/static_web nginx -g "daemon off;"
將容器的 80 端口綁定到本地宿主機(jī)的 127.0.0.1 這個(gè) IP 的隨機(jī)端口
sudo docker run -d -p 127.0.0.1::80 --name static_web zhiyewang/static_web nginx -g "daemon off;"
對(duì)外公開(kāi)端口,此命令可以將容器內(nèi)的 80 端口對(duì)本地宿主機(jī)公開(kāi),并且綁定要宿主機(jī)的一個(gè)
隨機(jī)端口。此命令同時(shí)也會(huì)將 Dockerfile 文件中 EXPOSE 指令指定的其他端口一并公開(kāi)。
sudo docker run -d -p --name static_web zhiyewang/static_web nginx -g "daemon off;"
這樣我們就可以使用本地宿主機(jī)的 IP 地址或者 127.0.0.1 的 localhost 來(lái)連接到運(yùn)行的容器,
查看 Web 服務(wù)器的內(nèi)容了。
[#33#cloudsoar@cloudsoar-virtual-machine ~]$curl localhost:32768
Hi, I am in your container
4.5.10 Dockerfile 指令
1 CMD 指令
CMD 指令用于指定一個(gè)容器啟動(dòng)時(shí)候需要運(yùn)行的指令。有點(diǎn)類(lèi)似于 RUN 指令,區(qū)別是 RUN
指令是指定鏡像被構(gòu)建時(shí)候運(yùn)行的指令,而 CMD 是容器被啟動(dòng)時(shí)運(yùn)行的指令。
命令行啟動(dòng)容器的 /bin/true
[#34#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker run -i -t zhiyewang/static_web /bin/true
可以使用 CMD 寫(xiě)在 Dockerfile 中:
CMD ["/bin/true"]
也可以為要運(yùn)行的命令指定參數(shù)
CMD ["/bin/bash", "-l"]
需要注意的是 docker run 命令可以覆蓋 CMD 指令。如果 dockerrun 中指定了命令,而CM
D 中也指定了相同的命令,命令行中的指令會(huì)覆蓋 Dockerfile 中的 CMD 指令。
假設(shè)我們的 Dockerfile 中有如下命令
CMD [ "/bin/bash" ]
使用 docker build 命令構(gòu)建一個(gè)新鏡像,假設(shè)為 zhiyewang/test,并基于此鏡像啟動(dòng)一個(gè)新
容器。
[#35#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker run -t -i zhiyewang/test
root@7ec0a03d41fc:/#
可以看到 docker run 命令的末尾并沒(méi)有指定 /bin/bash 指令,卻進(jìn)入了容器的 bash。實(shí)際上
Docker 使用了 CMD 中指定的命令。
但是 Dockerfile 中只能指定一條 CMD 指令。如果制定多個(gè),只有最后一個(gè)會(huì)被調(diào)用。
2 ENTRYPOINT
ENTRYPONIT 指令提供的命令不會(huì)再容器啟動(dòng)時(shí)被命令行覆蓋。
ENTRYPONIT ["/usr/sbin/nginx"]
為 ENTRYPOINT 指定參數(shù)
ENTRYPONIT ["/usr/sbin/nginx", "-g", "daemon off;"]
如果需要 也可以在運(yùn)行時(shí)通過(guò) docker run 的 --entrypoint 標(biāo)志覆蓋 ENTRYPOINT 指令。
3 WORKDIR
WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
ENTRYPOINT [ "rackup" ]
把目錄切換到 /opt/webapp/db 指定了 bundle install 命令,然后又將工作目錄切換為 /opt
/webapp 最后這只了 ENTRYPOINT 指令來(lái)啟動(dòng) rackup 命令。
4 ENV
ENV 可以用來(lái)在鏡像構(gòu)建過(guò)程中設(shè)置環(huán)境變量
ENV RMV_PATH /home/rvm/
這個(gè)環(huán)境變量設(shè)置后在后續(xù)的任何 RUN 中都可以使用
也可以在其他指令中直接使用這些環(huán)境變量
RVM_PATH=/home/rvm/ gem install unicorn
ENV 創(chuàng)建的環(huán)境變量也會(huì)被持久保存到從我們的鏡像創(chuàng)建的任何容器中。比如在容器中運(yùn)行
env 查看:
root@7ec0a03d41fc:/# env
...
RVM_PATH=/home/rvm/
運(yùn)行時(shí)環(huán)境變量
sudo docker run -ti -e "WEB_PORT=8080" ubuntu env
可以講容器的 WEB_PORT 環(huán)境變量設(shè)置為 8080
5 USER
user 指令用來(lái)指定該鏡像會(huì)以什么樣的用戶(hù)去執(zhí)行
USER nginx
我們可以指定用戶(hù)名或者 UID 以及組或者 GID,甚至是兩者的組合。也可以在 docker run 命
令中通過(guò) -u 選項(xiàng)來(lái)覆蓋該指令的值。如果不通過(guò) USER 指定特定用戶(hù),默認(rèn)是 root 。
6 VOLUME
VOLUME ["/opt/project"]
這條指令將會(huì)為基于此鏡像創(chuàng)建的任何容器創(chuàng)建一個(gè)名為 /opt/projiect 的掛載點(diǎn)。也可以通過(guò)
數(shù)組的方式指定多個(gè)卷。
VOLUME ["/opt/project", "/data"]
7 ADD
ADD 命令用來(lái)將構(gòu)建環(huán)境下的文件和目錄復(fù)制到鏡像中。也可以指定URL。Docker 通過(guò)目的地
址的參數(shù)末尾的字符來(lái)判斷文件源是目錄還是文件。如果目的地址以 / 結(jié)尾,Docker 認(rèn)為是一個(gè)
目錄,如果不是的話,認(rèn)為是文件。
ADD http://wordpress.org/latest.zip /root/wordpress.zip
ADD 在處理本地的歸檔文件(包括 gzip,bzip2,xv)指定為源文件時(shí)候,會(huì)自動(dòng)將歸檔解壓。
ADD latest.tar.gz /var/www/wordpress/
8 COPY
COPY 和 ADD 的本質(zhì)區(qū)別是 COPY 只關(guān)心在構(gòu)建上下文中復(fù)制本地文件,而不會(huì)去做文件提
取和解壓的工作。COPY 的文件源路徑必須是一個(gè)與當(dāng)前構(gòu)建環(huán)境相對(duì)的文件或目錄,本地文
件都放到和 Dockerfile 同一個(gè)目錄下。不能復(fù)制該目錄之外的任何文件。目的為止必須是容器
內(nèi)部的一個(gè)絕對(duì)路徑。該指令創(chuàng)建的文件或者目錄的 UID 和 GID 都會(huì)被設(shè)置為 0 。
COPY conf.d/ /etc/apache2/
9 ONBUILD
4.6 將鏡像退送到 Docker Hub
[#37#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker push zhiyewang/static_web
The push refers to a repository [docker.io/zhiyewang/static_web] (len: 1)
e97eb7ef0136: Pushed
6a7a53f6e78a: Pushed
ddc8935b098a: Pushed
40fa5cd1c3d2: Pushed
c5aed3a8ff95: Pushed
0b427fcc4cbb: Pushed
9d89fd8f8a3e: Pushed
073de23ee32b: Pushed
latest: digest: sha256:152eb2d70e0f795fbe1b8f8c9eea09e7832a8b01e953cc051cd07832732da0ed size: 14731
現(xiàn)在可以在 Docker Hub 上看到我們的鏡像了。

自動(dòng)構(gòu)建
4.7 刪除鏡像
如果不需要一個(gè)鏡像了 可以使用 docker rmi 來(lái)刪除
[#41#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker rmi zhiyewang/static_web
Error response from daemon: conflict: unable to remove repository reference "zhiyewang/static_web" (must force) - container 7ec0a03d41fc is using its referenced image e97eb7ef0136
Error: failed to remove images: [zhiyewang/static_web]
可以看到這個(gè)鏡像被一個(gè)容器 7ec0a03d41fc 使用著,首先刪除掉容器即可。
[#53#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker rm 7ec0a03d41fc
7ec0a03d41fc
[#62#cloudsoar@cloudsoar-virtual-machine ~]$sudo docker rmi e97eb7ef0136
Deleted: e97eb7ef013619e503bd729596a06e46ee85786619d95950e54f5a74c6fc2694
Deleted: 6a7a53f6e78a802ea932a5914e63d217acf4a47ddbedb80dab042d55297573a5
Deleted: ddc8935b098a0b449a3335286b2b0e555b3d44bd5d92dea305c57f6f7c846fae
Deleted: 40fa5cd1c3d2ae9c80763e9b787c5c9b4848a34164fc2138d2c160830505466d
Deleted: c5aed3a8ff9508b42644cef59c2b44c249628c54130fa1a030f3f2b299124ecc
這里刪除的是本地的鏡像。每一個(gè) Deleted: 行都代表一個(gè)鏡像層被刪除。
4.8 運(yùn)行自己的 Docker Registry
這個(gè)可以自己試試了。
到此為止,第四章學(xué)習(xí)完畢。
下一篇學(xué)習(xí)在測(cè)試中使用 Docker,用Docker 測(cè)試一個(gè)靜態(tài)網(wǎng)站,用 Docker 創(chuàng)建并測(cè)試一個(gè)
WEB 應(yīng)用,用 Docker 用于持續(xù)集成