Docker upgrade on WIN server
Upgrade Docker engine
You have two options how to upgrade docker engine. "Docker engine as a service" (A), "Docker engine triggered by scheduled task" (B)
Before upgrading docker engine stop all running containers by docker-compose down command from project directory.
A) Docker engine as a service
Best practise is to use docker engine as a service. Here are steps how to create new service:
Work in cmd as administator
In all commands replace "_$version_number" with real number of installed docker, e.g. path to docker binaries: C:\Program Files\Docker$version_number
You can follow steps below or use script which does the work:
Loading files from: /documents/installation/files.json
Directory: /documents/installation
Example of how to run the script.:
.\Install-DockerEngine.ps1 -DockerVersion "29.1.5" -ComposeVersion "5.0.2"
Steps to upgrade Docker engine
- Download binaries files with version that you want from web and unzip to host server to "C:\Program Files\Docker$version_number". You should have unzipped "docker.exe" and "dockerd.exe" files.
- Create data folder for new service:
mkdir "C:\ProgramData\Docker_$version_number"mkdir "C:\ProgramData\Docker_$version_number\exec"
- Register new service:
sc.exe create "Docker-_$version_number" binPath= "\"C:\Program Files\Docker\_$version_number\dockerd.exe\" --run-service --data-root=\"C:\ProgramData\Docker__$version_number\" --exec-root=\"C:\ProgramData\Docker__$version_number\exec\"" DisplayName= "Docker Engine _$version_number" start= demand
- Check service:
sc.exe qc Docker-_$version_number
- Stop old docker service in "Services" manager
- Start new service:
sc.exe start Docker-_$version_number
- Change environment variable in PATH to new folder with docker binaries, should be
C:\Program Files\Docker\$version_number
If steps above crashes with any error (1053/SCM timeout) - mainly on Windows servers 2019 - and you won't be able to run newly registered service you need to follow backup plan (option B)
B) Docker engine triggered by scheduled task
Steps 1 and 2 are same as in A) option.
- Create ps1 script in "C:\Program Files\Docker_$version_number\start-dockerd-_$version_number.ps1" with this content:
$ErrorActionPreference = 'Stop'$dockerd = 'C:\Program Files\Docker\$version_number\dockerd.exe'$dataRoot = 'C:\ProgramData\Docker_$version_number'$execRoot = 'C:\ProgramData\Docker_$version_number\exec'# "Header" log (human-readable), only launcher start/stop$logHeader = 'C:\ProgramData\Docker_$version_number\dockerd.log'# Dockerd stdout (daemon log)/stderr logs$logOut = 'C:\ProgramData\Docker_$version_number\dockerd.out.log'$logErr = 'C:\ProgramData\Docker_$version_number\dockerd.err.log'New-Item -ItemType Directory -Force -Path $dataRoot | Out-NullNew-Item -ItemType Directory -Force -Path $execRoot | Out-Null"==================================================" | Out-File -FilePath $logHeader -Append -Encoding ascii"start-dockerd-29.ps1 start: $(Get-Date -Format s)" | Out-File -FilePath $logHeader -Append -Encoding ascii"Computer: $env:COMPUTERNAME" | Out-File -FilePath $logHeader -Append -Encoding ascii"User: $env:USERNAME" | Out-File -FilePath $logHeader -Append -Encoding ascii"DataRoot: $dataRoot" | Out-File -FilePath $logHeader -Append -Encoding ascii"ExecRoot: $execRoot" | Out-File -FilePath $logHeader -Append -Encoding ascii"Stdout: $logOut" | Out-File -FilePath $logHeader -Append -Encoding ascii"Stderr: $logErr" | Out-File -FilePath $logHeader -Append -Encoding ascii"==================================================" | Out-File -FilePath $logHeader -Append -Encoding ascii# Guard: if dockerd already runs, do nothing$existing = Get-CimInstance Win32_Process -Filter "Name='dockerd.exe'" -ErrorAction SilentlyContinueif ($existing) {"dockerd already running (PID(s): $($existing.ProcessId -join ',')); exiting." |Out-File -FilePath $logHeader -Append -Encoding asciiexit 0}$args = @('--debug','--log-level', 'debug','--data-root', $dataRoot,'--exec-root', $execRoot)# Clean old stderr file (stdout can be overwritten; that's fine)if (Test-Path $logErr) { Remove-Item -Force $logErr -ErrorAction SilentlyContinue }# IMPORTANT: redirect into separate files so header isn't truncatedStart-Process -FilePath $dockerd -ArgumentList $args -NoNewWindow `-RedirectStandardOutput $logOut -RedirectStandardError $logErr"dockerd started." | Out-File -FilePath $logHeader -Append -Encoding ascii# wait up to 60s for default pipe$deadline = (Get-Date).AddSeconds(60)while ((Get-Date) -lt $deadline) {if (Test-Path "\\.\pipe\docker_engine") { break }Start-Sleep -Milliseconds 500}if (-not (Test-Path "\\.\pipe\docker_engine")) {"WARNING: docker_engine pipe not available after 60s" | Out-File -FilePath $logHeader -Append -Encoding ascii} else {"OK: docker_engine pipe is available" | Out-File -FilePath $logHeader -Append -Encoding ascii}
- Create task which triggers script above after Windows startup:
schtasks /Create /TN "Docker Engine $version_number" /SC ONSTART /RU "SYSTEM" /RL HIGHEST /F /TR "\"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe\" -NoProfile -ExecutionPolicy Bypass -File \"C:\Program Files\Docker\$version_number\start-dockerd-$version_number.ps1\""
- Kill previous instances of runnig dockerd:
taskkill /F /IM dockerd.exe
- Run task to check.
schtasks /Run /TN "Docker Engine $version_number"` and check if dockerd is runnig: `tasklist /fi "imagename eq dockerd.exe"
Upgrade Docker-compose plugin
- Create folder in "Docker" directory:
mkdir "C:\Program Files\Docker\$version_number\cli-plugins"
- Download "docker-compose" binary file:
$ver = "v5.0.2"Start-BitsTransfer `-Source "https://github.com/docker/compose/releases/download/$ver/docker-compose-windows-x86_64.exe" `-Destination "$Env:ProgramFiles\Docker\$version_number\cli-plugins\docker-compose.exe"
- Set environment variable in PATH to folder with "cli_plugins"
- Test plugin:
docker-compose version
- you should see correct version number of plugin
Clean environment
After successfull installation of new Docker engine service you have to delete (or disable) previous service and clean remains.
- Delete previous Docker service:
sc.exe delete Docker
- you should get message:
[SC] DeleteService SUCCESS
- you should get message:
- Delete environment variable in PATH for previous Docker folder
- Delete data folder for previous Docker service (typically: C:\ProgramData\docker)
- Delete folder with binaries for previous Docker service