Self-Hosted AI Stack — Part 2: Environment Setup
Part 2 of the self-hosted AI stack series. Get a dedicated WSL2 distro running on the drive of your choice, with Docker Engine and GPU passthrough confirmed working before installing a single AI service.
Goal for this part: get a dedicated WSL2 Linux distro running on the drive of your choice, with Docker Engine and GPU passthrough confirmed working, before installing a single AI service.
If you already use WSL2 for other development work, don't reuse your
existing distro for this stack. Create a separate, dedicated distro
instead — it keeps a bad dependency, a filled disk, or a botched update
in this project from ever touching your regular development environment.
This series assumes a fresh distro named Ubuntu-24.04, kept completely
separate from any distro you already use day-to-day.
Why WSL2 instead of a VM or dual-boot
WSL2 gives you a real Linux kernel with near-native performance and, critically, working GPU passthrough to NVIDIA GPUs — without needing to dual-boot or dedicate a physical machine to Linux. For a Windows-based build like this one, it's the path of least friction while still getting you a proper Linux environment for Docker.
Installing a dedicated distro
wsl --install Ubuntu-24.04If you already have a default distro installed, this adds a second, independent one without touching it. Confirm both exist and are separate:
wsl --list --verboseMoving the distro to a dedicated drive
By default, WSL2 distros live on your system drive. If you want this stack on a separate drive — recommended, since model checkpoints get large fast — export and re-import it:
wsl --shutdown
wsl --export Ubuntu-24.04 D:\wsl-backup\ubuntu-24.04.tar
wsl --unregister Ubuntu-24.04
wsl --import Ubuntu-24.04 D:\WSL\Ubuntu-24.04 D:\wsl-backup\ubuntu-24.04.tarwsl --import drops you into the distro as root by default. Set your
normal user as default so you're not accidentally running everything as root:
ubuntu2404 config --default-user your_usernameThe exact command name matches whatever launcher WSL registered for your
distro — check wsl --list if ubuntu2404 doesn't resolve.
Installing Docker Engine inside WSL2
Skip Docker Desktop for this — installing Docker Engine directly inside the
WSL2 distro gives you a lighter setup with fewer layers between your containers
and the GPU. From inside your Ubuntu-24.04 distro:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USERLog out and back into the distro (or run newgrp docker) for the group
membership to take effect, then confirm:
docker run hello-worldGPU passthrough: the NVIDIA Container Toolkit
This is the piece that lets containers actually use your GPU instead of just seeing a CPU. Two things need to be true:
- Your Windows NVIDIA driver needs WSL2 GPU support — recent drivers include this by default, no separate Linux driver install needed inside WSL2
- The NVIDIA Container Toolkit needs to be installed inside your distro
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update
sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockerBlackwell-generation GPUs (RTX 50-series) require CUDA 12.8 or newer to
be recognized correctly. This matters later when choosing container image
tags — Part 3's ComfyUI image is deliberately pinned to a cuda12.8 tag
for exactly this reason. An older CUDA tag can silently fail to detect the
GPU or fall back to CPU-only execution. If you're on an older GPU (Ampere,
Ada Lovelace), CUDA 12.x in general is still recommended but the specific
12.8 pinning is less critical.
Verifying GPU passthrough end-to-end
docker run --rm --gpus all nvidia/cuda:12.8.0-base-ubuntu24.04 nvidia-smiIf this prints your GPU's name, driver version, and memory — passthrough is working, and you're ready for Part 3.
If this command errors out, don't move on yet. Every service in this stack depends on GPU passthrough working correctly. Debug here before installing anything else.
Troubleshooting
nvidia-smi works on Windows but fails inside the container
Confirm your Windows NVIDIA driver version supports WSL2 GPU passthrough — recent drivers do by default. Also confirm you're not running an old cached Docker image:
docker pull nvidia/cuda:12.8.0-base-ubuntu24.04Pull the image fresh and retry. If it still fails, check that the NVIDIA
Container Toolkit installation completed without errors — re-run the toolkit
install commands and look for any apt errors.
wsl --import distro won't start, or hangs
Confirm the target path (e.g. D:\WSL\Ubuntu-24.04) exists and that you
have write permissions there. Also confirm wsl --shutdown fully stopped
all running distros before the export step — an export mid-write can produce
a corrupted tarball.
wsl --list --runningIf anything is still listed, shut it down before exporting.
Docker commands require sudo every time
Your user wasn't added to the docker group, or the group change hasn't
taken effect in the current shell session. Check with:
groupsIf docker isn't listed, the usermod command didn't apply yet. Fully close
and reopen your WSL2 terminal — not just newgrp docker — and check again.
If it's still missing, re-run:
sudo usermod -aG docker $USERThen close and reopen the terminal completely.