Using docker multi-stage to build windows images

Hello everyone! My name is Andrey, and I work as a DevOps engineer at Exness on the development team. My main activity is related to the assembly, deployment and support of applications in docker under the Linux operating system (hereinafter referred to as the OS). Not so long ago, I had a task with the same activities, but Windows Server and a set of C ++ projects became the target OS of the project. For me, this was the first close interaction with docker containers under Windows and in general with C ++ applications. Thanks to this, I gained interesting experience and learned about some of the intricacies of containerizing applications on Windows.



In this article I want to tell you what difficulties I had to face, how they were solved. I hope this will be useful for solving your current and future tasks. Enjoy reading!


Why containers?


Hashicorp Nomad — Consul Vault. . docker- Windows Server Core 1803 1809, docker- 1803 1809. 1803 , docker- docker- , . 1809 . .


multi-stage?


, , , toolset workload Visual Studio. — docker-. dockerfile .



docker multi-stage dockerfile , . , , docker- . , docker cache, .


dockerfile .


dockerfile , , .


Microsoft Windows Server .

ARG WINDOWS_OS_VERSION=1809
FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

RUN dockerfile Windows cmd.exe. Powershell SHELL.


SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

chocolatey :


COPY chocolatey.pkg.config .
RUN Set-ExecutionPolicy Bypass -Scope Process -Force ;\
    [System.Net.ServicePointManager]::SecurityProtocol = \
    [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 ;\
    $env:chocolateyUseWindowsCompression = 'true' ;\
    iex ((New-Object System.Net.WebClient).DownloadString( \
      'https://chocolatey.org/install.ps1')) ;\
    choco install chocolatey.pkg.config -y --ignore-detected-reboot ;\
    if ( @(0, 1605, 1614, 1641, 3010) -contains $LASTEXITCODE ) { \
      refreshenv; } else { exit $LASTEXITCODE; } ;\
    Remove-Item 'chocolatey.pkg.config'

, chocolatey, , . XML, . :


<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="python" version="3.8.2"/>
  <package id="nuget.commandline" version="5.5.1"/>
  <package id="git" version="2.26.2"/>
</packages>

, , MS Build Tools 2019 — Visual Studio 2019, .
C++ , :


  • Workload C++ tools
  • Toolset v141
  • Windows 10 SDK (10.0.17134.0)

JSON. :


Microsoft Visual Studio.

{
  "version": "1.0",
  "components": [
    "Microsoft.Component.MSBuild",
    "Microsoft.VisualStudio.Workload.VCTools;includeRecommended",
    "Microsoft.VisualStudio.Component.VC.v141.x86.x64",
    "Microsoft.VisualStudio.Component.Windows10SDK.17134"
  ]
}

dockerfile , build tools PATH. , .


COPY buildtools.config.json .
RUN Invoke-WebRequest 'https://aka.ms/vs/16/release/vs_BuildTools.exe' \
      -OutFile '.\vs_buildtools.exe' -UseBasicParsing ;\
    Start-Process -FilePath '.\vs_buildtools.exe' -Wait -ArgumentList \
      '--quiet --norestart --nocache --config C:\buildtools.config.json' ;\
    Remove-Item '.\vs_buildtools.exe' ;\
    Remove-Item '.\buildtools.config.json' ;\
    Remove-Item -Force -Recurse \
      'C:\Program Files (x86)\Microsoft Visual Studio\Installer' ;\
    $env:PATH = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin;' + $env:PATH; \
    [Environment]::SetEnvironmentVariable('PATH', $env:PATH, \
      [EnvironmentVariableTarget]::Machine)

C++ , docker multi-stage .


Multi-stage


. dockerfile , / . as builder FROM.


ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

. : , , .


COPY myapp .
RUN nuget restore myapp.sln ;\
    msbuild myapp.sln /t:myapp /p:Configuration=Release

— , . --from=builder COPY.


FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

COPY --from=builder C:/x64/Release/myapp/ ./
COPY ./configs ./

ENTRYPOINT CMD.



, C++ Windows , docker multi-stage .


All Articles