Skrog

Installing Skrog

On this page

Installing Skrog is three separate steps, and knowing they are separate saves the most common confusion — “I installed it and docker says command not found”:

what it gives you
1. Get skrog.exethe command-line tool, on your PATH. Nothing is provisioned
2. skrog installthe Docker engine, and a bridge serving it on a Windows named pipe
3. skrog cli installthe docker command itself — only if you do not already have one

Step 3 is not automatic, and that is deliberate: most people arrive with Docker Desktop’s docker.exe already on PATH and would not want a second one. On a clean machine you do need it, and skrog install now says so when it finishes.

Requirements

  • Windows 11, or Windows 10 22H2 (build 19045) — both tested.
  • x64 or ARM64. Both are native end to end, engine included — see Windows on ARM below.
  • WSL 2.x, from the Microsoft Store or the MSI. wsl --version should print something; if it errors, run wsl --update.
  • Virtualization enabled in firmware.

Windows on ARM

Supported since rootfs-v29.8.1-2 (#388). skrog.exe has an arm64 build, and so does the engine. skrog install picks the rootfs for your architecture automatically — there is no flag.

The arm64 engine is compiled from the same pinned upstream sources as amd64, natively on an arm64 runner rather than under emulation, and CI boots it and checks it against Docker’s aarch64 reference bundle on every change.

One honest caveat. The arm64 rootfs has never been run inside a WSL2 utility VM on Windows on ARM. There is no maintainer hardware, and GitHub’s hosted arm64 Windows runners expose no nested virtualization, so WSL2 cannot start on them at all — the engine is boot-tested in a container on arm64 Linux instead, which exercises dockerd but not WSL2’s side of it.

If you are running this on a Snapdragon or Surface machine, you are the first real test. Please report what happens either way: #458.

The docker CLI works too. Upstream publishes no Windows arm64 docker.exe, so Skrog builds it from docker/cli source — reproducibly, and skrog cli install places it like any other tool. compose, buildx and the credential helper are upstream’s own arm64 releases. docs/docker-cli.md explains which binary comes from where and why only one of them is ours (#450).

Nothing else. Skrog does not need Docker Desktop, and coexists with it if you keep it.

Step 1 — get skrog.exe

The one-liner

irm https://wslkit.github.io/skrog/install.ps1 | iex

It resolves the newest release, downloads the zip for your architecture, verifies it against the release’s SHA256SUMS, unpacks it to %LOCALAPPDATA%\Programs\skrog, and adds that to your user PATH (no elevation). It provisions nothing — that is step 2.

Options come from the environment, because irm | iex cannot take arguments:

$env:SKROG_VERSION = '0.10.0'           # default: newest release
$env:SKROG_DIR     = 'C:\tools\skrog'   # default: %LOCALAPPDATA%\Programs\skrog
$env:SKROG_NO_PATH = '1'                # do not touch PATH

Read the script first if you would rather not pipe a URL into your shell. It does nothing the manual steps below do not.

It installs the newest stable release. skrog upgrade --check deliberately counts pre-releases too, so it can tell you a preview exists on a machine this script put on the stable build — first contact should be stable, an explicit “what is new?” should be complete.

Or with scoop

scoop bucket add skrog https://github.com/wslkit/scoop-skrog
scoop install skrog

Then scoop update skrog keeps it current. Skrog notices it is managed — skrog upgrade --apply refuses inside a package-manager directory and tells you to use scoop instead, rather than fighting it for the same files.

A winget package is #412. Neither is blocked on code signing, which this project believed for longer than it should have; only the MSI is.

Or by hand

  1. Open the latest release.

  2. Download the zip for your architecture and the SHA256SUMS file beside it:

    you havedownload
    64-bit Intel/AMD (almost everyone)skrog_<version>_windows_amd64.zip
    Windows on ARM (Snapdragon, Surface Pro X)skrog_<version>_windows_arm64.zip — read this first

    Not sure? $env:PROCESSOR_ARCHITECTURE prints AMD64 or ARM64.

  3. Check it, and compare the line for your zip:

    Get-FileHash .\skrog_<version>_windows_amd64.zip -Algorithm SHA256
    Get-Content .\SHA256SUMS
    
  4. Unpack it somewhere on your PATH — %LOCALAPPDATA%\Programs\skrog is what the script uses:

    Expand-Archive .\skrog_<version>_windows_amd64.zip -DestinationPath "$env:LOCALAPPDATA\Programs\skrog"
    

The zip contains skrog.exe, skrogw.exe (the windowless logon launcher — autostart needs it), skrogtray.exe (an optional status tray), plus LICENSE and README.md. Keep them together.

SmartScreen will warn on first run. The binaries are not Authenticode-signed. The SignPath Foundation’s free programme declined for now — it is for projects with an established user base — and invited a reapplication as visibility grows; paying for a certificate is the other route. Which one, and when, is #358, so no date is promised here.

An MSI waits on the same answer, because an installer that asks for elevation unsigned is a worse experience than a zip, not a better one. A winget package does not — winget’s portable type unpacks per-user and needs no elevation or signature — and one is on the way; until it lands it is download-and-unpack, which is exactly why the checksum step above is written out in full rather than waved at.

What every release does carry today is SLSA build provenance and a cosign-signed SHA256SUMS — two things an Authenticode signature does not give you, because they tie the artifact to a workflow run and a commit. See verifying a download.

Step 2 — install the engine

skrog install

This downloads the checksum-verified engine rootfs, imports it as the skrog-engine WSL2 distro, starts the engine, wires a skrog docker context, and registers the supervisor to start at logon. It prints the pipe it took.

Then bring the bridge up now (from your next logon it starts itself):

skrog start

Useful flags:

flagwhy
--no-autostartdo not start the supervisor at logon. Skrog then does not come back after a reboot until you run skrog start. The choice is recorded as autostart = off, so skrog doctor treats it as deliberate; skrog config set autostart on (or skrog autostart enable) turns it on later
--headlessnever prompt; for CI and unattended installs
--locked skrog.lockinstall the exact engine a skrog lock pinned
--offline bundle.zipinstall from an air-gap bundle (air-gap.md)

Step 3 — make sure you have a docker command

Skrog does not install one by default. Check:

docker version

If that works, you are done — skip to Verify. It usually works when Docker Desktop is installed, because its CLI is already on PATH.

If it says “command not found”, install the upstream tools:

skrog cli install

That fetches and checksum-verifies pinned versions of the Docker CLI, Compose v2, Buildx and the Windows credential helper, straight from each project’s own release assets — no Docker Desktop and no third-party mirror. Open a new terminal afterwards so PATH is picked up. Details in docker-cli.md.

Verify

docker run --rm hello-world
skrog status
skrog doctor

skrog status should show the engine running and name the pipe it bound. skrog doctor checks the host, the engine, PATH, contexts, VPN/DNS/proxy interference and more, and --fix applies the safe remedies.

Which pipe, and when you need a context

If Docker Desktop is not serving it, Skrog takes \\.\pipe\docker_engine — the pipe docker already talks to — and plain docker reaches Skrog with no flag and no context.

If Desktop owns that pipe, Skrog serves its own and you select it:

docker context use skrog      # or: docker --context skrog ps

The install output names which case you are in, and docker context inspect skrog shows it at any time.

Tab completion

Optional, and worth the one line: skrog has 36 commands and a config surface of around 25 dotted keys, which is more than anyone should type from memory.

The release zip contains a completions folder.

PowerShell — dot-source it from your profile:

# see where your profile lives, and create it if it does not exist
if (-not (Test-Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
Add-Content $PROFILE ". '$env:LOCALAPPDATA\Programs\skrog\completions\skrog.ps1'"

Open a new terminal, then skrog sn<TAB> completes to snapshot, and skrog status --<TAB> offers that command’s flags.

bash (Git Bash, or a distro you have wsl-integrated):

source /c/Users/you/AppData/Local/Programs/skrog/completions/skrog.bash
# or, to make it permanent
echo "source .../completions/skrog.bash" >> ~/.bashrc

Both scripts complete commands, subcommands and flags from a list generated from the binary itself — CI fails if they drift from what the CLI accepts. Where the useful answer is something only your machine knows, they ask it at the moment you press TAB:

You typeIt offers
skrog config set <TAB>every setting key, including engine.* and hook.*
skrog profile switch <TAB>your saved profiles
skrog snapshot restore <TAB>your snapshots
skrog remote use <TAB>your registered remotes, plus local

Those lookups are read-only and never start the engine, so completing a word never costs you a cold start.

Upgrading

skrog upgrade --apply

That replaces skrog.exe itself. The engine is a separate, pinned thing: skrog engine list, skrog engine upgrade, skrog engine rollback. See upgrading.md and engine-upgrade.md.

Uninstalling

skrog uninstall

Removes the distro, the supervisor registration and the docker context. It asks before deleting engine data — images and volumes — because that is not recoverable. Then delete the folder from step 1.

If something goes wrong

skrog doctor first: it diagnoses most of it and explains the rest.

  • Corporate network, proxy or TLS inspection — corporate-network.md
  • A VPN breaks networking after connecting — vpn.md
  • No internet on the machine at all — air-gap.md
  • docker resolves to the wrong binary — skrog doctor names it and says what will move it

Edit this page on GitHub