Windows 上的 Dockerfile
Docker 引擎包含自動化容器映像建立的工具。 雖然您可以藉由執行 docker commit
命令手動建立容器映像,但採用自動化映像建立程式有許多優點,包括:
- 將容器映像儲存為程序代碼。
- 為了維護和升級目的,快速且精確地重新建立容器映像。
- 容器映像與開發週期之間的持續整合。
驅動此自動化的 Docker 元件是 Dockerfile 和 docker build
命令。
Dockerfile 是文本檔,其中包含建立新容器映像所需的指示。 這些指示包括識別要作為基底的現有映像、在映像建立程式期間執行的命令,以及部署容器映像新實例時將會執行的命令。
Docker 建置是 Docker 引擎命令,會取用 Dockerfile 並觸發映像檔建立流程。
本主題將說明如何搭配 Windows 容器使用 Dockerfiles、瞭解其基本語法,以及最常見的 Dockerfile 指示是什麼。
本文件將討論容器映像和容器映射層的概念。 如果您要深入瞭解映像和映像分層,請參閱 容器基底映像。
如需 Dockerfiles 的完整指南,請參閱 Dockerfile 參考資料。
基本語法
在最基本的形式中,Dockerfile 可以非常簡單。 下列範例會建立新的映像,其中包含 IIS 和 『hello world』 網站。 此範例包含批注(以 #
表示),可說明每個步驟。 本文後續章節將更詳細地說明 Dockerfile 語法規則,以及 Dockerfile 指示。
注意
必須建立 Dockerfile 且沒有擴充功能。 若要在 Windows 中執行此動作,請使用您選擇的編輯器建立檔案,然後使用表示法 “Dockerfile” 加以儲存(包括引號)。
# Sample Dockerfile
# Indicates that the windowsservercore image will be used as the base image.
FROM mcr.microsoft.com/windows/servercore:ltsc2019
# Metadata indicating an image maintainer.
LABEL maintainer="jshelton@contoso.com"
# Uses dism.exe to install the IIS role.
RUN dism.exe /online /enable-feature /all /featurename:iis-webserver /NoRestart
# Creates an HTML file and adds content to this file.
RUN echo "Hello World - Dockerfile" > c:\inetpub\wwwroot\index.html
# Sets a command or process that will run each time a container is run from the new image.
CMD [ "cmd" ]
如需適用於 Windows 的 Dockerfile 的其他範例,請參閱 Windows 的 Dockerfile 存放庫。
指示
Dockerfile 指示會提供 Docker Engine 建立容器映射所需的指示。 這些指示會依序執行。 下列範例是 Dockerfiles 中最常使用的指示。 如需 Dockerfile 指示的完整清單,請參閱 Dockerfile 參考。
從
FROM
指令會設定將在新映射建立程式期間使用的容器映像。 例如,使用指令 FROM mcr.microsoft.com/windows/servercore
時,生成的映像檔源自於,並依賴於 Windows Server Core 基底 OS 映像檔。 如果執行 Docker 建置程式所在的系統上沒有指定的映像,Docker 引擎會嘗試從公用或私人映射登錄下載映像。
FROM 指令的格式如下所示:
FROM <image>
以下是 FROM 命令的範例:
若要從 Microsoft 容器註冊表(MCR)下載 Windows Server Core ltsc2019 版本:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
如需詳細資訊,請參閱 FROM 參考資料。
跑
RUN
指令會指定要執行的命令,並擷取到新的容器映像中。 這些命令可以包含安裝軟體、建立檔案和目錄,以及建立環境設定等專案。
RUN 指令如下所示:
# exec form
RUN ["<executable>", "<param 1>", "<param 2>"]
# shell form
RUN <command>
exec 和 shell 窗體之間的差異在於如何執行 RUN
指令。 使用 exec 表單時,會明確執行指定的程式。
以下是 exec 表單的範例:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN ["powershell", "New-Item", "c:/test"]
產生的映像會執行 powershell New-Item c:/test
命令:
docker history doc-exe-method
IMAGE CREATED CREATED BY SIZE COMMENT
b3452b13e472 2 minutes ago powershell New-Item c:/test 30.76 MB
對比之下,下列範例以 shell 形式執行相同的作業:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell New-Item c:\test
產生的映像具有 cmd /S /C powershell New-Item c:\test
的執行指令。
docker history doc-shell-method
IMAGE CREATED CREATED BY SIZE COMMENT
062a543374fc 19 seconds ago cmd /S /C powershell New-Item c:\test 30.76 MB
搭配 Windows 使用 RUN 的考慮
在 Windows 上,搭配 exec 格式使用 RUN
指令時,必須逸出反斜杠。
RUN ["powershell", "New-Item", "c:\\test"]
當目標程式是 Windows 安裝程式時,您必須先透過 /x:<directory>
旗標擷取安裝程式,才能啟動實際的 (無訊息) 安裝程式。 您也必須等候命令結束,再執行任何其他動作。 否則,過程將會過早結束,並且不會安裝任何東西。 如需詳細資訊,請參閱下列範例。
搭配 Windows 使用 RUN 的範例
下列範例 Dockerfile 使用 DISM 在容器映射中安裝 IIS:
RUN dism.exe /online /enable-feature /all /featurename:iis-webserver /NoRestart
此範例會安裝 Visual Studio 可轉散發套件。
Start-Process
和 -Wait
參數可用來執行安裝程式。 這確保在繼續 Dockerfile 中的下一個指令之前安裝已完成。
RUN powershell.exe -Command Start-Process c:\vcredist_x86.exe -ArgumentList '/quiet' -Wait
如需 RUN 指示的詳細資訊,請參閱 RUN 參考。
複製
COPY
指令會將檔案和目錄複製到容器的檔案系統。 檔案和目錄必須位於相對於 Dockerfile 的路徑中。
COPY
指令的格式如下所示:
COPY <source> <destination>
如果來源或目的地包含空格符,請以方括弧和雙引號括住路徑,如下列範例所示:
COPY ["<source>", "<destination>"]
在 Windows 中使用 COPY 的考量
在 Windows 上,目的地格式必須使用正斜線。 例如,這些是有效的 COPY
指示:
COPY test1.txt /temp/
COPY test1.txt c:/temp/
同時,下列包含反斜杠的格式將無法有效:
COPY test1.txt c:\temp\
Windows 中使用 COPY 的範例
下列範例會將來源目錄的內容新增至容器映像中名為 sqllite
的目錄:
COPY source /sqlite/
下列範例會將以 config 開頭的所有檔案新增至容器映射的 c:\temp
目錄:
COPY config* c:/temp/
如需 COPY
指示的詳細資訊,請參閱 COPY 參考。
加
ADD 指令就像 COPY 指令,但具有更多功能。 除了將檔案從主機複製到容器映射之外,ADD
指令也可以從具有URL規格的遠端位置複製檔案。
ADD
指令的格式如下所示:
ADD <source> <destination>
如果來源或目的地包含空格符,請以方括弧和雙引號括住路徑:
ADD ["<source>", "<destination>"]
使用 Windows 執行 ADD 的考慮
在 Windows 上,目的地格式必須使用正斜線。 例如,這些是有效的 ADD
指令:
ADD test1.txt /temp/
ADD test1.txt c:/temp/
同時,具有反斜杠的下列格式將無法運作:
ADD test1.txt c:\temp\
此外,在Linux上,ADD
指令會在複製時展開壓縮套件。 此功能不適用於 Windows。
搭配 Windows 使用 ADD 的範例
下列範例會將來源目錄的內容新增至容器映像中名為 sqllite
的目錄:
ADD source /sqlite/
下列範例會將開頭為 「config」 的所有檔案新增至容器映像的 c:\temp
目錄。
ADD config* c:/temp/
下列範例會將適用於 Windows 的 Python 下載到容器映射的 c:\temp
目錄中。
ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe
如需 ADD
指示的詳細資訊,請參閱 ADD 參考。
WORKDIR
WORKDIR
指令會設定其他 Dockerfile 指令的工作目錄,例如 RUN
、CMD
,以及執行容器映射實例的工作目錄。
WORKDIR
指令的格式如下所示:
WORKDIR <path to working directory>
搭配 Windows 使用 WORKDIR 的考慮
在 Windows 上,如果工作目錄包含反斜杠,則必須逸出它。
WORKDIR c:\\windows
範例
WORKDIR c:\\Apache24\\bin
如需 WORKDIR
指示的詳細資訊,請參閱 WORKDIR 參考。
CMD
CMD
指令會設定部署容器映像實例時要執行的預設命令。 例如,如果容器將裝載 NGINX 網頁伺服器,則 CMD
可能包含使用類似 nginx.exe
命令啟動網頁伺服器的指示。 如果在 Dockerfile 中指定了多個 CMD
指令,則只會評估最後一個指令。
CMD
指令的格式如下所示:
# exec form
CMD ["<executable", "<param>"]
# shell form
CMD <command>
搭配 Windows 使用 CMD 的考慮
在 Windows 上,CMD
指令中指定的檔案路徑必須使用正斜線或逸出反斜杠 \\
。 以下是有效的 CMD
指示:
# exec form
CMD ["c:\\Apache24\\bin\\httpd.exe", "-w"]
# shell form
CMD c:\\Apache24\\bin\\httpd.exe -w
不過,沒有適當斜線的下列格式將無法運作:
CMD c:\Apache24\bin\httpd.exe -w
如需 CMD
指示的詳細資訊,請參閱 CMD 參考。
跳脫字元
在許多情況下,Dockerfile 指令必須跨越多行。 若要這樣做,您可以使用跳脫字元。 預設的 Dockerfile 跳脫字元是反斜杠 \
。 不過,由於反斜杠也是 Windows 中的檔案路徑分隔符,因此使用反斜杠跨越多行可能會導致問題。 若要解決此問題,您可以使用解析器指示詞來變更預設跳脫字符。 如需剖析器指示詞的詳細資訊,請參閱 剖析器指示詞。
下列範例顯示使用預設逸出字元跨越多行的單一 RUN 指令:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell.exe -Command \
$ErrorActionPreference = 'Stop'; \
wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; \
Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
Remove-Item c:\python-3.5.1.exe -Force
若要修改跳脫字元,請在 Dockerfile 的第一行加入跳脫剖析指示詞。 在下列範例中可以看到這一點。
注意
只能使用兩個值做為逸出字元:\
和 `
。
# escape=`
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell.exe -Command `
$ErrorActionPreference = 'Stop'; `
wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; `
Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; `
Remove-Item c:\python-3.5.1.exe -Force
如需有關逃逸剖析器指令的詳細資訊,請參閱 逃逸剖析器指令。
Dockerfile 中的 PowerShell
PowerShell Cmdlets
您可以使用 RUN
作業,在 Dockerfile 中執行 PowerShell Cmdlet。
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell -command Expand-Archive -Path c:\apache.zip -DestinationPath c:\
REST 呼叫
從 Web 服務收集資訊或檔案時,PowerShell 的 Invoke-WebRequest
Cmdlet 很有用。 例如,如果您建置包含 Python 的映像,您可以將 $ProgressPreference
設定為 SilentlyContinue
,以達到更快的下載速度,如下列範例所示。
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell.exe -Command \
$ErrorActionPreference = 'Stop'; \
$ProgressPreference = 'SilentlyContinue'; \
Invoke-WebRequest https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; \
Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
Remove-Item c:\python-3.5.1.exe -Force
注意
Invoke-WebRequest
也適用於 Nano Server。
在映像建立程序期間使用PowerShell下載檔案的另一個選項是使用 .NET WebClient 連結庫。 這會增加下載效能。 下列範例會使用 WebClient 連結庫下載 Python 軟體。
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell.exe -Command \
$ErrorActionPreference = 'Stop'; \
(New-Object System.Net.WebClient).DownloadFile('https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe','c:\python-3.5.1.exe') ; \
Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
Remove-Item c:\python-3.5.1.exe -Force
注意
Nano Server 目前不支援 WebClient。
PowerShell 腳本
在某些情況下,將腳本複製到您在映像建立程序期間使用的容器可能會很有幫助,然後從容器內執行腳本。
注意
這會限制任何影像層的快取,並降低 Dockerfile 的可讀性。
此範例會使用 ADD
指令,將組建機器中的腳本複製到容器中。 接著,此腳本會使用 RUN 指令來執行。
FROM mcr.microsoft.com/windows/servercore:ltsc2019
ADD script.ps1 /windows/temp/script.ps1
RUN powershell.exe -executionpolicy bypass c:\windows\temp\script.ps1
Docker 組建
建立 Dockerfile 並儲存至磁碟之後,您可以執行 docker build
來建立新的映像。
docker build
命令接受數個選擇性參數和 Dockerfile 的路徑。 如需 Docker 組建的完整檔,包括所有建置選項的清單,請參閱 組建參考。
docker build
命令的格式如下所示:
docker build [OPTIONS] PATH
例如,下列命令會建立名為 「iis」 的映像。
docker build -t iis .
當建置程式起始時,輸出會指出狀態並傳回任何擲回的錯誤。
C:\> docker build -t iis .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM mcr.microsoft.com/windows/servercore:ltsc2019
---> 6801d964fda5
Step 2 : RUN dism /online /enable-feature /all /featurename:iis-webserver /NoRestart
---> Running in ae8759fb47db
Deployment Image Servicing and Management tool
Version: 10.0.10586.0
Image Version: 10.0.10586.0
Enabling feature(s)
The operation completed successfully.
---> 4cd675d35444
Removing intermediate container ae8759fb47db
Step 3 : RUN echo "Hello World - Dockerfile" > c:\inetpub\wwwroot\index.html
---> Running in 9a26b8bcaa3a
---> e2aafdfbe392
Removing intermediate container 9a26b8bcaa3a
Successfully built e2aafdfbe392
結果是新的容器映射,在此範例中名為 「iis」。。
docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
iis latest e2aafdfbe392 About a minute ago 207.8 MB
windowsservercore latest 6801d964fda5 4 months ago 0 B
進一步閱讀和參考
- 優化適用於 Windows 的 Dockerfiles 和 Docker 組建
- Dockerfile 參考指南