一般來說,我們所說的“構建鏡像”並不是真正的從零構建一個全新的鏡像,而是修改一個已有的基礎鏡像(如ubuntu)。
創建Docker Hub賬號
(1) 如果要存儲和分發我們構建的新鏡像,那麼可以將鏡像發佈到 Docker Hub 或者自己私有的Registry上面。所以需要先在 Docker Hub 創建一個賬號。
(2)創建賬號後,使用 docker login
命令就可以登錄到Docker Hub了。
# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: sweeneys
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
如上所示,登錄的個人認證信息被保存到 ~/.docker/config.json
使用commit命令創建鏡像
1、創建容器
創建一個基於ubuntu鏡像的容器,後續會以這個容器爲基礎進行修改,從而形成新的鏡像。
# docker run -it ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7ddbc47eeb70: Pull complete
c1bbdc448b72: Pull complete
8c3b70e39044: Pull complete
45d437916d57: Pull complete
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for ubuntu:latest
2、添加Apache軟件包
Apache軟件包在ubuntu官方源上的名字爲apache2。
root@51753edb3a70:/# apt-get update
root@51753edb3a70:/# apt-get install apache2
3、提交容器
爲了避免以後每次創建容器的時候都重新添加Apache, 我們可以使用 docker commit
命令將 當前容器的狀態(容器快照)
保存下來形成一個新的鏡像。
(1)退出容器:
root@51753edb3a70:/# exit
exit
(2)提交容器:
# docker commit 51753edb3a70 apache2
sha256:a2ffe8f3ca2f02d3b0a202640ed5da45f81761fa6141c2dfa4bd99bb158d42fb
說明:
a.51753edb3a70
爲剛剛添加了apache的容器ID。
b.apache2
爲倉庫名。
(3)查看新鏡像
# sudo docker images apache2
REPOSITORY TAG IMAGE ID CREATED SIZE
apache2 latest bd1e81d3fd76 3 minutes ago 188MB
如上所示, apache2
倉庫中 IMAGE ID 爲 bd1e81d3fd76
的鏡像即爲剛剛創建的新鏡像。
(4)以新鏡像創建一個容器
sudo docker run -it apache2 /bin/bash
root@6ed53ad4fc3d:/#
使用Dockerfile構建鏡像
1、創建Dockerfile文件
Dockerfile文件使用基於DSL(Domain-special Language)語法的指令來構建一個Docker鏡像。
# mkdir static_web
# cd static_web/
static_web# touch Dockerfile
說明:
(1)創建 static_web
目錄用來保存Dockerfile, 則static_web
目錄就是我們的構建環境(build environment), Docker 把構建環境稱爲 構建上下文(build context)
或者 上下文(context)
。
2、編寫Dockerfile 文件
# version 0.0.1
FROM ubuntu:18.04
MAINTAINER sweeneys "[email protected]"
RUN apt-get update && apt-get install -y nginx
RUN echo 'Hi, I am in your contianer.' > /usr/share/nginx/html/index.html
EXPOSE 80
說明:
(1)Dockerfile由命令和參數組成,命令必須全部大寫,參數不可少,如:FROM ubuntu:18.04 。
(2)命令從上到下執行,大體流程如下:
a.Docker從基礎鏡像(FROM命令指定的鏡像)運行一個容器。
b.執行一條指令,對鏡像進行修改。
c.執行類似 docker commit的操作,提交一個新的鏡像。
d.Docker再基於剛提交的新鏡像,運行一個容器。
e.執行Dockerfile中的下一條指令。直到所有指令執行完畢。
(3)Dockerfile使用 # 號進行註釋。
(4)Dockerfile官方文檔:https://docs.docker.com/engine/reference/builder/
FROM: 指定基礎鏡像,後續指令操作將基於該鏡像。
MAINTAINER:指定鏡像作者及聯繫方式。
RUN: 在當前鏡像中運行的命令。
EXPOSE: 指定容器的端口。
3、docker build構建新鏡像
Dockerfile編寫好後,就可以結合 docker build
構建新鏡像了。
# sudo docker build -t static_web:v1 /tmp/static_web/
說明:
(1)-t: 指定標籤。
(2)/tmp/static_web/:告訴Docker 到該目錄尋找Dockerfile。
如果構建文件名不叫Dockerfile,例如:df。那麼需要使用 -f
參數。示例:
# sudo docker build -t static_web:v1 /tmp/static_web/df
4、docker history
如果我們想要查看鏡像是如何構建出來的,可以使用 docker history
命令。
# docker history static_web:v1
IMAGE CREATED CREATED BY SIZE COMMENT
637238913845 16... /bin/sh -c #(nop) ... 0B
d561441b8649 16... /bin/sh -c echo 'H... 28B
3457c54a2eda 16... /bin/sh -c apt-get... 87.9MB
775349758637 6 ... /bin/sh -c #(nop) ... 0B
5、從新鏡像啓動容器
# sudo docker run -d --name static_web -p 80 static_web:v1 nginx -g "daemon off;"
ac66082d8745fcbd0dcd77b1024499d4e701090228f477df085627505d09467f
說明:
(1)-p: 控制Docker在運行時公開哪些端口給外部(宿主機)。
(2)-P:也可以通過 -P
(大寫的P)參數對外公開EXPOSE命令指定的端口。
# sudo docker run -d --name nginx1 -P static_web:v1 nginx -g "daemon off;"
(3)Docker 有兩種方式將開發的端口映射到宿主機上。
a.隨機選擇。在讓Docker自己在創建容器的時候隨機選擇一個位於32768-61000中的端口映射到容器的80端口。
b.指定端口。在創建容器的時候指定一個具體的端口映射到容器的80端口。
# sudo docker run -d --name nginx1 -p 8080:80 static_web:v1 nginx -g "daemon off;"
如上所示,將容器的80端口綁定到宿主機的8080端口。然後通過綁定的端口即可訪問容器,如: http://127.0.0.1:8080
。
(4)可以通過 docker port
命令查看端口的映射情況
# sudo docker port static_web
80/tcp -> 0.0.0.0:32771
將鏡像推送到Docker Hub
1、確保倉庫名規範
如我在Docker Hub上的用戶爲sweeneys, 那麼我的鏡像倉庫名應該爲sweeneys/xxx的形式:
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sweeneys/static_web latest e9ae1570fdba 46 minutes ago 152MB
static_web v1 e9ae1570fdba 46 minutes ago 152MB
apache2 latest bd1e81d3fd76 7 hours ago 188MB
redis latest dcf9ec9265e0 3 weeks ago 98.2MB
ubuntu 18.04 775349758637 6 weeks ago 64.2MB
ubuntu latest 775349758637 6 weeks ago 64.2MB
如上所示,只有 sweeneys/static_web
這個倉庫名纔是規範的。
2、docker login
推送鏡像之前,要先登錄Docker Hub賬號。
# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: sweeneys
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
3、docker push
推送鏡像到Docker Hub使用的命令是 docker push
。
# docker push sweeneys/static_web
The push refers to repository [docker.io/sweeneys/static_web]
456ff9508bd5: Pushed
c142f1f70838: Pushed
e0b3afb09dc3: Pushed
6c01b5a53aac: Pushed
2c6ac8e5063e: Pushed
cc967c529ced: Pushed
latest: digest: sha256:949fe9adeedc001db1abb0d69ca138bc205b2d23c41b82d434fd9a21ec67f6a2 size: 1571
4、查看推送的鏡像
最後可以到 https://hub.docker.com/ 查看我們推送的鏡像。
參考資料
[1]James Turnbull, 《第一本Docker書》
[2]