Skip to content

Instantly share code, notes, and snippets.

@jermdavis
Last active April 6, 2023 21:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jermdavis/6fb0a6e47d6f1342c089af4c04d29c35 to your computer and use it in GitHub Desktop.
Save jermdavis/6fb0a6e47d6f1342c089af4c04d29c35 to your computer and use it in GitHub Desktop.
A first pass at a script for installing Docker without using Docker Desktop
#Requires -RunAsAdministrator
param(
[string]$dockerEnginePath = "C:\",
[string]$dockerInstallPath = "C:\Docker",
[string]$dockerEngineUrl = "https://download.docker.com/win/static/stable/x86_64/docker-20.10.8.zip",
[string]$dockerZip = "docker.zip",
[string]$serviceName = "docker",
[string]$composeEngineUrl = "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Windows-x86_64.exe",
[string]$composeExe = "docker-compose.exe"
)
$ErrorActionPreference = "Stop"
function DownloadFile
{
param(
[string]$name,
[string]$downloadUrl,
[string]$output
)
if(-not(Test-Path $output))
{
Write-Host "Downloading $name file" -ForegroundColor Green
Invoke-WebRequest -Uri $downloadUrl -OutFile $output
}
else
{
Write-Host "$name already exists" -ForegroundColor Yellow
}
}
function StopAndRemoveExistingService
{
param(
[string]$svcName
)
$service = Get-Service | where { $_.Name -eq $svcName }
if($service.length -eq 0)
{
Write-Host "No existing service for $svcName" -ForegroundColor Green
}
else
{
$service | % {
Write-Host "Service '$($_.DisplayName)' exists" -ForegroundColor Yellow
if($_.Status -eq "Running")
{
Write-Host "$($_.Name) service is running" -ForegroundColor Yellow
$items = docker ps -q
if($items -ne $null)
{
popd
throw "Containers are running - stop them before running this script"
}
}
Write-Host "Removing service" -ForegroundColor Green
Stop-Service $_.Name
dockerd --unregister-service
}
}
}
function EnsureDockerInPath
{
param(
[string]$installPath
)
$path = [System.Environment]::GetEnvironmentVariable("Path","Machine")
if(-not($path.Contains($installPath)))
{
$newPath = "$($env:path);$($installPath)"
Write-Host "New path: $newPath" -ForegroundColor Green
[Environment]::SetEnvironmentVariable("Path", $newPath, [System.EnvironmentVariableTarget]::Machine)
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
}
else
{
Write-Host "Path is already correct" -ForegroundColor Yellow
}
}
function VerifyWindowsFeature
{
param(
[string]$featureName
)
$hasFeature = (Get-WindowsOptionalFeature -FeatureName $featureName -Online | Select -ExpandProperty State) -eq "Enabled"
if(-not $hasFeature)
{
Write-Host "$featureName feature not currently installed - adding" -ForegroundColor Yellow
$result = Enable-WindowsOptionalFeature -Online -FeatureName $featureName -NoRestart -All
return $result.RestartNeeded
}
else
{
Write-Host "$featureName feature is already installed" -ForegroundColor Green
return $false
}
}
function EnsureWindowsFeatures
{
$containersNeedsRestart = VerifyWindowsFeature "Containers"
$hyperVNeedsReboot = VerifyWindowsFeature "Microsoft-Hyper-V"
if($containersNeedsRestart -or $hyperVNeedsReboot)
{
popd
throw "Restart required after adding Windows features"
}
}
function EnsureDockerServiceRunning
{
param(
[string]$svcName
)
Write-Host "Registering & starting $svcName service" -ForegroundColor Green
dockerd --register-service
Start-Service $svcName
}
# Make sure Hyper-V etc is installed
EnsureWindowsFeatures
# Go to this user's downloads folder
pushd $(New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
# stop & remove any running service if possible
StopAndRemoveExistingService $serviceName
# Fetch the docker engine and unzip it
DownloadFile "Docker" $dockerEngineUrl $dockerZip
Expand-Archive $dockerZip -DestinationPath $dockerEnginePath -Force
Remove-Item $dockerZip
# Make sure the docker folder is in the path
EnsureDockerInPath $dockerInstallPath
# Get docker service running
EnsureDockerServiceRunning $serviceName
# Aquire Compose v1
DownloadFile "Compose" $composeEngineUrl $composeExe
Unblock-File $composeExe
Move-Item $composeExe $dockerInstallPath
popd
param(
[string]$userName = $env:username,
[string]$userDomain = $env:userdomain
)
# non-admin rights to access engine: https://github.com/tfenster/dockeraccesshelper
function GrantRights
{
param(
[string]$domain,
[string]$user
)
Write-Host "Adding $domain \ $user to docker named pipe's rights" -ForegroundColor Green
$account="$($domain)\$($user)"
$npipe = "\\.\pipe\docker_engine"
$dInfo = New-Object "System.IO.DirectoryInfo" -ArgumentList $npipe
$dSec = $dInfo.GetAccessControl()
$fullControl =[System.Security.AccessControl.FileSystemRights]::FullControl
$allow =[System.Security.AccessControl.AccessControlType]::Allow
$rule = New-Object "System.Security.AccessControl.FileSystemAccessRule" -ArgumentList $account,$fullControl,$allow
$dSec.AddAccessRule($rule)
$dInfo.SetAccessControl($dSec)
Write-Host "Done." -ForegroundColor Green
}
# Make sure the current user has rights to run containers
GrantRights $userDomain $userName
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment