Windows 11 ProでWindows Container を動かす
今の業務で開発しているアプリが、ファイルパスの関係で正常に動かすにはWindows上でアプリを動かす必要があった。これまでは直接ホスト上でアプリを動かしていたのだが、融通が利かないアプリなので、何かと開発環境に設定が必要で面倒に感じてきた。 仮想マシンで動かすことも考えたが、開発用VMだと定期的に環境の作り直しが発生するし、新しくWindowsのライセンスを用意するのも微妙な気がする。
そこで思い出したのはWindows Container。いわゆるDockerで動かすContainerのOSはLinuxになるが、WindowsをOSとしたContainerも存在する。あんまり流行ってなさそうだが。
自分が今使っているのはWindows 11 Proを使っている かつ 開発目的にしか使う想定が無いので、Windows Container環境的には問題なし。(運用で使うにはWindows Serverを使用しないとNGとのこと)
これまで一度も動かしたことが無かったので、これを機会に動かしてみた。
セットアップ
Prepare Windows operating system containers | Microsoft Learnや、Windows PCでDocker Desktopを利用せずにLinuxコンテナーとWindowsコンテナー環境を構築する方法 #Docker - Qiita を参考にセットアップをする。
Windows 11 Proの場合は、dockerを使う以外の方法は無いようだ。 Docker Desktopが推奨の方法だが有償化してしまったので、Install Docker Engine from binaries | Docker Docsで言及されているDockerエンジンのみのインストールをおこなう。
管理者権限でPowerShellを起動
Enable-WindowsOptionalFeature -Online -FeatureName $("Microsoft-Hyper-V", "Containers") -All
一度再起動して、管理者権限で再度PowerShellを起動
winget install --scope machine -ei --id Docker.DockerCLI
dockerd --register-service
なお、上述の手順でwingetでscopeをmachineに設定したり、サービスとして登録している都合、winget update --allでエラーが発生するため、その対象から除外しておく。 (アップデート手順は後述)
winget pin add --id Docker.DockerCLI
Windows Containerの起動
現在のユーザからdockerコマンドを使用できるようにするため、管理者権限のPowerShellで以下を実行
New-LocalGroup -Name 'docker-users' -Description 'Users of Docker for Windows'
Add-LocalGroupMember -Group 'docker-users' -Member "$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)"
C:\ProgramData\docker\config\daemon.jsonに以下のファイルを作成する。
※他の設定を変更するときは、このサイトを参照すること。
{
"group" : "docker-users"
}
管理者権限のPowerShellで以下を実行し、dockerデーモンを起動する。
Start-Service docker
Windows Containerはプロセス分離、Hyper-Vの2つのモードがあり、プロセス分離はLinuxコンテナと同じようにカーネルを共有して動かすもの、Hyper-Vは仮想化により動かすものみたい。 Linuxとは異なり、カーネルとOSイメージが密接に結びついているようで、プロセス分離の場合はホストOSと合致するOSイメージしか使用できないそう。ホストOSと異なるOSを使いたい場合はHyper-Vを使うべし、ということらしい。
Windows 11 ProではデフォルトはHyper-V。プロセス分離で動かす場合は、コンテナ起動時に引数で明示する必要がある。
プロセス分離で起動する場合は、以下のようなコマンドになる。
docker run --isolation=process -d -t --name container-01 mcr.microsoft.com/windows/servercore:ltsc2022 cmd.exe
後は通常のdockerと同じような感じで使える(みたい)
docker exec -it container-01 powershell
GUIが使えないので、リモートのファイルサーバのマウントはnet use等、コマンドでどうにかする必要はあるが、それなりに使えそう。
ESETを使用している場合
ESETのSSL/TLSプロトコルフィルタリングの機能により、証明書の問題が発生する可能性がある。その場合は、ESETの証明書をホストでエクスポートし、それをコンテナでインポートする必要がある。
ESETの詳細設定画面を開き、下図の赤線部分(証明書の表示)をクリックする。

ファイルにコピーをクリック

証明書にエクスポートウィザードを進めて、証明書をファイルにエクスポートする。 エクスポートした証明書は、docker cpコマンドでコンテナにコピーする。
docker cp .\eset.cer container-01:C:/
コピーした証明書をコンテナでインポートする。
docker exec -it container-01 powershell -c "Import-Certificate -CertStoreLocation cert:\localMachine\Root C:/eset.cer"
Docker Composeを使用する場合
管理者権限でPowerShellを起動
winget install --scope machine -ei --id Docker.DockerCompose
winget pin add --id Docker.DockerCompose
docker-composeコマンドが使用できるようになる。(docker composeではない)
Dockerをアップデートする場合
上述の手順でDockerをインストールした場合、以下の手順でアップデートする。
管理者権限でPowerShellを起動
Stop-Service docker
winget update --scope machine -ei --id Docker.DockerCLI
winget update --scope machine -ei --id Docker.DockerCompose
Start-Service docker