> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Installing Docker on Windows (WSL 2 backend)

> The starting point for the Docker notes: install Docker on Windows with WSL 2, then on to commands, configuration, Compose, and Dockerfile.

export const TerminalDemo = ({lang = "zh", title, prompt, commands}) => {
  const L = ({
    zh: {
      play: "播放",
      pause: "暫停",
      step: "下一步",
      replay: "重新播放",
      reset: "重設",
      winTitle: "Windows PowerShell",
      hint: "點播放，逐行看驗證流程實際跑出來的樣子"
    },
    en: {
      play: "Play",
      pause: "Pause",
      step: "Step",
      replay: "Replay",
      reset: "Reset",
      winTitle: "Windows PowerShell",
      hint: "Press play to watch the verification run line by line"
    }
  })[lang] || ({});
  const defaultCmds = [{
    cmd: "nvidia-smi",
    output: ["Mon Jun  8 14:30:12 2026", "+-----------------------------------------------------------------------------+", "| NVIDIA-SMI 552.22       Driver Version: 552.22       CUDA Version: 12.4     |", "|-------------------------------+----------------------+----------------------+", "| GPU  Name           TCC/WDDM  | Bus-Id        Disp.A | Volatile Uncorr. ECC |", "| Fan  Temp Perf Pwr:Usage/Cap  | Memory-Usage         | GPU-Util  Compute M. |", "|===============================+======================+======================|", "|   0  GeForce RTX 3080  WDDM   | 00000000:01:00.0  On |                  N/A |", "| 30%   42C  P8    21W / 320W   |    842MiB / 10240MiB |      2%      Default |", "+-------------------------------+----------------------+----------------------+"]
  }, {
    cmd: "nvcc -V",
    output: ["nvcc: NVIDIA (R) Cuda compiler driver", "Copyright (c) 2005-2024 NVIDIA Corporation", "Built on Tue_Feb_27_16:28:36_2024", "Cuda compilation tools, release 12.4, V12.4.99", "Build cuda_12.4.r12.4/compiler.34097967_0"]
  }, {
    cmd: "python gpu_test.py",
    output: ["========================================", "PyTorch Version: 2.6.0+cu124", "CUDA Available:  True", "Device Name:     NVIDIA GeForce RTX 3080", "CUDA Version:    12.4", "✓ cuDNN Test Passed! Convolution executed successfully.", "========================================"]
  }];
  const raw = commands && commands.length ? commands : defaultCmds;
  const cmds = raw.map(c => ({
    cmd: c.cmd,
    lines: Array.isArray(c.output) ? c.output : String(c.output || "").split("\n")
  }));
  const PROMPT = prompt || "PS C:\\Users\\dev>";
  const TITLE = title || L.winTitle;
  const [idx, setIdx] = useState(0);
  const [typed, setTyped] = useState(0);
  const [outN, setOutN] = useState(0);
  const [stage, setStage] = useState("cmd");
  const [running, setRunning] = useState(false);
  const [done, setDone] = useState(false);
  useEffect(() => {
    if (!running || done) return;
    const cur = cmds[idx];
    if (!cur) {
      setRunning(false);
      setDone(true);
      return;
    }
    if (stage === "cmd") {
      if (typed < cur.cmd.length) {
        const id = setTimeout(() => setTyped(typed + 1), 28);
        return () => clearTimeout(id);
      }
      const id = setTimeout(() => setStage("out"), 200);
      return () => clearTimeout(id);
    }
    if (stage === "out") {
      if (outN < cur.lines.length) {
        const id = setTimeout(() => setOutN(outN + 1), 70);
        return () => clearTimeout(id);
      }
      const id = setTimeout(() => {
        if (idx + 1 < cmds.length) {
          setIdx(idx + 1);
          setTyped(0);
          setOutN(0);
          setStage("cmd");
        } else {
          setRunning(false);
          setDone(true);
        }
      }, 360);
      return () => clearTimeout(id);
    }
  }, [running, done, idx, typed, outN, stage]);
  const reset = () => {
    setRunning(false);
    setDone(false);
    setIdx(0);
    setTyped(0);
    setOutN(0);
    setStage("cmd");
  };
  const playPause = () => {
    if (done) {
      reset();
      setRunning(true);
      return;
    }
    setRunning(!running);
  };
  const step = () => {
    setRunning(false);
    if (done) return;
    if (idx + 1 < cmds.length) {
      setIdx(idx + 1);
      setTyped(0);
      setOutN(0);
      setStage("cmd");
    } else {
      const cur = cmds[idx];
      setTyped(cur.cmd.length);
      setOutN(cur.lines.length);
      setStage("out");
      setDone(true);
    }
  };
  const css = `
.td-root{--bg:#f4eee4;--bd:#e2d7c6;--ink:#5b5048;--accent:#bf7551;--accent-l:#cf8a68;
  --scr:#1c1815;--scr-fg:#e9e1d4;--scr-prompt:#cf8a68;--scr-dim:#8d8478;--scr-ok:#8fb573;--scr-err:#d98a72;
  border:1px solid var(--bd);border-radius:14px;overflow:hidden;background:var(--bg);
  font-family:ui-sans-serif,system-ui,"Noto Sans TC",sans-serif;margin:1.25rem 0;box-shadow:0 1px 2px rgba(60,40,25,.06);}
.dark .td-root{--bg:#26221e;--bd:#3a332c;--ink:#cabfb2;}
.td-bar{display:flex;align-items:center;gap:.6rem;padding:.55rem .8rem;background:linear-gradient(var(--bg),color-mix(in srgb,var(--bg) 90%,#000));border-bottom:1px solid var(--bd);}
.td-dots{display:flex;gap:.4rem;}
.td-dots i{width:11px;height:11px;border-radius:50%;display:block;}
.td-dots i:nth-child(1){background:#d98a72;} .td-dots i:nth-child(2){background:#dcb46a;} .td-dots i:nth-child(3){background:#8fb573;}
.td-title{font-size:.78rem;color:var(--ink);font-weight:600;letter-spacing:.01em;flex:1;text-align:center;opacity:.85;}
.td-ctrl{display:flex;align-items:center;gap:.3rem;}
.td-btn{display:inline-flex;align-items:center;gap:.32rem;border:1px solid var(--bd);background:transparent;color:var(--ink);
  border-radius:8px;padding:.3rem .55rem;font-size:.74rem;font-weight:600;cursor:pointer;transition:all .15s ease;line-height:1;}
.td-btn:hover{border-color:var(--accent);color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);}
.td-btn svg{width:13px;height:13px;}
.td-btn--primary{background:var(--accent);border-color:var(--accent);color:#fff;}
.dark .td-btn--primary{background:var(--accent-l);border-color:var(--accent-l);}
.td-btn--primary:hover{background:var(--accent-l);color:#fff;}
.td-count{font-size:.72rem;color:var(--ink);opacity:.6;font-variant-numeric:tabular-nums;margin-left:.2rem;}
.td-screen{background:var(--scr);color:var(--scr-fg);padding:.85rem 1rem 1.05rem;font-family:ui-monospace,"Cascadia Code","Consolas",monospace;
  font-size:.8rem;line-height:1.55;overflow-x:auto;min-height:120px;}
.td-block{margin-bottom:.5rem;}
.td-cmdline{white-space:pre;}
.td-prompt{color:var(--scr-prompt);font-weight:600;}
.td-cmd{color:#f3ecdf;}
.td-out{white-space:pre;color:var(--scr-fg);opacity:.92;}
.td-out.ok{color:var(--scr-ok);font-weight:600;}
.td-out.err{color:var(--scr-err);font-weight:600;}
.td-cursor{display:inline-block;width:8px;height:1em;background:var(--scr-prompt);margin-left:1px;vertical-align:text-bottom;
  animation:tdblink 1s steps(2,start) infinite;}
@keyframes tdblink{to{opacity:0;}}
.td-hint{padding:.5rem .9rem;font-size:.72rem;color:var(--ink);opacity:.6;border-top:1px solid var(--bd);background:var(--bg);}
@media (max-width:600px){.td-screen{font-size:.68rem;} .td-title{display:none;} .td-btn{padding:.28rem .42rem;}}
`;
  const PlayIcon = () => <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M7 5.5v13l11-6.5z" /></svg>;
  const PauseIcon = () => <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="6.5" y="5" width="4" height="14" rx="1" /><rect x="13.5" y="5" width="4" height="14" rx="1" /></svg>;
  const StepIcon = () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 4l10 8-10 8z" /><line x1="19" y1="5" x2="19" y2="19" /></svg>;
  const ResetIcon = () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7L3 8" /><path d="M3 3v5h5" /></svg>;
  const shown = Math.min(idx + (done ? 1 : 0), cmds.length);
  return <div className="td-root">
      <style>{css}</style>
      <div className="td-bar">
        <span className="td-dots"><i /><i /><i /></span>
        <span className="td-title">{TITLE}</span>
        <span className="td-ctrl">
          <button className="td-btn td-btn--primary" onClick={playPause}>
            {running ? <PauseIcon /> : <PlayIcon />}
            {done ? L.replay : running ? L.pause : L.play}
          </button>
          <button className="td-btn" onClick={step} disabled={done}><StepIcon />{L.step}</button>
          <button className="td-btn" onClick={reset}><ResetIcon />{L.reset}</button>
          <span className="td-count">{shown}/{cmds.length}</span>
        </span>
      </div>
      <div className="td-screen">
        {Array.from({
    length: idx + 1
  }).map((_, i) => {
    const c = cmds[i];
    if (!c) return null;
    const isCur = i === idx;
    const cmdText = isCur ? c.cmd.slice(0, typed) : c.cmd;
    const lines = isCur ? c.lines.slice(0, outN) : c.lines;
    const cursor = isCur && !done && stage === "cmd";
    return <div className="td-block" key={i}>
              <div className="td-cmdline">
                <span className="td-prompt">{PROMPT}</span> <span className="td-cmd">{cmdText}</span>
                {cursor && <span className="td-cursor" />}
              </div>
              {lines.map((ln, j) => {
      const tr = ln.trim();
      const cls = tr.startsWith("✓") ? "ok" : tr.startsWith("✗") || tr.startsWith("✘") ? "err" : "";
      return <div className={"td-out " + cls} key={j}>{ln.length ? ln : " "}</div>;
    })}
            </div>;
  })}
      </div>
      <div className="td-hint">{L.hint}</div>
    </div>;
};

`Docker` `WSL 2` `Windows`

Docker is an open-source application container engine that packages an app with its dependencies into a portable container that runs anywhere supported. Containers are sandboxed and isolated from each other with very low overhead. This note runs Docker on Windows on top of WSL 2, from WSL setup through Docker installed and running for the first time. For commands, configuration, and Compose once it is installed, start from [Core concepts](/en/notes/docker/guide/concepts/); to build your own image, see [How to Write a Dockerfile](/en/notes/docker/dockerfile/basics/).

<Tip>
  **Windows Pro or Enterprise is recommended**: they include Hyper-V and full virtualization, giving the most complete Docker Desktop experience with the fewest setup pitfalls. Windows Home can still run Docker via the WSL 2 backend but lacks Hyper-V and some features, which is more limiting for advanced virtualization needs.
</Tip>

## Installing WSL

WSL (Windows Subsystem for Linux) runs a Linux environment on Windows and is the best foundation for Docker on Windows.

<Note>
  The modern `wsl --install` automatically enables the required Windows features and installs the default distro, so manual feature toggling is usually unnecessary. The manual step 1 below is for fine-grained control or when auto-install fails. WSL 2 only needs "Virtual Machine Platform" and "Windows Subsystem for Linux"; Hyper-V and Windows Hypervisor Platform are not required (and Hyper-V is absent on Windows Home).
</Note>

<Steps>
  <Step title="Enable features (optional, if auto-install fails)">
    Control Panel → Programs → Turn Windows features on or off, check:

    * Virtual Machine Platform (**required**)
    * Windows Subsystem for Linux (**required**)
    * Hyper-V, Windows Hypervisor Platform (optional, not required for WSL 2)

    Click OK and restart.
  </Step>

  <Step title="Install WSL">
    Open PowerShell or Command Prompt as administrator and run:

    ```powershell theme={null}
    wsl --update
    wsl --install
    ```

    This enables the required features and installs the default Linux distro (Ubuntu). Restart afterwards.
  </Step>

  <Step title="Set up the Linux user">
    On first launch the new distro opens a console, waits for files to extract (faster afterwards), and prompts you to create a username and password.
  </Step>

  <Step title="Verify WSL">
    Check the WSL version and installed distros:

    ```powershell theme={null}
    wsl -l -v
    ```
  </Step>

  <Step title="Set WSL 2 as default">
    WSL 2 is the recommended environment for Docker:

    ```powershell theme={null}
    wsl --set-default-version 2
    ```
  </Step>

  <Step title="Change the default distro (optional)">
    List available distros and install a specific one with `-d`:

    ```powershell theme={null}
    wsl --list --online
    wsl --install -d <distro-name>
    ```
  </Step>

  <Step title="Start as root (if no user was set in step 3)">
    If `wsl --install` did not prompt for a username/password, enter as root first, then create an account manually:

    ```powershell theme={null}
    wsl.exe --user root
    ```
  </Step>

  <Step title="Tune WSL 2 resources (optional)">
    Edit `C:\Users\<your-username>\.wslconfig` to cap WSL 2 memory and processors. **The `[wsl2]` section header is mandatory**, or the settings are ignored:

    ```ini theme={null}
    [wsl2]
    memory=8GB      # WSL 2 VM memory cap
    processors=16   # virtual processors for the WSL 2 VM
    swap=8GB        # swap size
    ```

    Apply with `wsl --shutdown` to restart WSL. Docker's CPU and memory on the WSL 2 backend are controlled by this file (not the Docker Desktop GUI); see [Performance settings](/en/notes/docker/guide/config/).
  </Step>

  <Step title="Integrate VS Code and Windows Terminal (optional)">
    VS Code integrates with WSL automatically once installed, so you can edit and compile inside WSL. Windows Terminal lets you switch between multiple Linux terminals and PowerShell.
  </Step>
</Steps>

## Installing Docker

Use Docker Desktop with the WSL 2 engine on Windows.

<Steps>
  <Step title="Install Docker Desktop">
    Download the installer from [Docker](https://docs.docker.com/desktop/setup/install/windows-install/) and follow the prompts; mind the [system requirements](https://docs.docker.com/desktop/setup/install/windows-install/#system-requirements).
  </Step>

  <Step title="Launch Docker Desktop">
    Start it from the Windows Start menu after installation.
  </Step>

  <Step title="Enable the WSL 2 engine and integration">
    Settings (top-right gear) → General, check "Use the WSL 2 based engine"; Resources → WSL Integration, select the distros to enable Docker integration for, then Apply & Restart.
  </Step>

  <Step title="Verify Docker">
    In the WSL Linux terminal run:

    ```bash theme={null}
    docker run hello-world
    docker version
    ```
  </Step>
</Steps>

Run the verification in the WSL terminal; on success you should see output like this:

<TerminalDemo
  lang="en"
  title="Ubuntu (WSL 2)"
  prompt="user@wsl:~$"
  commands={[
{
  cmd: "docker run hello-world",
  output: [
    "Unable to find image 'hello-world:latest' locally",
    "latest: Pulling from library/hello-world",
    "c1ec31eb5944: Pull complete",
    "Status: Downloaded newer image for hello-world:latest",
    "",
    "Hello from Docker!",
    "This message shows that your installation appears to be working correctly.",
  ],
},
{
  cmd: "docker version",
  output: [
    "Client:",
    " Version:        27.3.1",
    " API version:    1.47",
    " OS/Arch:        linux/amd64",
    "Server: Docker Desktop",
    " Engine:",
    "  Version:       27.3.1",
    "  API version:   1.47 (minimum version 1.24)",
  ],
},
]}
/>

<Warning>
  Docker Desktop requires a paid subscription for large enterprises (above the official employee or revenue thresholds); personal and small-team use is free. See Docker's licensing terms.
</Warning>

## Next steps

Once installed, continue here. **Usage and configuration**:

* [Core concepts](/en/notes/docker/guide/concepts/): Image, Container, Volume, and the two interfaces.
* [CLI commands](/en/notes/docker/guide/cli/): what you use every day.
* [Docker Hub](/en/notes/docker/guide/hub/): where images come from and how to trust them.
* [Performance settings](/en/notes/docker/guide/config/): WSL 2 backend resources and daemon.json.
* [Where data lives](/en/notes/docker/guide/storage/): volume, bind mount, tmpfs, and no mount.
* [Docker Compose](/en/notes/docker/guide/compose/): bring up many containers at once.

**Dockerfile** (build your own image):

* [Basics and building from scratch](/en/notes/docker/dockerfile/basics/), [instructions](/en/notes/docker/dockerfile/instructions/), [Python app](/en/notes/docker/dockerfile/python/), [choosing images](/en/notes/docker/dockerfile/images/), [layer cache and best practices](/en/notes/docker/dockerfile/caching/).

## Links

* Docker docs: [docs.docker.com](https://docs.docker.com/)
* WSL docs: [learn.microsoft.com/windows/wsl](https://learn.microsoft.com/windows/wsl/)
