Modules/businessdev.ALbuild.Containers/Private/Wait-BcDockerDaemon.ps1

function Wait-BcDockerDaemon {
    <#
    .SYNOPSIS
        Waits until the Docker daemon answers, or the timeout expires.
 
    .DESCRIPTION
        A started service is not a ready daemon: on Windows the engine takes seconds to tens of seconds
        after Start-Service before it responds, and longer on the first start after its data root changed,
        because it initialises an empty layer store. Anything that queries Docker in that window gets a
        connection error that looks like a real failure.
 
        So readiness is polled by asking the daemon something it can only answer when it is up.
 
    .PARAMETER DockerExecutable
        The Docker executable to poll. Default 'docker'.
 
    .PARAMETER TimeoutSeconds
        How long to keep trying. Default 180.
 
    .PARAMETER IntervalSeconds
        Delay between attempts. Default 3.
 
    .OUTPUTS
        System.Boolean - $true once the daemon answered, $false if the timeout expired.
    #>

    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [string] $DockerExecutable = 'docker',
        [ValidateRange(1, 3600)] [int] $TimeoutSeconds = 180,
        [ValidateRange(1, 60)] [int] $IntervalSeconds = 3
    )

    $deadline = (Get-Date).AddSeconds($TimeoutSeconds)
    $attempt = 0
    while ((Get-Date) -lt $deadline) {
        $attempt++
        $probe = Invoke-BcDocker -DockerExecutable $DockerExecutable -Quiet -PassThru -Arguments @('info', '--format', '{{.ServerVersion}}')
        if ($probe.Success -and "$($probe.StdOut)".Trim()) { return $true }
        Write-Verbose "Docker daemon not ready yet (attempt $attempt); waiting $IntervalSeconds s."
        Start-Sleep -Seconds $IntervalSeconds
    }
    return $false
}