如今咱們定製好了變化,咱們但願能將其保存下來造成鏡像。html
要知道,當咱們運行一個容器的時候(若是不使用卷的話),咱們作的任何文件修改都會被記錄於容器存儲層裏。而 Docker 提供了一個 docker commit
命令,能夠將容器的存儲層保存下來成爲鏡像。換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,並構成新的鏡像。之後咱們運行這個新鏡像的時候,就會擁有原有容器最後的文件變化。nginx
docker commit
的語法格式爲:git
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標籤>]]
咱們能夠用下面的命令將容器保存爲鏡像:web
$ docker commit \ --author "Tao Wang <twang2218@gmail.com>" \ --message "修改了默認網頁" \ webserver \ nginx:v2 sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214
其中 --author
是指定修改的做者,而 --message
則是記錄本次修改的內容。這點和 git
版本控制類似,不過這裏這些信息能夠省略留空。docker
咱們能夠在 docker images
中看到這個新定製的鏡像:bash
$ docker images nginx REPOSITORY TAG IMAGE ID CREATED SIZE nginx v2 07e334659748 9 seconds ago 181.5 MB nginx 1.11 05a60462f8ba 12 days ago 181.5 MB nginx latest e43d811ce2f4 4 weeks ago 181.5 MB``` 咱們還能夠用 `docker history` 具體查看鏡像內的歷史記錄,若是比較 `nginx:latest` 的歷史記錄,咱們會發現新增了咱們剛剛提交的這一層。 ```bash $ docker history nginx:v2 IMAGE CREATED CREATED BY SIZE COMMENT 07e334659748 54 seconds ago nginx -g daemon off; 95 B 修改了默認網頁 e43d811ce2f4 4 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon 0 B <missing> 4 weeks ago /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp 0 B <missing> 4 weeks ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx/ 22 B <missing> 4 weeks ago /bin/sh -c apt-key adv --keyserver hkp://pgp. 58.46 MB <missing> 4 weeks ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.11.5-1 0 B <missing> 4 weeks ago /bin/sh -c #(nop) MAINTAINER NGINX Docker Ma 0 B <missing> 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:23aa4f893e3288698c 123 MB
新的鏡像定製好後,咱們能夠來運行這個鏡像。tcp
docker run --name web2 -d -p 81:80 nginx:v2
這裏咱們命名爲新的服務爲 web2
,而且映射到 81
端口。若是是 Docker for Mac/Windows 或 Linux 桌面的話,咱們就能夠直接訪問 http://localhost:81 看到結果,其內容應該和以前修改後的 webserver
同樣。學習
至此,咱們第一次完成了定製鏡像,使用的是 docker commit
命令,手動操做給舊的鏡像添加了新的一層,造成新的鏡像,對鏡像多層存儲應該有了更直觀的感受。spa
docker commit
使用 docker commit
命令雖然能夠比較直觀的幫助理解鏡像分層存儲的概念,可是實際環境中並不會這樣使用。3d
首先,若是仔細觀察以前的 docker diff webserver
的結果,你會發現除了真正想要修改的 /usr/share/nginx/html/index.html
文件外,因爲命令的執行,還有不少文件被改動或添加了。這還僅僅是最簡單的操做,若是是安裝軟件包、編譯構建,那會有大量的無關內容被添加進來,若是不當心清理,將會致使鏡像極爲臃腫。
此外,使用 docker commit
意味着全部對鏡像的操做都是黑箱操做,生成的鏡像也被稱爲黑箱鏡像,換句話說,就是除了製做鏡像的人知道執行過什麼命令、怎麼生成的鏡像,別人根本無從得知。並且,即便是這個製做鏡像的人,過一段時間後也沒法記清具體在操做的。雖然 docker diff
或許能夠告訴獲得一些線索,可是遠遠不到能夠確保生成一致鏡像的地步。這種黑箱鏡像的維護工做是很是痛苦的。
並且,回顧以前說起的鏡像所使用的分層存儲的概念,除當前層外,以前的每一層都是不會發生改變的,換句話說,任何修改的結果僅僅是在當前層進行標記、添加、修改,而不會改動上一層。若是使用 docker commit
製做鏡像,以及後期修改的話,每一次修改都會讓鏡像更加臃腫一次,所刪除的上一層的東西並不會丟失,會一直如影隨形的跟着這個鏡像,即便根本沒法訪問到™。這會讓鏡像更加臃腫。
docker commit
命令除了學習以外,還有一些特殊的應用場合,好比被入侵後保存現場等。可是,不要使用 docker commit
定製鏡像,定製行爲應該使用 Dockerfile
來完成。下面的章節咱們就來說述一下如何使用 Dockerfile
定製鏡像。