前一篇《GitLab CI + Windows Docker 的一些紀錄》的時候,Heresy 已經大概有說明最近在玩 GitLab CI/CD,並試著拿 Docker 來做 Runner 時、在 Windows 平台上碰到的一些狀況了。
當時本來是想放棄的,不過後來還是繼續玩下去了;而玩了一個多禮拜,也總算是把整個環境初步完成了。
而這篇,就來分享一下,Heresy 這邊建置出 Visual C++ 2017 建置環境的 Docker 映像檔的紀錄。
首先,微軟官方其實針對怎麼建立包含 Visual Studio 的 Docker 映像檔有好幾個地方都有範例(範例一、範例二、範例三),內容基本上都相當地類似。
Heresy 這邊最後能用的範例,是基於 dotnet-framework:3.5-sdk-windowsservercore-1709 的版本(連結),其內容如下:
# escape=` # Copyright (C) Microsoft Corporation. All rights reserved. # Licensed under the MIT license. See LICENSE.txt in the project root for license information. ARG FROM_IMAGE=microsoft/dotnet-framework:3.5-sdk-windowsservercore-1709 FROM ${FROM_IMAGE} # Reset the shell. SHELL ["cmd", "/S", "/C"] # Set up environment to collect install errors. COPY Install.cmd C:TEMP ADD https://aka.ms/vscollect.exe C:TEMPcollect.exe # Install Node.js LTS ADD https://nodejs.org/dist/v8.11.3/node-v8.11.3-x64.msi C:TEMPnode-install.msi RUN start /wait msiexec.exe /i C:TEMPnode-install.msi /l*vx "%TEMP%MSI-node-install.log" /qn ADDLOCAL=ALL # Download channel for fixed install. ARG CHANNEL_URL=https://aka.ms/vs/15/release/channel ADD ${CHANNEL_URL} C:TEMPVisualStudio.chman # Download and install Build Tools for Visual Studio 2017 for native desktop workload. ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:TEMPvs_buildtools.exe RUN C:TEMPInstall.cmd C:TEMPvs_buildtools.exe --quiet --wait --norestart --nocache ` --channelUri C:TEMPVisualStudio.chman ` --installChannelUri C:TEMPVisualStudio.chman ` --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended` --installPath C:BuildTools # Use developer command prompt and start PowerShell if no other command specified. ENTRYPOINT C:BuildToolsCommon7ToolsVsDevCmd.bat && CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
而要建置出 Docker 映像檔的時候,則是執行下面的指令:
docker build -t buildtools2017native:latest -m 2GB .
當映像檔建立好後,如果要透過這個映像檔來建置,則是執行:
docker run -m 2G -v %CD%:C:src buildtools2017native:latest --name Solution msbuild /m c:srcSolution.sln
如此一來,就可以把當下的目錄對應到 docker 內的 c:src 資料夾、並透過 msbuild 指令來建置了。
這邊的內容基本上都還可以再做修改,其內容意義大致上是:
-
下載 vscollect.exe 來蒐集 Visual Studio 的安裝紀錄(透過隨附的 Install.cmd)、作為分析之用;如果不需要,可以把相關的段落都拿掉。
-
下載 Node.js 並安裝,不需要也可以拿掉。
-
下載 Build Tools for Visual Studio 2017(沒有圖形介面的版本)線上安裝程式(vs_buildtools.exe)、以及對應的 channel 資料(VisualStudio.chman),並透過 Install.cmd 來安裝。
而 Visual Studio 的安裝元件,也可以透過「–add」指令來新增指定的元件,相關的列表可以參考官方《Visual Studio workload and component IDs》文件。
比如說像 Heresy 這邊使用的 Windows SDK 是較舊的版本,就可以在執行 vs_buildtools.exe 的時候、額外加上「–add Microsoft.VisualStudio.Component.Windows10SDK.15063.Desktop」這樣的參數,來要求他下載、並安裝這個元件。
這樣雖然的確可以做出可以用的 Docker 映像檔,但是實際上卻有一些問題。在 Heresy 來看,最主要的問題,是這邊沒辦法使用較新版的 Windows 基礎影像,只要換成其他新的基礎影像,都會導致 Visual Studio 安裝失敗(而且沒有明顯的錯誤訊息)。
但是 Windows Docker 要使用效能較好的「process」模式來做隔離(isolation)的話,需要 Widnows 1809 以後的版本才可以(參考),所以這份映像檔,會變成只能用 HyperV 的模式來執行…
後來又研究了好一陣子,Heresy 最後是決定使用 Build Tools for Visual Studio 2019 搭配 VC2017 的元件,以搭配較新的 Windows 基礎影像來建置。
最後寫出來的 Dockerfile,就是下面的樣子:
# escape=` # Use the latest Windows Server Core image with .NET Framework 4.8. FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-1903 # Restore the default Windows shell for correct batch processing. SHELL ["cmd", "/S", "/C"] # Download the Build Tools 2019 bootstrapper. ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:TEMPvs_buildtools.exe ADD https://aka.ms/vs/16/release/channel C:TEMPVisualStudio.chman # Install Build Tools excluding workloads and components with known issues. RUN C:TEMPvs_buildtools.exe --quiet --wait --norestart --nocache ` --channelUri C:TEMPVisualStudio.chman ` --installPath C:BuildTools ` --add Microsoft.VisualStudio.Workload.VCTools ` --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 ` --add Microsoft.VisualStudio.Component.VC.v141.MFC # Download and install Windows SDK 10.0.15063 ADD https://go.microsoft.com/fwlink/p/?LinkId=845298 C:TEMPwinsdeksetup.exe RUN C:TEMPwinsdeksetup.exe /features OptionId.DesktopCppx64 /norestart /q # clean download files RUN del C:TEMP* /q # Start developer command prompt with any other commands specified. ENTRYPOINT c:BuildToolsVCAuxiliaryBuildvcvarsall.bat x64 &&
這邊主要的變化,就是下載連結的版本從 2017 的 15 變成 2019 的 16,如此一來才能搭配較新的基礎映像檔。
而執行 vs_buildtools.exe 進行安裝的時候,則是需要額外指定要安裝 Microsoft.VisualStudio.Component.VC.v141.x86.x64 這個 Visual C++ 2017 的元件。
Heresy 這邊因為有用到圖形介面、所以也需要 2017 的 MFC、因此也要加入 Microsoft.VisualStudio.Component.VC.v141.MFC;如果沒有用到的話,也是可以拿掉的。
另外,由於 Heresy 這邊實際上使用的 Windows SDK 是較舊的 10.0.15063,Visual Studio 2019 已經沒有提供了,所以還需要另外去下載來安裝。如果是較新的版本,也是可以直接透過 vs_buildtools.exe 來安裝的。
最後,ENTRYPOINT 的部分,這邊則是略作調整,變成去設定 VC x64 的環境變數。
這樣一來,就建立出一個可以使用 process 模式來隔離的 WIndows Docker 的 Visual C++ 2017 建置環境了!
建置映像檔的時候,可以用下面的指令:
docker build -t builder -m 2GB .
要建置程式碼的話,則可以寫成:
docker run -v %CD%:c:code --isolation process --rm builder msbuild /m
c:code
而如果要進入 Docker 容器內繼續做其他事的話,則可以執行:
docker run -v %CD%:c:code --isolation process --rm builder cmd
基本的 Visual Studio 環境大概就是這樣了~接下來,還有一些額外的 SDK 安裝,有機會再來整理吧。