Skip to content

Commit

Permalink
[TW-84247] Windows-based Docker images: migrate from Windows 2004 to …
Browse files Browse the repository at this point in the history
…Windows 2022 (#117)

* Implement Windows 2022-based TeamCity Docker Images: Server, Agent (minimal / regular);
* Implement Dockerfiles, along with the mandatory changes within Dockerfiles generator;
* Add automation for the build process of Windows 2022-based DOcker Images;
* Add backslash for JAVA_HOME path, replacing forward slash.
  • Loading branch information
AndreyKoltsov1997 authored Nov 21, 2023
1 parent 5d98a0e commit e01a2c1
Show file tree
Hide file tree
Showing 42 changed files with 582 additions and 109 deletions.
2 changes: 1 addition & 1 deletion checks/windows-dotnet/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '2'
services:
teamcity-server:
image: teamcity-server:local-nanoserver-2004
image: teamcity-server:local-nanoserver-2022
ports:
- "8112:8111"

Expand Down
8 changes: 4 additions & 4 deletions checks/windows-jetbrains/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
version: '2'
services:
teamcity-server:
image: registry.jetbrains.team/teamcity/teamcity-server:EAP-nanoserver-2004
image: registry.jetbrains.team/teamcity/teamcity-server:EAP-nanoserver-2022
ports:
- "8112:8111"

teamcity-minimal-agent:
image: registry.jetbrains.team/teamcity/teamcity-minimal-agent:EAP-nanoserver-2004
image: registry.jetbrains.team/teamcity/teamcity-minimal-agent:EAP-nanoserver-2022
environment:
- SERVER_URL=teamcity-server:8111

teamcity-agent:
image: registry.jetbrains.team/teamcity/teamcity-agent:EAP-nanoserver-2004
image: registry.jetbrains.team/teamcity/teamcity-agent:EAP-nanoserver-2022
environment:
- SERVER_URL=teamcity-server:8111

teamcity-core-agent:
image: registry.jetbrains.team/teamcity/teamcity-agent:EAP-windowsservercore-2004
image: registry.jetbrains.team/teamcity/teamcity-agent:EAP-windowsservercore-2022
environment:
- SERVER_URL=teamcity-server:8111
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
windowsBuild=2004
windowsBuild=2022
tag=nanoserver-${windowsBuild}
repo=https://hub.docker.com/r/jetbrains/
# https://hub.docker.com/_/microsoft-powershell
powershellImage=mcr.microsoft.com/powershell:nanoserver-${windowsBuild}
powershellImage=mcr.microsoft.com/powershell:nanoserver-ltsc${windowsBuild}
# https://hub.docker.com/_/microsoft-windows-nanoserver
nanoserverImage=mcr.microsoft.com/windows/nanoserver:${windowsBuild}
nanoserverImage=mcr.microsoft.com/windows/nanoserver:ltsc${windowsBuild}
teamcityWindowsservercoreImage=teamcity-agent:${versionTag}-windowsservercore-${windowsBuild}
2 changes: 1 addition & 1 deletion configs/windows/Agent/nanoserver/NanoServer1803.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ VOLUME C:/BuildAgent/conf
CMD ["pwsh", "./BuildAgent/run-agent.ps1"]

# Configuration file for TeamCity agent
ENV CONFIG_FILE="C:/BuildAgent/conf/buildAgent.properties" \
ENV CONFIG_FILE="C:\BuildAgent\conf\buildAgent.properties" \
# Java home directory
JAVA_HOME="C:\Program Files\Java\OpenJDK" \
# Opt out of the telemetry feature
Expand Down
2 changes: 1 addition & 1 deletion configs/windows/Agent/nanoserver/NanoServer1809.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ EXPOSE 9090
VOLUME C:/BuildAgent/conf

# Configuration file for TeamCity agent
ENV CONFIG_FILE="C:/BuildAgent/conf/buildAgent.properties" \
ENV CONFIG_FILE="C:\BuildAgent\conf\buildAgent.properties" \
# Java home directory
JAVA_HOME="C:\Program Files\Java\OpenJDK" \
# Opt out of the telemetry feature
Expand Down
102 changes: 102 additions & 0 deletions configs/windows/Agent/nanoserver/NanoServer2022.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# The list of required arguments
# ARG nanoserverImage
# ARG powershellImage
# ARG teamcityWindowsservercoreImage

# Id teamcity-agent
# Tag ${versionTag}-${tag}
# Tag ${latestTag}
# Tag ${versionTag}
# Platform ${windowsPlatform}
# Repo ${repo}
# Weight 2

## ${agentCommentHeader}

# @AddToolToDoc [${jdkWindowsComponentName}](${jdkWindowsComponent})
# @AddToolToDoc ${powerShellComponentName}
# @AddToolToDoc [${gitWindowsComponentName}](${gitWindowsComponent})
# @AddToolToDoc [${dotnetWindowsComponentName}](${dotnetWindowsComponent})

# Based on ${powershellImage} 3
FROM ${powershellImage} AS dotnet

# On some agents, Windows 2022 requires administrator permissions to modify "C:/" folder within ...
# ... PowerShell container.
USER ContainerAdministrator

COPY scripts/*.cs /scripts/
SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

# Based on ${teamcityWindowsservercoreImage}
ARG teamcityWindowsservercoreImage
FROM ${teamcityWindowsservercoreImage} AS tools

# Workaround for https://github.com/PowerShell/PowerShell-Docker/issues/164
ARG nanoserverImage
# Based on ${nanoserverImage} 2
FROM ${nanoserverImage}

ENV ProgramFiles="C:\Program Files" \
# set a fixed location for the Module analysis cache
PSModuleAnalysisCachePath="C:\Users\ContainerUser\AppData\Local\Microsoft\Windows\PowerShell\docker\ModuleAnalysisCache" \
# Persist %PSCORE% ENV variable for user convenience
PSCORE="$ProgramFiles\PowerShell\pwsh.exe"

# PowerShell
COPY --from=dotnet ["C:/Program Files/PowerShell", "C:/Program Files/PowerShell"]

# In order to set system PATH, ContainerAdministrator must be used
USER ContainerAdministrator
RUN setx /M PATH "%PATH%;%ProgramFiles%\PowerShell"
USER ContainerUser

# intialize powershell module cache
RUN pwsh -NoLogo -NoProfile -Command " \
$stopTime = (get-date).AddMinutes(15); \
$ErrorActionPreference = 'Stop' ; \
$ProgressPreference = 'SilentlyContinue' ; \
while(!(Test-Path -Path $env:PSModuleAnalysisCachePath)) { \
Write-Host "'Waiting for $env:PSModuleAnalysisCachePath'" ; \
if((get-date) -gt $stopTime) { throw 'timout expired'} \
Start-Sleep -Seconds 6 ; \
}"

# JDK
COPY --from=tools ["C:/Program Files/Java/OpenJDK", "C:/Program Files/Java/OpenJDK"]
# Git
COPY --from=tools ["C:/Program Files/Git", "C:/Program Files/Git"]
# .NET
COPY --from=tools ["C:/Program Files/dotnet", "C:/Program Files/dotnet"]
COPY --from=tools /BuildAgent /BuildAgent

EXPOSE 9090

VOLUME C:/BuildAgent/conf

# Configuration file for TeamCity agent
ENV CONFIG_FILE="C:\BuildAgent\conf\buildAgent.properties" \
# Java home directory
JAVA_HOME="C:\Program Files\Java\OpenJDK" \
# Opt out of the telemetry feature
DOTNET_CLI_TELEMETRY_OPTOUT=true \
# Disable first time experience
DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true \
# Configure Kestrel web server to bind to port 80 when present
ASPNETCORE_URLS=http://+:80 \
# Enable detection of running in a container
DOTNET_RUNNING_IN_CONTAINER=true \
# Enable correct mode for dotnet watch (only mode supported in a container)
DOTNET_USE_POLLING_FILE_WATCHER=true \
# Skip extraction of XML docs - generally not useful within an image/container - helps perfomance
NUGET_XMLDOC_MODE=skip

# In order to set system PATH, ContainerAdministrator must be used
USER ContainerAdministrator
RUN setx /M PATH "%PATH%;%JAVA_HOME%\bin;C:\Program Files\Git\cmd;C:\Program Files\dotnet"
USER ContainerUser

# Trigger first run experience by running arbitrary cmd to populate local package cache
RUN dotnet help

CMD ["pwsh", "./BuildAgent/run-agent.ps1"]
3 changes: 3 additions & 0 deletions configs/windows/Agent/nanoserver/NanoServer2022.Dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TeamCity/webapps
TeamCity/devPackage
TeamCity/lib
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
windowsBuild=2004
windowsBuild=2022
tag=windowsservercore-${windowsBuild}
repo=https://hub.docker.com/r/jetbrains/
# https://hub.docker.com/_/microsoft-dotnet-framework-sdk/
windowsservercoreImage=mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-${windowsBuild}
windowsservercoreImage=mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc${windowsBuild}
teamcityMinimalAgentImage=teamcity-minimal-agent:${versionTag}-nanoserver-${windowsBuild}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ RUN [Net.ServicePointManager]::SecurityProtocol = 'tls12, tls11, tls' ; \
Add-Type -IgnoreWarnings -TypeDefinition "$code" -Language CSharp ; \
$downloadScript = [Scripts.Web]::DownloadFiles($Env:jdkWindowsComponent + '#MD5#' + $Env:jdkWindowsComponentMD5SUM, 'jdk.zip', $Env:gitWindowsComponent + '#SHA256#' + $Env:gitWindowsComponentSHA256, 'git.zip', $Env:mercurialWindowsComponent, 'hg.msi', $Env:dotnetWindowsComponent + '#SHA512#' + $Env:dotnetWindowsComponentSHA512, 'dotnet.zip') ; \
Remove-Item -Force -Recurse $Env:ProgramFiles\dotnet; \
# .NET 6.0
# .NET 6.0, .NET Framework 4 is inherited from base image
Expand-Archive dotnet.zip -Force -DestinationPath $Env:ProgramFiles\dotnet; \
Remove-Item -Force dotnet.zip; \
Get-ChildItem -Path $Env:ProgramFiles\dotnet -Include *.lzma -File -Recurse | foreach { $_.Delete()}; \
Expand Down Expand Up @@ -82,7 +82,7 @@ VOLUME C:/BuildAgent/conf
CMD ["pwsh", "./BuildAgent/run-agent.ps1"]

# Configuration file for TeamCity agent
ENV CONFIG_FILE="C:/BuildAgent/conf/buildAgent.properties" \
ENV CONFIG_FILE="C:\BuildAgent\conf\buildAgent.properties" \
# Java home directory
JAVA_HOME="C:\Program Files\Java\OpenJDK" \
# Opt out of the telemetry feature
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# The list of required arguments
# ARG windowsservercoreImage
# ARG dotnetWindowsComponent
# ARG dotnetWindowsComponentSHA512
# ARG jdkWindowsComponent
# ARG jdkWindowsComponentMD5SUM
# ARG gitWindowsComponent
# ARG gitWindowsComponentSHA256
# ARG mercurialWindowsComponentName
# ARG teamcityMinimalAgentImage

# Id teamcity-agent
# Tag ${versionTag}-${tag}
# Tag ${versionTag}-windowsservercore
# Tag ${latestTag}-windowsservercore
# Platform ${windowsPlatform}
# Repo ${repo}
# Weight 16
# Requires teamcity.agent.jvm.os.name contains Windows 10

## ${agentCommentHeader}

# @AddToolToDoc [${jdkWindowsComponentName}](${jdkWindowsComponent})
# @AddToolToDoc [${gitWindowsComponentName}](${gitWindowsComponent})
# @AddToolToDoc ${powerShellComponentName}
# @AddToolToDoc [${mercurialWindowsComponentName}](${mercurialWindowsComponent})
# @AddToolToDoc [${dotnetWindowsComponentName}](${dotnetWindowsComponent})

# Based on ${teamcityMinimalAgentImage}
FROM ${teamcityMinimalAgentImage} AS buildagent

# Based on ${windowsservercoreImage} 12
ARG windowsservercoreImage
FROM ${windowsservercoreImage}

# On some agents, Windows 2022 requires administrator permissions to modify "C:/" folder within ...
# ... PowerShell container.
USER ContainerAdministrator

COPY scripts/*.cs /scripts/

# PowerShell
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ARG dotnetWindowsComponent
ARG dotnetWindowsComponentSHA512
ARG jdkWindowsComponent
ARG jdkWindowsComponentMD5SUM
ARG gitWindowsComponent
ARG gitWindowsComponentSHA256
ARG mercurialWindowsComponent

RUN [Net.ServicePointManager]::SecurityProtocol = 'tls12, tls11, tls' ; \
$code = Get-Content -Path "scripts/Web.cs" -Raw ; \
Add-Type -IgnoreWarnings -TypeDefinition "$code" -Language CSharp ; \
$downloadScript = [Scripts.Web]::DownloadFiles($Env:jdkWindowsComponent + '#MD5#' + $Env:jdkWindowsComponentMD5SUM, 'jdk.zip', $Env:gitWindowsComponent + '#SHA256#' + $Env:gitWindowsComponentSHA256, 'git.zip', $Env:mercurialWindowsComponent, 'hg.msi', $Env:dotnetWindowsComponent + '#SHA512#' + $Env:dotnetWindowsComponentSHA512, 'dotnet.zip') ; \
Remove-Item -Force -Recurse $Env:ProgramFiles\dotnet; \
# .NET 6.0, .NET Framework 4 is inherited from base image
Expand-Archive dotnet.zip -Force -DestinationPath $Env:ProgramFiles\dotnet; \
Remove-Item -Force dotnet.zip; \
Get-ChildItem -Path $Env:ProgramFiles\dotnet -Include *.lzma -File -Recurse | foreach { $_.Delete()}; \
# JDK
Expand-Archive jdk.zip -DestinationPath $Env:ProgramFiles\Java ; \
Get-ChildItem $Env:ProgramFiles\Java | Rename-Item -NewName "OpenJDK" ; \
Remove-Item $Env:ProgramFiles\Java\OpenJDK\lib\src.zip -Force ; \
Remove-Item -Force jdk.zip ; \
# Git
$gitPath = $Env:ProgramFiles + '\Git'; \
Expand-Archive git.zip -DestinationPath $gitPath ; \
Remove-Item -Force git.zip ; \
# avoid circular dependencies in gitconfig
$gitConfigFile = $gitPath + '\etc\gitconfig'; \
$configContent = Get-Content $gitConfigFile; \
$configContent = $configContent.Replace('path = C:/Program Files/Git/etc/gitconfig', ''); \
Set-Content $gitConfigFile $configContent; \
# Mercirual
Start-Process msiexec -Wait -ArgumentList /q, /i, hg.msi ; \
Remove-Item -Force hg.msi

COPY --from=buildagent /BuildAgent /BuildAgent

EXPOSE 9090

VOLUME C:/BuildAgent/conf

CMD ["pwsh", "./BuildAgent/run-agent.ps1"]

# Configuration file for TeamCity agent
ENV CONFIG_FILE="C:\BuildAgent\conf\buildAgent.properties" \
# Java home directory
JAVA_HOME="C:\Program Files\Java\OpenJDK" \
# Opt out of the telemetry feature
DOTNET_CLI_TELEMETRY_OPTOUT=true \
# Disable first time experience
DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true \
# Configure Kestrel web server to bind to port 80 when present
ASPNETCORE_URLS=http://+:80 \
# Enable detection of running in a container
DOTNET_RUNNING_IN_CONTAINER=true \
# Enable correct mode for dotnet watch (only mode supported in a container)
DOTNET_USE_POLLING_FILE_WATCHER=true \
# Skip extraction of XML docs - generally not useful within an image/container - helps perfomance
NUGET_XMLDOC_MODE=skip

USER ContainerAdministrator
RUN setx /M PATH ('{0};{1}\bin;C:\Program Files\Git\cmd;C:\Program Files\Mercurial' -f $env:PATH, $env:JAVA_HOME)
USER ContainerUser
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TeamCity/webapps
TeamCity/devPackage
TeamCity/lib
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
windowsBuild=2004
windowsBuild=2022
tag=nanoserver-${windowsBuild}
repo=https://hub.docker.com/r/jetbrains/
# https://hub.docker.com/_/microsoft-powershell
powershellImage=mcr.microsoft.com/powershell:nanoserver-${windowsBuild}
powershellImage=mcr.microsoft.com/powershell:nanoserver-ltsc${windowsBuild}
# https://hub.docker.com/_/microsoft-windows-nanoserver
nanoserverImage=mcr.microsoft.com/windows/nanoserver:${windowsBuild}
nanoserverImage=mcr.microsoft.com/windows/nanoserver:ltsc${windowsBuild}
Loading

0 comments on commit e01a2c1

Please sign in to comment.