CD 등을 위해 Rust 빌드 환경을 Docker Hub의 공식 Rust 이미지를 기반으로 하여 자주 구성하는데, 공식 이미지는 Linux 컨테이너만 지원하기 때문에 Windows 기반의 빌드 환경을 샌드박싱하기 어려웠다. 이번 포스트에서는 Windows Docker Image 기반으로 Rust 빌드 환경을 구성하는 법을 다룰 것이다.

참고한 문서 목록

Dockerfile

# escape=`
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-20H2

WORKDIR C:\\build
RUN `
    # Download the Build Tools bootstrapper.
    curl -SL --output vs_buildtools.exe https://aka.ms/vs/17/release/vs_buildtools.exe `
    `
    # Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
    && (start /w vs_buildtools.exe --quiet --wait --norestart --nocache modify `
    --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" `
    --add Microsoft.VisualStudio.Workload.VCTools `
    --add Microsoft.VisualStudio.Component.CoreBuildTools `
    --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
    --add Microsoft.VisualStudio.Component.VC.CoreBuildTools `
    --add Microsoft.VisualStudio.Component.Windows10SDK.19041 `
    || IF "%ERRORLEVEL%"=="3010" EXIT 0) `
    `
    # Cleanup
    && del /q vs_buildtools.exe

RUN `
    powershell -Command "(Invoke-WebRequest -OutFile rustup-init.exe https://win.rustup.rs/x86_64) `
    ; (./rustup-init.exe --default-toolchain nightly-2022-02-20 -y --profile minimal) `
    ; rm ./rustup-init.exe"

RUN mkdir C:\\mount

COPY build_isolated.ps1 .

ENTRYPOINT [ "powershell", "-Command", "./build_isolated.ps1" ]

build-isolated.ps1

$mnt = $args[0].Trim()
Copy-Item $mnt/* . -Recurse -Force -Exclude $mnt/target
cargo build --release --features windows_subsystem
Copy-Item target/release/<crate-name>.exe $mnt/output.exe
echo Done

Gotchas

  • Docker Desktop의 기본 설정은 WSL2인데 여기서는 리눅스 이미지만 사용할 수 있다. Windows 컨테이너를 사용할 수 있도록 Hyper-V 백엔드로 바꿔야 한다.
  • 내가 사용하는 Host OS는 Windows 10 21H2(빌드 19044)인데, 여기서는 ltsc2022 이미지를 실행할 수 없었다. Windows 11로 업그레이드할 때까지만 임시로 20H2 이미지를 사용하기로 했다.
  • vs_buildtools.exe는 .NET 프레임워크를 필요로 하는 것으로 보인다. (확실하지 않음). Windows Server Core와 같은 이미지에서는 잘 작동하지 않았다.
  • Windows 10 SDK와 Core Build Tools가 있어야 rustclink.exe 링커를 사용할 수 있다.
  • 기본 상태에서는 Hyper-V 이미지가 2개의 CPU 코어만 사용하는 것으로 보인다. Issue #1877 수동으로 --cpu-count 옵션을 주면 해결된다.