1# escape=` 2 3# ----------------------------------------------------------------------------------------- 4# This file describes the standard way to build Docker in a container on Windows 5# Server 2016 or Windows 10. 6# 7# Maintainer: @jhowardmsft 8# ----------------------------------------------------------------------------------------- 9 10 11# Prerequisites: 12# -------------- 13# 14# 1. Windows Server 2016 or Windows 10 with all Windows updates applied. The major 15# build number must be at least 14393. This can be confirmed, for example, by 16# running the following from an elevated PowerShell prompt - this sample output 17# is from a fully up to date machine as at mid-November 2016: 18# 19# >> PS C:\> $(gin).WindowsBuildLabEx 20# >> 14393.447.amd64fre.rs1_release_inmarket.161102-0100 21# 22# 2. Git for Windows (or another git client) must be installed. https://git-scm.com/download/win. 23# 24# 3. The machine must be configured to run containers. For example, by following 25# the quick start guidance at https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start or 26# https://github.com/docker/labs/blob/master/windows/windows-containers/Setup.md 27# 28# 4. If building in a Hyper-V VM: For Windows Server 2016 using Windows Server 29# containers as the default option, it is recommended you have at least 1GB 30# of memory assigned; For Windows 10 where Hyper-V Containers are employed, you 31# should have at least 4GB of memory assigned. Note also, to run Hyper-V 32# containers in a VM, it is necessary to configure the VM for nested virtualization. 33 34# ----------------------------------------------------------------------------------------- 35 36 37# Usage: 38# ----- 39# 40# The following steps should be run from an (elevated*) Windows PowerShell prompt. 41# 42# (*In a default installation of containers on Windows following the quick-start guidance at 43# https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start, 44# the docker.exe client must run elevated to be able to connect to the daemon). 45# 46# 1. Clone the sources from github.com: 47# 48# >> git clone https://github.com/docker/docker.git C:\go\src\github.com\docker\docker 49# >> Cloning into 'C:\go\src\github.com\docker\docker'... 50# >> remote: Counting objects: 186216, done. 51# >> remote: Compressing objects: 100% (21/21), done. 52# >> remote: Total 186216 (delta 5), reused 0 (delta 0), pack-reused 186195 53# >> Receiving objects: 100% (186216/186216), 104.32 MiB | 8.18 MiB/s, done. 54# >> Resolving deltas: 100% (123139/123139), done. 55# >> Checking connectivity... done. 56# >> Checking out files: 100% (3912/3912), done. 57# >> PS C:\> 58# 59# 60# 2. Change directory to the cloned docker sources: 61# 62# >> cd C:\go\src\github.com\docker\docker 63# 64# 65# 3. Build a docker image with the components required to build the docker binaries from source 66# by running one of the following: 67# 68# >> docker build -t nativebuildimage -f Dockerfile.windows . 69# >> docker build -t nativebuildimage -f Dockerfile.windows -m 2GB . (if using Hyper-V containers) 70# 71# 72# 4. Build the docker executable binaries by running one of the following: 73# 74# >> $DOCKER_GITCOMMIT=(git rev-parse --short HEAD) 75# >> docker run --name binaries -e DOCKER_GITCOMMIT=$DOCKER_GITCOMMIT nativebuildimage hack\make.ps1 -Binary 76# >> docker run --name binaries -e DOCKER_GITCOMMIT=$DOCKER_GITCOMMIT -m 2GB nativebuildimage hack\make.ps1 -Binary (if using Hyper-V containers) 77# 78# 79# 5. Copy the binaries out of the container, replacing HostPath with an appropriate destination 80# folder on the host system where you want the binaries to be located. 81# 82# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\docker.exe C:\HostPath\docker.exe 83# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\dockerd.exe C:\HostPath\dockerd.exe 84# 85# 86# 6. (Optional) Remove the interim container holding the built executable binaries: 87# 88# >> docker rm binaries 89# 90# 91# 7. (Optional) Remove the image used for the container in which the executable 92# binaries are build. Tip - it may be useful to keep this image around if you need to 93# build multiple times. Then you can take advantage of the builder cache to have an 94# image which has all the components required to build the binaries already installed. 95# 96# >> docker rmi nativebuildimage 97# 98 99# ----------------------------------------------------------------------------------------- 100 101 102# The validation tests can only run directly on the host. This is because they calculate 103# information from the git repo, but the .git directory is not passed into the image as 104# it is excluded via .dockerignore. Run the following from a Windows PowerShell prompt 105# (elevation is not required): (Note Go must be installed to run these tests) 106# 107# >> hack\make.ps1 -DCO -PkgImports -GoFormat 108 109 110# ----------------------------------------------------------------------------------------- 111 112 113# To run unit tests, ensure you have created the nativebuildimage above. Then run one of 114# the following from an (elevated) Windows PowerShell prompt: 115# 116# >> docker run --rm nativebuildimage hack\make.ps1 -TestUnit 117# >> docker run --rm -m 2GB nativebuildimage hack\make.ps1 -TestUnit (if using Hyper-V containers) 118 119 120# ----------------------------------------------------------------------------------------- 121 122 123# To run unit tests and binary build, ensure you have created the nativebuildimage above. Then 124# run one of the following from an (elevated) Windows PowerShell prompt: 125# 126# >> docker run nativebuildimage hack\make.ps1 -All 127# >> docker run -m 2GB nativebuildimage hack\make.ps1 -All (if using Hyper-V containers) 128 129# ----------------------------------------------------------------------------------------- 130 131 132# Important notes: 133# --------------- 134# 135# Don't attempt to use a bind mount to pass a local directory as the bundles target 136# directory. It does not work (golang attempts for follow a mapped folder incorrectly). 137# Instead, use docker cp as per the example. 138# 139# go.zip is not removed from the image as it is used by the Windows CI servers 140# to ensure the host and image are running consistent versions of go. 141# 142# Nanoserver support is a work in progress. Although the image will build if the 143# FROM statement is updated, it will not work when running autogen through hack\make.ps1. 144# It is suspected that the required GCC utilities (eg gcc, windres, windmc) silently 145# quit due to the use of console hooks which are not available. 146# 147# The docker integration tests do not currently run in a container on Windows, predominantly 148# due to Windows not supporting privileged mode, so anything using a volume would fail. 149# They (along with the rest of the docker CI suite) can be run using 150# https://github.com/jhowardmsft/docker-w2wCIScripts/blob/master/runCI/Invoke-DockerCI.ps1. 151# 152# ----------------------------------------------------------------------------------------- 153 154 155# The number of build steps below are explicitly minimised to improve performance. 156FROM microsoft/windowsservercore 157 158# Use PowerShell as the default shell 159SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] 160 161# Environment variable notes: 162# - GO_VERSION must be consistent with 'Dockerfile' used by Linux. 163# - FROM_DOCKERFILE is used for detection of building within a container. 164ENV GO_VERSION=1.10.8 ` 165 GIT_VERSION=2.11.1 ` 166 GOPATH=C:\go ` 167 FROM_DOCKERFILE=1 168 169RUN ` 170 Function Test-Nano() { ` 171 $EditionId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name 'EditionID').EditionId; ` 172 return (($EditionId -eq 'ServerStandardNano') -or ($EditionId -eq 'ServerDataCenterNano') -or ($EditionId -eq 'NanoServer')); ` 173 }` 174 ` 175 Function Download-File([string] $source, [string] $target) { ` 176 if (Test-Nano) { ` 177 $handler = New-Object System.Net.Http.HttpClientHandler; ` 178 $client = New-Object System.Net.Http.HttpClient($handler); ` 179 $client.Timeout = New-Object System.TimeSpan(0, 30, 0); ` 180 $cancelTokenSource = [System.Threading.CancellationTokenSource]::new(); ` 181 $responseMsg = $client.GetAsync([System.Uri]::new($source), $cancelTokenSource.Token); ` 182 $responseMsg.Wait(); ` 183 if (!$responseMsg.IsCanceled) { ` 184 $response = $responseMsg.Result; ` 185 if ($response.IsSuccessStatusCode) { ` 186 $downloadedFileStream = [System.IO.FileStream]::new($target, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write); ` 187 $copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream); ` 188 $copyStreamOp.Wait(); ` 189 $downloadedFileStream.Close(); ` 190 if ($copyStreamOp.Exception -ne $null) { throw $copyStreamOp.Exception } ` 191 } ` 192 } else { ` 193 Throw ("Failed to download " + $source) ` 194 }` 195 } else { ` 196 $webClient = New-Object System.Net.WebClient; ` 197 $webClient.DownloadFile($source, $target); ` 198 } ` 199 } ` 200 ` 201 setx /M PATH $('C:\git\cmd;C:\git\usr\bin;'+$Env:PATH+';C:\gcc\bin;C:\go\bin'); ` 202 ` 203 Write-Host INFO: Downloading git...; ` 204 $location='https://www.nuget.org/api/v2/package/GitForWindows/'+$Env:GIT_VERSION; ` 205 Download-File $location C:\gitsetup.zip; ` 206 ` 207 Write-Host INFO: Downloading go...; ` 208 Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION+'.windows-amd64.zip') C:\go.zip; ` 209 ` 210 Write-Host INFO: Downloading compiler 1 of 3...; ` 211 Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip C:\gcc.zip; ` 212 ` 213 Write-Host INFO: Downloading compiler 2 of 3...; ` 214 Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/runtime.zip C:\runtime.zip; ` 215 ` 216 Write-Host INFO: Downloading compiler 3 of 3...; ` 217 Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/binutils.zip C:\binutils.zip; ` 218 ` 219 Write-Host INFO: Extracting git...; ` 220 Expand-Archive C:\gitsetup.zip C:\git-tmp; ` 221 New-Item -Type Directory C:\git | Out-Null; ` 222 Move-Item C:\git-tmp\tools\* C:\git\.; ` 223 Remove-Item -Recurse -Force C:\git-tmp; ` 224 ` 225 Write-Host INFO: Expanding go...; ` 226 Expand-Archive C:\go.zip -DestinationPath C:\; ` 227 ` 228 Write-Host INFO: Expanding compiler 1 of 3...; ` 229 Expand-Archive C:\gcc.zip -DestinationPath C:\gcc -Force; ` 230 Write-Host INFO: Expanding compiler 2 of 3...; ` 231 Expand-Archive C:\runtime.zip -DestinationPath C:\gcc -Force; ` 232 Write-Host INFO: Expanding compiler 3 of 3...; ` 233 Expand-Archive C:\binutils.zip -DestinationPath C:\gcc -Force; ` 234 ` 235 Write-Host INFO: Removing downloaded files...; ` 236 Remove-Item C:\gcc.zip; ` 237 Remove-Item C:\runtime.zip; ` 238 Remove-Item C:\binutils.zip; ` 239 Remove-Item C:\gitsetup.zip; ` 240 ` 241 Write-Host INFO: Creating source directory...; ` 242 New-Item -ItemType Directory -Path C:\go\src\github.com\docker\docker | Out-Null; ` 243 ` 244 Write-Host INFO: Configuring git core.autocrlf...; ` 245 C:\git\cmd\git config --global core.autocrlf true; ` 246 ` 247 Write-Host INFO: Completed 248 249# Make PowerShell the default entrypoint 250ENTRYPOINT ["powershell.exe"] 251 252# Set the working directory to the location of the sources 253WORKDIR C:\go\src\github.com\docker\docker 254 255# Copy the sources into the container 256COPY . . 257