WSL で systemctl が使えない(System has not been booted with systemd)
WSL の既定の init は systemd ではないため systemctl が動かない。/etc/wsl.conf に [boot] systemd=true を書いて wsl --shutdown で再起動すれば有効になる。
公開:
要約
WSL の中で systemctl を叩くとエラーになり、Docker や PostgreSQL をサービスとして起動できない。
sudo systemctl status sshSystem has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down原因は WSL が既定では systemd を PID 1 として起動していないことである。
WSL は独自の init プロセスで Linux を立ち上げるため、systemd を前提にしたコマンドがそのままでは通らない。
公式ドキュメント(新しいタブで開く)のとおり、/etc/wsl.conf に 2 行足して WSL を再起動すれば systemd が PID 1 になる。
設定はディストリビューションごとに独立している。
よくある原因
wsl.confに設定が無い: systemd はディストリビューションごとのオプトインで、既定では無効である。
Microsoft Store から入れた Ubuntu では最初から有効になっている場合もあるが、既存の環境を使い続けているなら書かれていないことが多い。wsl --shutdownをしていない:wsl.confは起動時にしか読まれない。
ウィンドウを閉じただけではディストリビューションのプロセスが残るため、設定を書いても反映されない。- WSL 本体が古い: systemd サポートは WSL 0.67.6 以降で入った。
Windows の「オプション機能」として入れた古い WSL のままだと、wsl.confに書いても無視される。 - WSL 1 で動いている: WSL 1 は Linux カーネルを持たず、システムコールを変換して動く方式なので systemd を有効にできない。
wsl -l -vの VERSION 列が 1 なら、まず WSL 2 へ変換する。 - セクション名が違う:
systemd=trueは[boot]セクションに置く必要がある。[wsl2]や[user]の下に書いても効かない。[boot]自体を書き忘れているケースも多い。
解決策
1. /etc/wsl.conf を書く
WSL の中で編集する。
ファイルが無ければ新規に作る。
sudo tee /etc/wsl.conf > /dev/null <<'EOF'
[boot]
systemd=true
EOF既に [boot] セクションがある場合は、その下に systemd=true の行を足す。
同じセクションを 2 つ書かないよう注意する。
2. wsl --shutdown で完全に止める
ここが抜けると設定が反映されない。Windows 側の PowerShell またはコマンドプロンプトで実行する。
wsl --shutdownすべてのディストリビューションと WSL の仮想マシンが停止する。
そのあと改めて端末を開くと、systemd が PID 1 として起動する。
確認は次のコマンドで行う。
ps -p 1 -o comm=
systemctl list-units --type=service --state=running1 行目が systemd を返せば成功である。
3. WSL 本体を更新する
wsl.conf を書いても変わらないときは、まず WSL のバージョンを見る。
wsl --versionこのコマンド自体が「認識されていない」と言われる場合、systemd をサポートしないビルドである。
ストア版へ更新する。
wsl --update更新後に wsl --shutdown をもう一度実行する。
4. WSL 1 なら WSL 2 に変換する
wsl -l -v
wsl --set-version Ubuntu 2変換はディスクイメージの作り直しになるため、サイズによっては数分から十数分かかる。
変換前にバックアップを取っておくと安全である。
なお、Windows のファイルシステム上のファイルへ大量にアクセスする用途では WSL 1 のほうが速いという性質があるので、変換の前に用途を確認しておくとよい。