Windows 11 WSL2自动挂载VHDX并实现Docker Desktop自动挂载指南

一、手动附加并获取磁盘信息

  1. 系统要求:需要运行 Windows 11 Build 22000 以上版本,或安装最新版 Microsoft Store 版 WSLlearn.microsoft.com。这些版本内置了 wsl --mount 功能,可以直接挂载 ext4 磁盘。

  2. 创建 VHDX:在 Windows 磁盘管理 中创建 VHDX。

    操作 → 创建 VHD → 指定路径(如 `E:\data.vhdx`)→ 选择动态扩展 → 分离 VHD(否则 WSL 无法挂载)
    
  3. 附加VHDX虚拟磁盘

    
    运行以下命令,将 `<Your-VHDX-Path>` 替换为你的 VHDX 文件实际路径。
    # 仅附加设备,不自动挂载(裸设备模式)
    # 路径中如果包含空格,请用引号括起来
    wsl --mount "<Your-VHDX-Path>" --bare
  1. 进入 Ubuntu 并查找磁盘信息

    打开你的 Ubuntu 终端,然后运行以下命令查看新附加的磁盘设备。
    
    lsblk
你应该会看到一个新设备,例如 `sdb`、`sdc` 或 `sdd`。它的大小应该与你的 VHDX 文件相匹配。假设我们找到的设备是 `/dev/sdc`。
  1. 格式化ext文件系统,临时挂载

# 格式化为 ext4 文件系统
sudo mkfs.ext4 /dev/sdc 
# 创建挂载点
sudo mkdir /data
# 挂载
sudo mount /dev/sdc /data
  1. 获取分区的 UUID
    使用 UUID 是最可靠的方式,因为设备名 (/dev/sdc) 在重启后可能会改变。运行 blkid 命令获取分区的 UUID。

    sudo blkid /dev/sdc1
  * 你会得到类似下面这样的输出:
/dev/sdc1: UUID="a1b2c3d4-e5f6-7890-1234-567890abcdef" TYPE="ext4" PARTUUID="..."
  * **复制 `UUID` 的值**(例如 `a1b2c3d4-e5f6-7890-1234-567890abcdef`),我们下一步会用到它。
  

二、在 Ubuntu 中配置 fstab 自动挂载

现在,我们来编辑 Ubuntu 的文件系统表,让它在看到这个 UUID 的设备时就自动挂载。

  1. 在 Ubuntu 中创建挂载点
    这是你希望访问 VHDX 内容的目录。一个常见的选择是在 /mnt 下创建一个目录。

    sudo mkdir /data
你可以将 `data` 替换为你喜欢的任何名称。
  1. 编辑 /etc/fstab 文件
    使用你喜欢的文本编辑器(如 nano)打开 fstab 文件。

    sudo nano /etc/fstab
  2. 添加新的挂载条目
    在文件的末尾,添加新的一行。格式如下:

    UUID=<Your-Partition-UUID>  /mnt/data  ext4  defaults  0  0
  * 将 `<Your-Partition-UUID>` 替换为你在第一步中复制的 UUID。
  * `/mnt/data` 是你创建的挂载点。
  * `ext4` 是文件系统类型。
  * `defaults` 表示使用默认的挂载选项,这通常足够了。
  * 最后两个 `0` 是用于 `dump` 和 `fsck` 的,对于这种类型的挂载设为 `0` 即可。
  * **示例**:
UUID=a1b2c3d4-e5f6-7890-1234-567890abcdef  /mnt/data  ext4  defaults  0  0
  1. 保存并关闭文件 (在 nano 中,按 Ctrl + X,然后按 Y,最后按 Enter)。

三:在 Windows 中设置自动启动脚本任务

第一步:禁用 Docker Desktop 的自动启动

这是最关键的一步。我们必须先禁止 Docker Desktop 自己启动,把启动权交给我们自己的脚本。

  1. 启动 Docker Desktop。

  2. 点击右上角的设置(齿轮图标)。

  3. General (常规) 选项卡中,取消勾选 "Start Docker Desktop when you log in" (登录时启动 Docker Desktop)。

  4. 点击 "Apply & restart" (应用并重启) 保存设置。

现在,Docker Desktop 在你下次登录时不会自动运行了。

第二步:创建 PowerShell 控制脚本

我们将创建一个 PowerShell 脚本(.ps1 文件)来编排整个启动流程。PowerShell 脚本能很好地执行外部命令并进行流程控制。

  1. 选择一个位置存放脚本。 例如,在你的 C: 盘下创建一个 Scripts 文件夹,即 C:\Scripts

  2. 创建脚本文件。 在 C:\Scripts 文件夹中,创建一个新的文本文件,并将其命名为 start-wsl-docker.ps1。 (确保文件后缀是 .ps1 而不是 .txt)。

  3. 编辑脚本内容。 用记事本、VS Code 或任何文本编辑器打开 start-wsl-docker.ps1 文件,然后粘贴以下内容:
# --- 请根据你的实际情况修改下面的变量 ---

# 1. 你的 VHDX 文件的完整 Windows 路径
$vhdxPath = "D:\data.vhdx"

# 2. 你的 WSL 发行版名称
$wslDistro = "Ubuntu"

# 3. 你在 Ubuntu 中设置的挂载点 (fstab 中配置的目录)
$mountPoint = "/data"

# 4. Docker Desktop 可执行文件的路径 (通常是这个,如果不是请修改)
$dockerDesktopPath = "C:\Program Files\Docker\Docker\Docker Desktop.exe"

# --- 脚本主逻辑,通常无需修改 ---

Write-Host "Step 1: 正在附加 VHDX 磁盘: $vhdxPath"
# 使用 wsl --mount 附加磁盘

wsl.exe --mount --vhd $vhdxPath --bare

Write-Host "Step 2: 正在等待 WSL 内部挂载点 '$mountPoint' 出现..."
$maxWaitSeconds = 60 # 最长等待60秒
$waitTime = 0
$mountSuccess = $false

# 循环检查 WSL 内部的挂载点是否已经准备好
while ($waitTime -lt $maxWaitSeconds) {
    # 使用 wsl.exe 在指定的发行版中执行 test -d 命令来检查目录是否存在
    # $? 在 PowerShell 中检查上一条命令是否成功
    $result = wsl.exe -d Ubuntu -- mount | Select-String "on /data type ext4"
    if ($result) {
        Write-Host "成功: 挂载点 '$mountPoint' 已在 WSL 中找到。"
        $mountSuccess = $true
        break
    }

    # 如果未找到,等待2秒后重试
    Start-Sleep -Seconds 2
    $waitTime += 2
    Write-Host "等待中..."
}

# Step 3: 根据挂载结果决定是否启动 Docker Desktop
if ($mountSuccess) {
    Write-Host "Step 3: 挂载成功,正在启动 Docker Desktop..."
    # 使用 Start-Process 启动 Docker Desktop
    Start-Process -FilePath $dockerDesktopPath
    Write-Host "脚本执行完毕。"
} else {
    Write-Host "错误: 在 $maxWaitSeconds 秒内未能检测到 WSL 挂载点。Docker Desktop 未启动。"
    # 你可以在这里添加错误处理,例如弹窗提示
    # [System.Windows.Forms.MessageBox]::Show("WSL 磁盘挂载失败,Docker Desktop 未能启动。", "启动错误", 0)
    exit 1 # 退出并返回错误代码
}

第三步:修改 Windows 任务计划程序
  1. 打开任务计划程序

    • Win + R,输入 taskschd.msc,然后按 Enter。
  2. 创建新任务

    • 在右侧的“操作”面板中,点击“创建任务...”。
  3. “常规”选项卡:

    • 名称: 给任务起一个描述性的名字,例如 Auto Mount WSL VHDX
    • 描述: (可选) 添加一些备注,例如 Mounts the data.vhdx for WSL2 Ubuntu
    • 安全选项: 选择“不管用户是否登录都运行”,这能确保即使你在后台运行 WSL,磁盘也能被挂载。
    • 关键一步:点击 “更改用户或组...” 按钮。(解决WSL启动身份问题)
    • 在弹出的窗口中,输入您自己的 Windows 用户名 (例如 MyPC\YourUser),然后点击“检查名称”并“确定”。
    • 勾选 “使用最高权限运行”
  4. “触发器”选项卡:

    • 点击“新建...”。
    • 在“开始任务”的下拉菜单中,选择“启动时”。
  5. “操作”选项卡:

    • 点击“新建...”。
    • 操作: 保持“启动程序”。
    • 程序/脚本: 输入 powershell.exe
    • 添加参数 (可选): 输入 -ExecutionPolicy Bypass -File "C:\Scripts\tart-wsl-docker.ps1"

      • ExecutionPolicy Bypass: 这是一个安全参数,允许 PowerShell 执行本地脚本。
      • File "C:\Scripts\start-wsl-docker.ps1": 这里是你的脚本的完整路径。如果你的路径不同,请务必修改。
    • 点击“确定”。
  6. “条件”选项卡:

    • 取消勾选“只有在计算机使用交流电源时才启动此任务”。这样可以确保在用电池的笔记本电脑上也能正常工作。
  7. “设置”选项卡:

    • 可以保留默认设置。确保“如果任务失败,按以下频率重新启动”是启用的,以增加可靠性。
    • 点击“确定”保存整个任务。系统可能会再次要求你输入密码。

第四步:重启并验证

现在,所有配置都已完成。重启你的电脑。

在你登录后,任务计划程序会自动执行 start-wsl-docker.ps1 脚本。脚本会:

  1. 先挂载 VHDX。
  2. 然后循环检查,直到确认 Ubuntu 里的 /mnt/data 目录出现。
  3. 最后启动 Docker Desktop。
  4. 现在可以远程登录 Windows 。打开你的 Ubuntu 终端。运行 df -hlsblk 命令来检查挂载情况。

<!-- end list -->

df -h

你应该能在输出列表中看到你的 VHDX 分区被挂载到了 /data 上,并且可以像使用本地目录一样访问它了。

Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sdc       100G   60M   95G   1% /data
...

至此,你已成功配置了 WSL2 VHDX 虚拟磁盘的持久化自动挂载(不依赖用户登录),并完美地解决了启动顺序的问题,确保了当 Docker Desktop 启动时,它所依赖的 WSL 磁盘映射已经准备就绪。

本文链接:

https://www.egowan.com/archives/17/

粤ICP备20049596号-1

粤公网安备 44030402003838号