Visual C++開発環境をコンテナ化する

# 概要
Visual C++開発環境のコンテナ化をしました。

[「コンテナーの高度な例」](https://docs.microsoft.com/ja-jp/visualstudio/install/advanced-build-tools-container?view=vs-2017)のサンプルを元に、Windowsの更新、コンポーネントの限定、不要ファイルの削除などの最適化を行いました。

* [Dockerfile](https://github.com/tetsurom/vctools/blob/master/Dockerfile)
* [ビルド済みイメージ(Docker Hub)](https://hub.docker.com/r/tetsurom/vctools/tags/)

# はじめに

Visual Studio Build Toolsは、Visual Studioからエディターを取り除いたビルドのためのツールです。エディターを含まないので小さなフットプリントでインストールでき、次のような場合に有効です。

* 好きなテキストエディタを使用するのでビルドだけ実行したい
* ビルドの自動化をしたい(+開発マシンと別にビルドマシンを用意したい)

Visual Studio Build Toolsはコンテナへのインストールが可能で、公式の解説も用意されています。

* [Build Tools をコンテナーにインストールする](https://docs.microsoft.com/ja-jp/visualstudio/install/build-tools-container?view=vs-2017)
* [コンテナーの高度な例](https://docs.microsoft.com/ja-jp/visualstudio/install/advanced-build-tools-container?view=vs-2017)

(「Build Tools をコンテナーにインストールする」より)

```Dockerfile:Dockerfile
# escape=`

# .NET Framework 4.7.1が入った最新のWindows Server Coreイメージを使用する
FROM microsoft/dotnet-framework:4.7.1

# デフォルトのシェルを復元する(powershellなどにされている場合に備えて)
SHELL ["cmd", "/S", "/C"]

# Visual Studio Build Toolsのインストーラーを追加する
ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe

# 既知の問題のあるコンポーネントを除いてインストールする
RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
    --installPath C:\BuildTools `
    --all `
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
    --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
    --remove Microsoft.VisualStudio.Component.Windows81SDK `
 || IF "%ERRORLEVEL%"=="3010" EXIT 0

# Visual Studio Build Toolsの環境変数を設定してからコマンドを実行するようにする
ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat &&

# デフォルトでPowerShellを使用する
CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
```

ただ、この通りに実行するとすべての開発環境をインストールするので、コンテナが非常に大きくなってしまいます。すべての開発環境を同時に使うことは稀だと思いますので、必要なものだけをインストールしてコンテナを小さくしましょう。

今回はC++開発環境をインストールしたので記録を残します。

## 注意事項

* コンテナの最大サイズを増やしてください。ビルド実行中はメモリーを多く割り当ててください([「Build Tools をコンテナーにインストールする」](https://docs.microsoft.com/ja-jp/visualstudio/install/build-tools-container?view=vs-2017)を参照)。
* WindowsにおけるDocker環境の構築については解説しません。
* Windows 10 1809およびWindows Server 2019で実験しました。

# ベースイメージを更新する

公式のDockerfileはWindows Server 2016がベースです。
今回はWindows Server Core 2019を使用してみます。

* `microsoft/dotnet-framework:4.7.2-runtime-windowsservercore-ltsc2019`

# Visual Studio Build Toolsをサイレントインストールする

コマンドラインオプションはVisual Studio 2017と同じです。

* [コマンド ライン パラメーターを使用して Visual Studio 2017 をインストールする](https://docs.microsoft.com/ja-jp/visualstudio/install/use-command-line-parameters-to-install-visual-studio?view=vs-2017)

コンポーネントIDについてはこちらを参照してください。

* [Visual Studio Build Tools 2017 のコンポーネント ディレクトリ](https://docs.microsoft.com/ja-jp/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2017)

問題のあるものを除くすべてのコンポーネントをインストールするコマンドラインは次の通りです。

```
vs_buildtools.exe --quiet --wait --norestart --nocache `
    --installPath (インストールパス) `
    --all `
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
    --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
    --remove Microsoft.VisualStudio.Component.Windows81SDK `
```

これを次のように変更すると、C++開発環境のうち推奨コンポーネントまでをインストールできます。

```
vs_buildtools.exe --quiet --wait --norestart --nocache `
    --installPath (インストールパス) `
    --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended `
```

なお、サイレントインストールは回線によっては1時間以上かかります。進捗表示などが無いのでフリーズしているように見えますが、タスクマネージャーで監視したりしながら待ちましょう。

# ログとインストーラーを削除する

Visual Studioのインストールログは非常に大きいので削除しましょう。同様に、インストーラーも削除することができます。
それぞれ、以下の場所にあります。

* `%USERPROFILE%\AppData\Local\Temp\`
* `%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\`

# マルチステージビルドを使う

Visual Studio Build Toolsのインストーラーを複数回実行し、後からコンポーネントの追加・削除ができます。インストールしたコンポーネントの数で別のイメージを作る場合、これをマルチステージビルドにしておくと、ストレージ効率の良いイメージになります。

例えば以下のように、MFC, ATL, C++/CLIを追加したイメージを作れます。
(これだけで3GBほど増加します)

```Dockerfile
FROM microsoft/dotnet-framework:4.7.2-runtime-windowsservercore-ltsc2019 as recommended

# (略)

RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
    --installPath C:\BuildTools `
    --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended

# (略)

FROM recommended as mfc-atl-cli

# (略)

RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
    --installPath C:\BuildTools `
    --add Microsoft.VisualStudio.Component.VC.ATL `
    --add Microsoft.VisualStudio.Component.VC.ATLMFC `
    --add Microsoft.VisualStudio.Component.VC.CLI.Support
```

# コンテナのサイズ

コンテナのサイズは9GB程になります。

* Windows Server Core …… 4GB
* Visual Studio Build Tools (Visual C++のみ) …… 5GB

大きいですね。