[Docker] 容器初體驗 - 搞個 IIS Container 來部署網站

使用 IIS Container 來部署前端網站,藉此熟悉相關指令語法功能。

前言


雖然目前工作上使用 docker 的機會並不多,但容器化的概念絕對也要略懂略懂,因此筆者本著搞搞就懂的精神,當然要實際搞搞來體驗一下;由於筆者並沒有特別關注 Docker 相關技術,所以最快的學習方式就是站在巨人的肩膀上臨摹,趁著保哥最近佛心半價期間上了線上課程,在有經驗的前輩引領下踏入 Docker 世界探險,本文應用是將前端網站部署到 IIS 容器中,藉此瞭解熟悉相關指令及語法;以下就是從無到有的過程,有興趣的朋友也可以玩看看。

 

 

環境準備


Windows 功能中啟用 ContainersHyper-V 功能。

 

安裝 Docker Desktop for Windows 常駐程式,完畢後發現小鯨魚在右下角就成功了。

 

輸入 docker version 可以看到目前 docker 版本資訊,且 docker server 預設 OSlinux

docker version

 

由於我們想要 run 的是 Windows IIS 容器,因此先切換成 Windows containers 環境。

 

再確認一下,確實切換完成。

 

 

取得映像檔 (Image)


Docker Hub 是存放許多 Image 的倉儲,包括公開及私人建立的 Image 檔案,我們可以搜尋 IIS 即可找到不少版本的 IIS 映像檔,由於不是部署 asp.net 網站,所以直接使用 Windows IIS 這個 repo 即可。

 

頁面中會列出部分具代表性的 tags 來區分不同版本 Windows IIS Image,我們可以透過 docker pull 指令將 Image 拉回本機,此範例使用 windowsservercore-1903 標籤的版本。

docker pull mcr.microsoft.com/windows/servercore/iis:windowsservercore-1903

 

 

查看本機映像檔清單


image 取回後可使用 docker images 指令確認剛拉回的 image 是否存在本機。

docker images

 

 

啟動容器 (Container)


首先直接啟動剛下載的 IIS 容器,使用 docker run 指令執行,並透過 -p 設定本機 8080 與容器 80 port 對應關係,最後要指定 run 哪一個 image 起來;執行後顯示 861f 開頭的字串表示這個被啟動 containercontainer id ,後續若要對這個 container 做處理時,可以使用此字串作識別 (僅需前幾碼)。

docker run -d -p 8080:80 mcr.microsoft.com/windows/servercore/iis:windowsservercore-1903

 

使用 docker ps 列出目前運作中的 container 清單,此時就可以看到剛剛啟動標示為 861f 開頭的 container 兩分鐘前被建立且正在執行中。

docker ps

 

打開瀏覽器,確實 IIS container 正在運作中。

 

 

進入容器瞧瞧


剛剛已經見證 IIS container 確實正常運作中,所以筆者想要確認一下 container 中的 IIS 站台資料夾是否確實有資料,並且就是我們瀏覽的那個畫面,因此我們可以透過 docker exec 執行容器內的命令,使用 -it 讓容器的標準輸入保持打開,讓 docker 分配一個虛擬終端 pseudo-tty 並綁定到容器的標準輸入上,並指定 container id 為 861f 開頭的 container 執行 cmd 指令。

docker exec -it 861f cmd

 

執行後隨即進入 container 中,所以我們就可以瀏覽 c:\inetpub\wwwroot 網站資料,確實存在 iisstart.htm 就是我們看到的畫面;如果要離開可以輸入 exit 即跳出 container 回到本機中。

 

 

移除容器


當這個運作的 container 不再需要時,可以透過 docker rm 指令移除,其中 -f 表示強制移除則不需要先停止,最後在指定哪個 container 即可。

docker rm -f 861f

 

執行後確實消失了

 

 

部署網站至容器


我們最終目的是要將網站放入容器,但檔案如何放進容器呢?在測試時期中與其搬進去,我們可以透過 -v 參數來將本機資料夾映射到容器中的特定資料夾位置,這樣帶來的好處是當容器運作中,我們有檔案需要異動時,只需要直接調整檔案即可,無須重新啟動容器就可以達到刷新。

 

docker run -d -p 8080:80 -v d:/containermapper/chat_tw:c:/inetpub/wwwroot/chat/tw mcr.microsoft.com/windows/servercore/iis:windowsservercore-1903

指令表示

  1. 啟動 mcr.microsoft.com/windows/servercore/iis:windowsservercore-1903 映像檔
  2. 本機 port 8080 映射到 container 中的 port 80
  3. 本機 d:/containermapper/chat_tw 映射到容器 c:/inetpub/wwwroot/chat/tw 資料夾

 

執行成功,啟動 container id9d 開頭的容器。

 

在來驗證一下資料是否有映射進去,首先先看本機 d:\containermapper\chat_tw 資料內容。

 

進入 containerc:\inetpub\wwwroot\chat\tw 確認有資料表示映射成功。

 

最後打開瀏覽器看看,網站出現了! 

後續如果修改程式重新建置後隨即可以看到修改後的內容,以驗證建置後的各項參數邏輯是否正確。

 

 

使用 Dockerfile 建立自己的映像檔


當測試都告一段落,我們可以選擇將檔案真的搬入容器中,並且產生新 Image 作為部署的媒介,而此時就需要使用 Dockerfile 來撰寫產生 Image 所需的所有行為指令,簡單 Dockerfile 範例如下。

# 使用的映像檔
FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-1903

# 移除容器 IIS 網站根目錄所有檔案
RUN powershell -NoProfile -Command Remove-Item -Recurse C:\inetpub\wwwroot\*

# 切換容器預設目錄至 IIS 網站根目錄資料夾
WORKDIR /inetpub/wwwroot

# 複製(部署)本機網站檔案至容器中
# From: 本機相對 Dockerfile 檔案位置之相對路徑 build 資料夾下的所有檔案
# To: container 目前工作目錄(WORKDIR)下的 chat/tw 資料夾中
COPY build/ chat/tw

 

接著切換目錄至 Dockerfile 資料夾,透過 docker build 指令來依據 Dockerfile 建立出新的 Image 映像檔,其中 -t 表示給予 Image 名稱及標籤 (標籤沒寫就以預設 latest 標示),由於本例 Dockerfile 就在當前目錄下,因此直接在最後給個 . 就好,若是在其他資料夾則須提供該資料夾路徑,或者使用 -f 給定 Dockerfile 實際位置。

docker build -t my-site .

 

使用 docker images 查看 my-site 映像檔確實已產生。

 

進入 container 看看檔案有沒有真的被搬進去,而這裡透過 --entrypoint 去覆寫原本 IIS 容器的進入點,因為現在我們只想要進去查察資料,不打算真的把 IIS 服務叫起,而是執行 cmd 來看看資料而已。

docker run -it --entrypoint cmd my-site

 

進入後首要發現就是預設目錄如 Dockerfile 設定般地於 inetpub\wwwroot 位置,另外進入 wwwroot 下的 chat\tw 可以發現網站檔案都存在,確定 Dockerfile 寫的 COPY 指令無誤。

 

最後可以把 my-site 映像檔 run 起來 (不需要 -v 去映射資料夾,因為已經在裡面了)

docker run -d -p 8080:80 my-site

 

開啟瀏覽器即可看到網站了。

 

 

後記


本文僅針對這幾天的線上學習做簡易文字紀錄,可以理解的是容器化在維運中確實扮演著重要的角色,其應用支援層面已經越來越廣,看保哥教學針對 asp.net 專案透過版控 commit 觸發執行 msbuild 產生網站檔案後,再透過 docker build 產生 imagepushimage repo 中並觸發部署的流程,讓開發、提交與部署一氣呵成,確實是非常不錯的開發體驗。

 

 

參考資訊


微服務開發基礎:打造容器化 .NET 應用程式

《Docker —— 從入門到實踐­》正體中文版

 

 


希望此篇文章可以幫助到需要的人

若內容有誤或有其他建議請不吝留言給筆者喔 !