Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion helpful_tools/Install-DockerCE/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#### SYNTAX
install-docker-ce.ps1 [-DockerPath <String>] [-DockerDPath <String>] [-DockerVersion <String>] [-ContainerBaseImage <String>] [-ExternalNetAdapter <String>]
[-Force] [-HyperV] [-SkipDefaultHost] [-NATSubnet <String>] [-NoRestart] [-PSDirect] [-Staging]
[-UseDHCP] [-WimPath <String>] [-TarPath] [<CommonParameters>]
[-UseDHCP] [-WimPath <String>] [-TarPath] [-Update] [<CommonParameters>]


#### DESCRIPTION
Expand Down Expand Up @@ -131,6 +131,15 @@
Default value
Accept pipeline input? false
Accept wildcard characters? false

-Update [<SwitchParameter>]
If passed, allows updating an existing Docker installation while preserving daemon.json configuration.

Required? false
Position? named
Default value False
Accept pipeline input? false
Accept wildcard characters? false

#### NOTES
Copyright (c) Microsoft Corporation. All rights reserved.
Expand All @@ -147,5 +156,8 @@

PS C:\>.\install-docker-ce.ps1

PS C:\>.\install-docker-ce.ps1 -Update
Updates an existing Docker installation while preserving daemon.json configuration

#### Prerequisites
Requires PowerShell version 5.0
162 changes: 157 additions & 5 deletions helpful_tools/Install-DockerCE/install-docker-ce.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
.PARAMETER TarPath
Path to the .tar that is the base image to load into Docker.

.PARAMETER Update
If passed, allows updating an existing Docker installation while preserving daemon.json configuration.

.EXAMPLE
.\install-docker-ce.ps1

Expand Down Expand Up @@ -110,7 +113,10 @@ param(

[string]
[ValidateNotNullOrEmpty()]
$TarPath
$TarPath,

[switch]
$Update
)

$global:RebootRequired = $false
Expand Down Expand Up @@ -330,7 +336,73 @@ Install-ContainerHost
#
if (Test-Docker)
{
Write-Output "Docker is already installed."
if ($Update)
{
Write-Output "Docker is already installed. Updating Docker..."

# Backup existing configuration
$configBackedUp = Backup-DockerConfig

# Stop and remove existing Docker service for update
Write-Output "Stopping Docker service for update..."
try { Stop-Docker } catch { Write-Output "Docker service was not running" }

Write-Output "Unregistering Docker service for update..."
try
{
& dockerd --unregister-service --service-name $global:DockerServiceName
if ($LASTEXITCODE -ne 0)
{
Write-Warning "Failed to unregister Docker service (exit code: $LASTEXITCODE). Proceeding with update..."
}
}
catch
{
Write-Warning "Error unregistering Docker service: $($_.Exception.Message). Proceeding with update..."
}

# Install updated Docker version
try
{
if ($NATSubnet)
{
Install-Docker -DockerPath $DockerPath -DockerDPath $DockerDPath -NATSubnet $NATSubnet -ContainerBaseImage $ContainerBaseImage -Update
}
else
{
Install-Docker -DockerPath $DockerPath -DockerDPath $DockerDPath -ContainerBaseImage $ContainerBaseImage -Update
}
}
catch
{
Write-Error "Failed to install Docker update: $($_.Exception.Message)"

# Attempt to restore configuration if backup exists
if ($configBackedUp)
{
Write-Output "Attempting to restore configuration after failed update..."
Restore-DockerConfig
}
throw
}

# The Install-Docker function already starts Docker with preserved config
# Additional restore is not needed unless Install-Docker failed to preserve config
if ($configBackedUp)
{
# Clean up backup file since configuration was preserved during install
$dockerConfigPath = Join-Path $global:DockerDataPath "config"
$backupFile = Join-Path $dockerConfigPath "daemon.json.backup"
if (Test-Path $backupFile)
{
Remove-Item -Path $backupFile -Force -ErrorAction SilentlyContinue
}
}
}
else
{
Write-Output "Docker is already installed."
}
}
else
{
Expand Down Expand Up @@ -569,6 +641,73 @@ Wait-Network()
}


function
Backup-DockerConfig()
{
$dockerConfigPath = Join-Path $global:DockerDataPath "config"
$daemonSettingsFile = Join-Path $dockerConfigPath "daemon.json"
$backupFile = "$daemonSettingsFile.backup"

if (Test-Path $daemonSettingsFile)
{
Write-Output "Backing up existing Docker daemon configuration..."
try
{
# Validate that the daemon.json file is readable and appears to be valid JSON
$configContent = Get-Content -Path $daemonSettingsFile -Raw -ErrorAction Stop
if ($configContent -and $configContent.Trim().StartsWith('{'))
{
Copy-Item -Path $daemonSettingsFile -Destination $backupFile -Force -ErrorAction Stop
Write-Output "Docker configuration backed up successfully."
return $true
}
else
{
Write-Warning "Existing daemon.json appears to be empty or invalid. Skipping backup."
return $false
}
}
catch
{
Write-Warning "Failed to backup Docker configuration: $($_.Exception.Message)"
return $false
}
}

Write-Output "No existing Docker daemon configuration found to backup."
return $false
}


function
Restore-DockerConfig()
{
$dockerConfigPath = Join-Path $global:DockerDataPath "config"
$daemonSettingsFile = Join-Path $dockerConfigPath "daemon.json"
$backupFile = "$daemonSettingsFile.backup"

if (Test-Path $backupFile)
{
Write-Output "Restoring Docker daemon configuration..."
try
{
Copy-Item -Path $backupFile -Destination $daemonSettingsFile -Force -ErrorAction Stop
Remove-Item -Path $backupFile -Force -ErrorAction Stop
Write-Output "Docker configuration restored successfully."
return $true
}
catch
{
Write-Warning "Failed to restore Docker configuration: $($_.Exception.Message)"
return $false
}
}

Write-Output "No backup configuration found to restore."
return $false
}


function
Install-Docker()
{
Expand All @@ -590,7 +729,10 @@ Install-Docker()
$SkipDefaultHost,

[string]
$ContainerBaseImage
$ContainerBaseImage,

[switch]
$Update
)

Test-Admin
Expand Down Expand Up @@ -682,8 +824,18 @@ Install-Docker()
}

$daemonSettingsFile = Join-Path $dockerConfigPath "daemon.json"

$daemonSettings | ConvertTo-Json | Out-File -FilePath $daemonSettingsFile -Encoding ASCII

# Handle daemon.json configuration
if ($Update -and (Test-Path $daemonSettingsFile))
{
Write-Output "Update mode: preserving existing daemon.json configuration"
# In update mode, keep the existing daemon.json file
}
else
{
# Create new daemon.json configuration (fresh install or no existing config)
$daemonSettings | ConvertTo-Json | Out-File -FilePath $daemonSettingsFile -Encoding ASCII
}

& dockerd --register-service --service-name $global:DockerServiceName

Expand Down