Skip to main content
On Windows the runner runs inside WSL2. For isolated builds, Docker Engine must run inside WSL2 too. For a runner installed in WSL2, Docker Desktop is not enough. With it alone, outerlayer runner init refuses unless you pass --allow-process-builds. Builds then use builtin:process, record shared-user, and are not isolated. See The process fallback. The runner image accepts Docker Desktop on Windows, with an engine of version 26 or later. It is not yet verified end to end: no one has run a build that way and reported the result. See Run the runner in a container.

Set it up

  1. In a WSL2 shell, install and start Docker Engine 26 or later, following Docker’s instructions for your Linux distribution. Install Docker’s Buildx plugin too, version 0.18 or later. The runner builds images with it; see Image builds.
  2. Check the shell and the engine:
  3. From the same shell, follow Set up a host. outerlayer runner init names builtin:container when it finds Docker Engine in WSL2. Otherwise it refuses and says what is missing; --allow-process-builds names builtin:process instead, with no isolation.
  4. Run outerlayer doctor. The Build isolation line should say builtin:container.

Keep the runner running

WSL2 shuts a distribution down once no Windows program is using it, so the runner would stop when you close your terminals or log out. outerlayer runner init sets up what prevents that. You write no service file, and the command is the same as on Linux.
  • It writes the systemd unit inside WSL2 and enables it.
  • It makes a Windows scheduled task that starts the distribution when you log in and keeps it running, with schtasks.exe through WSL2’s Windows interop. The task has the unit’s name, outerlayer-runner. The runner runs from when you log in, not before. For a runner that runs before anyone logs in, use Linux.
If systemd is off in the distribution, setup turns it on in /etc/wsl.conf and stops there. Run wsl --shutdown once from Windows, open the distribution again, and run outerlayer runner init or outerlayer runner install --service again. Setup makes no unit and no task until then. If schtasks.exe cannot start, setup does not check for the task. It prints two schtasks commands to run in Windows: schtasks /Query /TN outerlayer-runner to check for the task, and schtasks /Create /F to make it. It does the same under sudo, which drops WSL_DISTRO_NAME, the variable that names the distribution. Run setup without sudo so it can make the task. To remove the unit, run outerlayer runner uninstall --service. If schtasks.exe cannot start, uninstall prints schtasks /Delete /F /TN outerlayer-runner to run in Windows. See Run the runner as a service.

Windows access from the runner’s distribution

Setup turns off three WSL2 defaults in the runner’s distribution. It writes them to /etc/wsl.conf:
  • Interop. With interop on, any Linux process in the distribution can start a Windows program. Windows runs it as the active Windows user.
  • The Windows PATH. WSL adds it to the distribution’s PATH, so a shell finds cmd.exe and powershell.exe by name.
  • Drive automount. WSL mounts each Windows drive under /mnt. A process can then read and change the drive with your Windows rights.
A build that escapes its container as an account other than root would reach your Windows account through these. The runner needs none of them after setup. Setup keeps every other line of /etc/wsl.conf. It writes the file only if a line must change. Uninstall leaves the three settings in place, because another runner can share the distribution. To turn Windows access back on, delete the three lines and restart the distribution.

Restart the distribution

WSL reads /etc/wsl.conf only when the distribution starts. Setup does not restart it. Until you restart, interop and the drive mounts stay on. A restart stops every running build. Restart when no build runs. From Windows, run these commands:
Use the name that wsl -l shows for <distribution>. After the restart, schtasks.exe cannot start in the distribution. A later run of setup or uninstall prints the schtasks command to run in Windows. A host set up before this change gets the settings the next time you run outerlayer runner install --service. Then restart the distribution.

Before the restart

  • Use a distribution that runs nothing but the runner. After the restart, you lose code ., explorer.exe and /mnt/c in it. Use another distribution for Windows tools.
  • Keep the runner’s config, its directory and its Node in the distribution’s own file system, not under /mnt. The service cannot start otherwise.
  • Check Git’s credential helper. If it is Git Credential Manager for Windows, Git fails after the restart.
  • Check ~/.docker/config.json. If it holds "credsStore": "desktop.exe", which Docker Desktop leaves behind, Docker cannot get credentials. Pulls and image builds fail. Remove the key.
  • A copy of a distribution made with wsl --export and wsl --import starts as root. Set [user] default= in that copy’s /etc/wsl.conf. Otherwise setup runs as root, and so does the service.

What the settings do not stop

Root in the distribution can still mount a Windows drive by hand. The runner’s account is often in the docker group, which gives root in practice. So the settings remove the default paths to Windows. They do not stop root. A drive listed in /etc/fstab still mounts at start. WSLg still shows windows on your desktop. A build that must never reach your account needs microVM builds, which WSL2 does not offer.

What doctor says