Windows 上的 Dockerfile
Docker 引擎包含自動化容器映射建立的工具。 雖然您可以藉由執行 docker commit
命令手動建立容器映射,但採用自動化映射建立程式有許多優點,包括:
- 將容器映像儲存為程式碼。
- 快速、精確地為維護和升級等用途重新建立容器映像。
- 容器映像與開發週期之間的持續整合。
驅動這項自動化的 Docker 元件是 Dockerfile 和 docker build
命令。
Dockerfile 是文字檔,其中包含建立新容器映射所需的指示。 這些指令包含將用作基底的現有映像識別碼、在映像建立程序中執行的命令,以及部署容器映像新執行個體時所執行的命令。
Docker build 是 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 的 Dockerfiles 的其他範例,請參閱 適用于 Windows 的 Dockerfile 存放庫。
指示
Dockerfile 指示會提供 Docker 引擎建立容器映射所需的指示。 這些指令會依序逐一執行。 下列範例是 Dockerfiles 中最常使用的指示。 如需 Dockerfile 指示的完整清單,請參閱 Dockerfile 參考。
FROM
FROM
指令會設定新映像建立程序期間所使用的容器映像。 比方說,在使用指令 FROM mcr.microsoft.com/windows/servercore
時,所產生的映像衍生自 (而且會相依於) Windows Server Core 基本 OS 映像。 如果指定的映像不存在於正在執行 Docker 建置流程的系統上,Docker 引擎會嘗試從公用或私用的映像登錄下載映像。
FROM 指令的格式如下所示:
FROM <image>
以下是 FROM 命令的範例:
若要從 Microsoft Container Registry (MCR) 下載 ltsc2019 版 Windows Server Core:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
如需詳細資訊,請參閱 FROM 參考。
RUN
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
相反地,下列範例會在殼層表單中執行相同的作業:
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
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\
此外,ADD
指令在 Linux 上會於複製時展開壓縮的封裝。 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 Cmdlet
您可以使用作業在 Dockerfile RUN
中執行 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。
您也可以選擇使用 .NET WebClient 文件庫,便可在映像建立程序期間使用 PowerShell 下載檔案。 這樣會增進下載效能。 下列範例會使用 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