WSL2のUbuntuを別マシンに移行しようとして盛大にハマった話 ― 失敗から生まれた手順書

はじめに
「ext4.vhdx をコピーすれば環境は移るだろう」
……と軽い気持ちで始めた WSL2 の Ubuntu 移行作業が、想定外のエラーと仕様の落とし穴に次々と引っかかり、かなりの時間を溶かしました。この記事は、その 試行錯誤の全記録 です。
この記事を読むと分かること:
- WSL2 ディストリビューションの移行で陥りやすい 失敗パターン とその見分け方
-
wsl --export/wsl --importの正しい使い方と落とし穴 -
Optimize-VHDが動かない場合の原因切り分けと対処 - VHDX を安全に小さくするためのクリーンアップ手順
1. 発端 ―「コピーすれば移るだろう」
やりたかったこと
他のマシンで同じ開発環境を使いたくて、WSL2 の Ubuntu 22.04 を別マシンに移行しようとしました。作業前の仮説はめちゃくちゃシンプルでした。
ext4.vhdx(WSL の仮想ディスク)をコピーすれば、そのまま環境が移るでしょ?
実際にやったこと(時系列)
最初はシンプルに進めるつもりでした。ざっくりこんな流れです。
① まず wsl --unregister で既存の登録を解除
一旦 unregister して登録を消しました。
wsl --unregister Ubuntu-22.04
② D ドライブにディストリを登録
VHDX ファイルを D ドライブにコピーして、--import-in-place で直接登録しました。tar を経由せず、VHDX をそのまま使えるコマンドです。
wsl --import-in-place Ubuntu-22.04 D:\WSL\Ubuntu-22.04\ext4.vhdx
ここまでは順調。
③ 起動したら root だった
インポート後にいざ起動してみると root@... で立ち上がりました。
元のユーザーで入れない。ということで ubuntu2204.exe config --default-user でデフォルトユーザーを設定し直して対応。
④ そして地獄が始まった
ユーザー設定は解決したのに、今度は起動が安定しなくなりました。起動できるときもあれば、以下のエラーが出て起動できないときもある。
ディスク '\\?\D:\WSL\Ubuntu-22.04\ext4.vhdx' を WSL2 にアタッチできませんでした: アクセスが拒否されました。
エラー コード: Wsl/Service/CreateInstance/MountDisk/HCS/E_ACCESSDENIED
「さっきまで動いてたのに……?」の繰り返し。
再現条件がよく分からないのが困りました。
ハマったこと一覧
最終的にぶつかった問題をまとめるとこうなります。
| # | 起きたこと | ざっくり原因 |
|---|---|---|
| 1 | VHDX コピーしても動かない | WSL のレジストリ登録が別途必要だった |
| 2 |
wsl --import がエラー |
インポート先フォルダに残骸が残ってた |
| 3 |
Optimize-VHD が見つからない |
Hyper-V 管理ツールが無効だった |
| 4 | インポート後に root で起動する | デフォルトユーザー情報が引き継がれてない |
| 5 |
E_ACCESSDENIED で起動が不安定 |
VHDX のロック / 権限 / WSL サービスの状態 |
結論から言うと、これらは全部バラバラの問題じゃなくて、様々な前提条件が絡み合った結果でした。
2. まずやるべき診断 ― 現状把握のためのコマンド集
問題を切り分けるために、まず現状を正確に把握する必要があります。私が実際に使った診断コマンドを、Windows 側と Ubuntu 側に分けて紹介します。
Windows 側(PowerShell)
wsl --list --verbose
wsl --shutdown
3. よくある失敗パターンとその見分け方
今回の作業で遭遇した(または調査中に判明した)失敗パターンを、症状→見分け方→対処法 の形式でまとめます。
パターン A:インポート先フォルダが空でない
💥 症状
wsl --import 実行時に「インストール場所は既に使用されています」とエラーが出る。
🔍 見分け方
dir "D:\WSL\Ubuntu-22.04"
✅ 対処法
Remove-Item "D:\WSL\Ubuntu-22.04" -Recurse -Force
New-Item -ItemType Directory "D:\WSL\Ubuntu-22.04"
wsl --import Ubuntu-22.04 "D:\WSL\Ubuntu-22.04" "E:\TEMP\Ubuntu-22.04.tar"
パターン B:誤ったインポート引数でディストリビューション名が変わる
💥 症状
意図しない名前のディストリビューションがある。
🔍 見分け方
wsl --list --verbose
✅ 対処法
wsl --unregister ext4.vhdx
wsl --import Ubuntu-22.04 "D:\WSL\Ubuntu-22.04" "E:\Ubuntu-22.04.tar"
パターン C:デフォルトユーザーが root のまま
💥 症状
起動すると root@... でログインされる。/home にはユーザーディレクトリが存在しているのに。
🔍 見分け方
ls /home
✅ 対処法
Windows 側でデフォルトユーザーを再設定
ubuntu2204.exe config --default-user <ユーザー名>
パターン D:Optimize-VHD が使えない
💥 症状
-
Optimize-VHDコマンドが見つからない
🔍 見分け方
Get-Command Optimize-VHD
✅ 対処法
-
Hyper-V 管理ツールを有効化する(GUI の場合)
- 「Windows の機能の有効化または無効化」を開く
- 「Hyper-V 管理ツール」にチェック → 再起動
-
WSL 停止後に実行
wsl --shutdown
Optimize-VHD -Path "D:\WSL\Ubuntu-22.04\ext4.vhdx" -Mode Full
4. VHDX 圧縮前にやるべきクリーンアップ
Optimize-VHD や wsl --export の前に、再生成可能な不要データ を削除しておくと、ファイルサイズを大幅に削減できます。
優先度:高(削除で効果大)
| 対象 | コマンド | 理由 |
|---|---|---|
| apt キャッシュ | sudo apt clean && sudo apt autoremove -y |
.deb パッケージが大量に溜まる |
| pip キャッシュ | pip cache purge |
Python パッケージのキャッシュが肥大化 |
| Docker のイメージ/コンテナ | docker system prune -a -f |
Docker は VHDX を 急速に 肥大化させる |
優先度:中(効果あり)
| 対象 | コマンド |
|---|---|
| /tmp の一時ファイル | sudo rm -rf /tmp/* |
| journal ログ | sudo journalctl --vacuum-size=50M |
| npm / yarn キャッシュ | npm cache clean --force |
| 古いログファイル | sudo rm -f /var/log/*.gz /var/log/*.[0-9] |
⚠️ 絶対に消してはいけないもの
5. 実際に使った自動化スクリプト
毎回手動で同じコマンドを打つのは非効率なので、スクリプト化しました。実際に私の環境で使っているものをそのまま掲載します。
Ubuntu 内クリーンアップスクリプト
safe-clean.sh(クリックで展開)
#!/usr/bin/env bash
set -e
echo "=== APT キャッシュ削除 ==="
sudo apt clean
sudo apt autoremove -y
echo "=== pip キャッシュ削除 ==="
if command -v pip >/dev/null 2>&1; then
pip cache purge || true
fi
echo "=== npm キャッシュ削除 ==="
if command -v npm >/dev/null 2>&1; then
npm cache clean --force || true
fi
echo "=== /tmp の削除 ==="
sudo rm -rf /tmp/*
echo "=== journal の圧縮 ==="
sudo journalctl --vacuum-size=50M
echo "=== Docker のクリーンアップ(インストール済みの場合のみ) ==="
if command -v docker >/dev/null 2>&1; then
docker system prune -a -f || true
fi
echo "=== 不要ログ削除 ==="
sudo rm -f /var/log/*.gz
sudo rm -f /var/log/*.[0-9]
echo "=== 完了しました ==="
使い方:
nano safe-clean.sh
chmod +x safe-clean.sh
./safe-clean.sh
実行後、Windows 側で wsl --shutdown → Optimize-VHD を実行します。
6. おわりに ― 失敗を記録する価値
「VHDX をコピーすれば移るだろう」という直感は自然なものでした。
今回の一連の失敗でかなりの時間を消費しましたが、得たものは大きかったです。
- WSL が「単なるファイル」ではなく Windows のコンポーネント群と連携して動いている ことの理解
- Hyper-V 管理ツールの依存関係と、Windows のエディションによる制約
- VHDX の最適化が移行サイズに与える影響
- そして何より、「壊れない運用フロー」 を手に入れたこと
Discussion