根據 Ubuntu 22.04 建立 Nginx 容器映像檔,首先需安裝必要的套件,並將自訂的 index.html 檔案複製到容器中,取代 Nginx 預設的網頁。透過埠對映,將容器的 80 埠對映到本機的不同埠,例如 8082、8083、8084 等,避免埠衝突。執行容器後,可使用 curl 指令測試網頁伺服器是否正常運作,並確認自訂的 index.html 內容是否正確顯示。為了方便管理容器映像檔,可以使用 docker tag 命令為映像檔加上標籤,例如 mynginx:01,取代複雜的映像檔 ID,簡化後續的 docker run 操作。文章最後提供一個練習,引導讀者使用 Apache HTTP 伺服器建立容器映像檔,並進行相關操作。
建構我們的首個容器映像檔
執行容器
在成功建立容器映像檔後,我們現在可以執行剛剛建立的容器。清單4-12展示瞭如何執行容器。
清單4-12. 執行我們剛剛建立的容器
docker run -d --name mynginx01 -p 8082:80 aed4ca1695a0
執行上述指令後,系統會回傳容器的ID:
10686bdb60fbb7b83622cd555b6b8cd4e0dfbf4574d7c8c088a26d8b1f2ea8ce
上述指令的語法與前一章節類別似:
-d
:在背景執行容器。--name
:為容器命名,在此例中為mynginx01
。-p 8082:80
:將本機的8082埠對映到容器的80埠。aed4ca1695a0
:容器映像檔的ID,請記得替換成您自己的映像檔ID。
請注意,本機的8080和8081埠已經被佔用,而容器的80埠是我們在建立映像檔時暴露出來的。現在,我們可以使用docker ps
指令來確認容器是否正在執行,如清單4-13所示。
清單4-13. 確認容器正在執行
docker ps
執行結果如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
10686bdb60fb aed4ca1695a0 "/usr/sbin/nginx -g ..." 2 minutes ago Up 2 minutes 0.0.0.0:8082->80/tcp mynginx01
容器正在執行中,這與我們的預期相符。
測試我們的映像檔
為了測試我們的映像檔,我們只需像之前一樣使用curl
指令存取localhost:8082
,如清單4-14所示。
清單4-14. 測試nginx伺服器
curl localhost:8082
執行結果如下:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<SNIP>
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
目前顯示的仍然是預設的index.html
檔案,我們將很快用自訂的index.html
檔案替換它。
將自訂的index.html
納入映像檔
nginx的預設index.html
檔案通常位於/var/www/html/index.nginx-debian.html
。如果我們在建立映像檔的過程中替換這個檔案,我們自訂的index.html
就會被納入映像檔中。清單4-15展示了更新後的Dockerfile。
清單4-15. 更新後的Dockerfile
FROM ubuntu:22.04
COPY ubuntupkgs/*.deb /tmp/
RUN dpkg -i /tmp/*.deb
RUN rm -rf /var/www/html/index.nginx-debian.html
COPY index.html /var/www/html/
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
EXPOSE 80/tcp
我們新增了兩行指令:
RUN rm -rf /var/www/html/index.nginx-debian.html
:刪除預設的index.nginx-debian.html
檔案。COPY index.html /var/www/html/
:將我們自訂的index.html
檔案複製到容器中的/var/www/html/
目錄。
接著,我們可以使用docker build
指令重新建立映像檔,如清單4-16所示。
清單4-16. 重新建立容器映像檔
docker build .
執行結果如下:
Sending build context to Docker daemon 1.968MB
Step 1/7 : FROM ubuntu:22.04
---> 08d22c0ceb15
Step 2/7 : COPY ubuntupkgs/*.deb /tmp/
---> Using cache
---> 1bfeb9969945
Step 3/7 : RUN dpkg -i /tmp/*.deb
---> Using cache
---> 0feb1cd39cf6
Step 4/7 : RUN rm -rf /var/www/html/index.nginx-debian.html
---> Using cache
---> f1154c7b40a8
Step 5/7 : COPY index.html /var/www/html/
---> 0b06c88e4552
Step 6/7 : ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
---> Running in 52a0f6c74a3b
Removing intermediate container 52a0f6c74a3b
---> 623180dcc6a1
Step 7/7 : EXPOSE 80/tcp
---> Running in 8be2c5e7e0e9
Removing intermediate container 8be2c5e7e0e9
---> 390c89ba092d
Successfully built 390c89ba092d
請記下新的容器ID。接著,我們可以使用這個新的映像檔來啟動另一個容器,如清單4-17所示。這次,我們將本機的8083埠對映到容器的80埠。
清單4-17. 啟動更新後的容器映像檔
docker run -d --name mynginx02 -p 8083:80 390c89ba092d
curl localhost:8083
執行結果如下:
<html>
<title>My own container image </title>
<body>
Hello world!<br>
This is my index file embedded in my first container image!!<br>
</body>
</html>
現在,我們的自訂index.html
已經成功地被納入容器映像檔中並且可以正常存取。
#### 內容解密:
docker run
指令引數解析:-d
:使容器在背景執行。--name
:為容器指定名稱。-p
:進行埠對映,將主機埠與容器埠進行繫結。
curl
指令測試:- 使用
curl
存取localhost
對應的埠,驗證nginx伺服器是否正常執行。
- 使用
Dockerfile更新內容:
RUN rm -rf /var/www/html/index.nginx-debian.html
:刪除預設的index.html
。COPY index.html /var/www/html/
:將自訂的index.html
複製到容器中。
docker build
指令:- 根據更新後的Dockerfile重新建立映像檔。
連續整合(CI)概念:
- 透過自動化建立和測試容器映像檔,實作連續整合的基礎。
圖表翻譯:
此圖示展示了容器建立與執行的流程:
graph LR A[建立Dockerfile] --> B[執行docker build指令] B --> C[生成容器映像檔] C --> D[執行docker run指令] D --> E[啟動容器] E --> F[測試容器服務]
圖表翻譯: 此圖展示了從建立Dockerfile到測試容器服務的完整流程。首先,我們建立Dockerfile,接著執行docker build
指令生成容器映像檔。然後,使用docker run
指令啟動容器,最後測試容器中的服務是否正常執行。
為容器映像檔加上標籤
由於很難記住或使用映像檔ID,我們可以為容器映像檔加上友好的名稱,也就是標籤。在本文中,我們將為容器映像檔加上標籤。首先,我們需要使用docker images
命令來查詢我們要標記的容器映像檔的IMAGE ID,如清單4-18所示。
清單4-18:顯示目前的容器映像檔列表
docker images
shiva@wks01:~/container-static-website$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 390c89ba092d 11 minutes ago 86.1MB
<none> <none> aed4ca1695a0 38 minutes ago 86.1MB
ubuntu/nginx latest c1c59dacd1ed 4 weeks ago 140MB
ubuntu 22.04 08d22c0ceb15 4 weeks ago 77.8MB
ubuntu latest 08d22c0ceb15 4 weeks ago 77.8MB
ubuntu 20.04 1c5c8d0b973a 4 weeks ago 72.8MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
shiva@wks01:~/container-static-website$
內容解密:
此命令輸出了目前系統中的容器映像檔列表,包括映像檔的REPOSITORY、TAG、IMAGE ID、CREATED和SIZE等資訊。可以看到,我們剛剛建立的映像檔沒有REPOSITORY和TAG名稱,只有IMAGE ID。
使用IMAGE ID非常不方便,因此我們需要為容器映像檔加上標籤。標記映像檔的命令格式如下:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
在我們的例子中,我們希望將IMAGE ID為390c89ba092d
的映像檔標記為mynginx:01
,因為這個映像檔包含了我們建立的nginx網頁伺服器,如清單4-19所示。
清單4-19:為容器映像檔加上標籤
docker tag 390c89ba092d mynginx:01
shiva@wks01:~/container-static-website$ docker tag 390c89ba092d mynginx:01
shiva@wks01:~/container-static-website$
內容解密:
此命令將IMAGE ID為390c89ba092d
的映像檔標記為mynginx:01
。這使得我們可以使用友好的名稱來操作容器映像檔。
然後,我們使用docker images
命令來驗證標記結果,如清單4-20所示。
清單4-20:顯示加上標籤後的容器映像檔列表
docker images
shiva@wks01:~/container-static-website$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx 01 390c89ba092d 13 minutes ago 86.1MB
<none> <none> aed4ca1695a0 40 minutes ago 86.1MB
ubuntu/nginx latest c1c59dacd1ed 4 weeks ago 140MB
ubuntu 22.04 08d22c0ceb15 4 weeks ago 77.8MB
ubuntu latest 08d22c0ceb15 4 weeks ago 77.8MB
ubuntu 20.04 1c5c8d0b973a 4 weeks ago 72.8MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
shiva@wks01:~/container-static-website$
內容解密:
現在,IMAGE ID為390c89ba092d
的映像檔有了友好的名稱mynginx:01
。我們可以使用這個名稱來啟動容器。
現在,我們可以使用新的名稱來啟動容器,如清單4-21所示。
清單4-21:啟動容器並將網頁伺服器對映到未使用的連線埠
docker run -d --name mynginx04 -p 8084:80 mynginx:01
shiva@wks01:~/container-static-website$ docker run -d --name mynginx04 -p 8084:80 mynginx:01
20d136c66141942f167a5f3cf24a3d30a68d0bc8559ab8ff17b1f788d16d3886
shiva@wks01:~/container-static-website$
內容解密:
此命令啟動了一個名為mynginx04
的容器,並將容器的80連線埠對映到主機的8084連線埠。容器使用了我們剛剛建立的mynginx:01
映像檔。
然後,我們可以使用docker ps
命令來驗證容器是否成功啟動,如清單4-22所示。
清單4-22:確認容器成功啟動
docker ps
shiva@wks01:~/container-static-website$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
20d136c66141 mynginx:01 "/usr/sbin/nginx -g ..." 18 seconds ago Up 17 seconds 0.0.0.0:8084->80/tcp, :::8084->80/tcp mynginx04
9da0cfa8be22 390c89ba092d "/usr/sbin/nginx -g ..." 15 minutes ago Up 15 minutes 0.0.0.0:8083->80/tcp, :::8083->80/tcp mynginx02
50231cd5dd48 aed4ca1695a0 "/usr/sbin/nginx -g ..." 22 minutes ago Up 22 minutes 0.0.0.0:8082->80/tcp, :::8082->80/tcp mynginx01
5e25f3c059ec ubuntu/nginx:latest "/docker-entrypoint...." 3 hours ago Up 3 hours 0.0.0.0:8081->80/tcp, :::8081->80/tcp nginx02
b51b6f4a5934 ubuntu/nginx:latest "/docker-entrypoint...." 3 hours ago Up 3 hours 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx01
shiva@wks01:~/container-static-website$
內容解密:
此命令輸出了目前正在執行的容器列表。可以看到,我們剛剛啟動的容器mynginx04
正在執行,並且網頁伺服器的80連線埠已經對映到主機的8084連線埠。
練習
與前面的練習類別似,請嘗試使用apache2/httpd伺服器建立自己的容器映像檔,使用自己的index.html,建立、發布和執行容器。
graph LR A[建立容器映像檔] --> B[為容器映像檔加上標籤] B --> C[啟動容器] C --> D[驗證容器狀態]
圖表翻譯: 此圖表呈現了建立容器映像檔的流程。首先,我們需要建立容器映像檔(A),然後為容器映像檔加上標籤(B),接著啟動容器(C),最後驗證容器狀態(D)。這個流程展示了容器映像檔從建立到佈署的完整過程。