學習 Docker 最先碰到的困擾應該都是究竟該如何偵錯
,畢竟 Docker Run Container 如果沒有下一些指令,通常都是執行完就砍掉,什麼都沒留下,不像在本機可以透過開發的 IDE、Log … 等手段來 Debug,所以這邊就寫下一些我較常使用的偵錯方式
Run
如果 Build Docker Image 時就有指定 CMD 或是 ENTRYPOINT,那 Container Run 起來後跑完就關掉了,這時候可以透過 Run 的最後一個參數來覆蓋過原本的 CMD 指令。
1 | $ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe |
這邊的 cmd.exe 就是要覆蓋 Build Image 所指定的指令,讓你可以進入 Container 的 terminal 中執行你想做的指令
Volume
因為 Container 每次執行都是全新的,所以導致 Log 不易保留,但我們可以 Volume 的方式將 Host Folder 與 Container 內的 Log Folder Mount ,這樣就可以將 Container 內的 Log File 寫出來,達到持久化的效果。
(圖片來源 : Docker Docs )
接著用簡單的範例來展示一下
1 | $ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe |
進到 Container 後,隨便寫個檔案
1 | $ mkdir log |
可以看到在 Container 內的確長出了 C:\log 資料夾,並且裡面有個 test.txt 的檔案,檔案裡面寫著 “hi”。但這時候你在 host 機器應該找不到對應的檔案,因為 Container 是彼此獨立且隔離的。
這時候離開 Container 再重啟一次,會發現剛剛 log 的 Folder 已經消失,因為這個 Container 是全新的
1 | $ exit |
Volume 使用方式
1 | docker run -v HostFolderPath:ContainerFolderPath |
加上 Volume 參數再重新執行一次剛剛的步驟
1 | $ docker run -it -v c:\files:c:\log mcr.microsoft.com/windows/nanoserver:1809 cmd.exe |
將 Host 機器的 c:\files
Folder Mount 到 Container 內的 c:\log
資料夾,所以在 Container 內新增檔案寫 Log 也會同時寫出來
這邊應該會注意到,因為 Volume 了 Container 內原本不存在的 log 資料夾,所以一進去的時候它就長出來了,並不需要特別另外建立。
EXEC
有時候 Container 內執行的是常駐程式,它可能會持續執行直到任務完成,如果又沒有將 Log 寫出來的必要,其實很難知道它目前的狀況為何,這時候 EXEC 就派上用場了,它可以讓你進入一個正在執行中的 Container 中。
一樣用個簡單的範例來演練一下
先 Run 一個 Container 起來,並且一樣寫一個 log 下來
1 | $ docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe |
這時候開另一個 terminal,先查詢剛剛的 Container ID
1 | $ docker ps |
透過 EXEC 指定要執行哪個 Container
1 | $ docker exec -it d24e6db4de85 cmd.exe |
可以看到一進去就已經有剛剛我們寫下的 test.txt,表示這是同一個 Container,或是可以透過 hostname 來做驗證,可以得到相同的 ID