Thursday 25 April 2024

Installing Mising Fonts in windowsservercore-ltsc2022 Docker Image Using Azure Pipelines with az acr build

 The missing fonts in windowsservercore-ltsc2022  docker images can be installed as described in the blog post here. However, when we are not using hosted agents, and when we use kubernetes based self hosted build agents, we do not have access to host machine, to perform the all steps described in the post "Adding optional font packages to Windows containers". Since docker is not supported on self hosted build agent running as container in AKS, we have to use az acr build to build the docker images in such cases. To setup fonts in this kind of a situation in a Azure DevOps pipeline we can take the steps described in this post.

The expected outcome is building docker file with az acr build successfully installing fonts in windowsservercore-ltsc2022  image as shown below.


As suggested in the first comment of the the blog post here we are having to install the fonts using PowerShell commands, by downloading the required fonts from a predefined storage blob. To obtain the fonts for Windows Server 2022, we can setup a VM in Azure with Windows Server 2022, and copy all fonts from the fonts folder c:\windows\fonts to a folder. Then make a zip file of it. We have to make sure, when we extract the zip file it always extract all fonts to the defined folder path root. To ensure this, go to folder where all fonts are copied to and select all files (Cntrl+A), then right click and send to zipped folder. Then take the zip file and rename it as winsvr2022fonts.zip. We should uplod this to a public anonymous access enabled (else you have to ensure Azure devops service connection SPN has blob read access) blob as shown below.


The first step to perform in the pipeline is downloading the zip file from blob and extract it to repo root. We can use below PowerShell task for that in the pipeline.

- task: PowerShell@2
  name: setup_blue_green_controls_vars
  displayName: 'Download and extract Windows server 2022 fonts'
  inputs:
    failOnStderr: true
    targetType: 'inline'
    script: |
      $fontsZipFile = 'winsvr2022fonts.zip';
      Invoke-WebRequest https://mystorageacctname.blob.core.windows.net/winsvr2022-fonts/winsvr2022fonts.zip -outfile $fontsZipFile -UseBasicParsing;
      
      dir
      
      Expand-Archive -Path $fontsZipFile -DestinationPath winsvr2022fonts
      
      cd winsvr2022fonts
      dir


This task shows the fonts are downloaded in the build agent as shown below.



The below script copied and slightly modified from the script mentioned in this GitHub gist can be used in the docker file to install the fonts.

$fontSourceFolder = 'c:\winsvr2022fonts';
$SystemFontsPath = 'c:\windows\fonts\';

foreach($FontFile in Get-ChildItem $fontSourceFolder -Include '*.ttf','*.ttc','*.otf','*.fon' -recurse )
{
    $targetPath = Join-Path $SystemFontsPath $FontFile.Name
	if(Test-Path -Path $targetPath){
		$FontFile.Name + " already installed"
	}
	else {
		"Installing font " + $FontFile.Name
		
		$ShellFolder = (New-Object -COMObject Shell.Application).Namespace($fontSourceFolder)
		$ShellFile = $ShellFolder.ParseName($FontFile.name)
		$ShellFileType = $ShellFolder.GetDetailsOf($ShellFile, 2)

		$FontType = '';
		If ($ShellFileType -Like '*TrueType font file*') {$FontType = '(TrueType)'}
			
		$RegName = $ShellFolder.GetDetailsOf($ShellFile, 21) + ' ' + $FontType

                New-ItemProperty -Name $RegName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -PropertyType string -Value $FontFile.name -Force | out-null
		Copy-item $FontFile.FullName -Destination $SystemFontsPath
		"Installed " + $FontFile.Name
	}
}


Then we can enable installing all windows fonts in the base image as shown in the below docker file. We need to copy the fonts downloaded to build agent and the script to install fonts to the container. Then we can run the script to get the fonts installed to the docker container.

FROM mcr.microsoft.com/dotnet/runtime:8.0-windowsservercore-ltsc2022 AS base

COPY ["winsvr2022fonts", "winsvr2022fonts/"]
COPY ["pipelines/scripts/install_windows_fonts.ps1", ""]

RUN dir

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; $verbosePreference='Continue';"]
RUN ./install_windows_fonts.ps1

RUN remove-item -Path ./install_windows_fonts.ps1 -Force
RUN remove-item -Path winsvr2022fonts -Recurse -Force
RUN dir

SHELL ["cmd"]

FROM mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2022 AS build
WORKDIR /src

... 

We are building the docker image using below pipeline task.

- task: AzureCLI@2
  displayName: 'Build and push'
  retryCountOnTaskFailure: 2
  inputs:
    azureSubscription: 'MyServiceConnection'
    scriptType: ps
    scriptLocation: inlineScript
    inlineScript: |
      az account set --subscription $(mysubscription)
      az acr build --platform ${{ variables.container_platform }} --registry $(aks_shared_container_registry) --image $(aks_shared_container_registry).azurecr.io/avalanche/$(aks_app_name):$(Build.BuildId) --file '$(project_path)/Dockerfile' $(Build.Repository.LocalPath)










No comments:

Popular Posts