前回のログでは、WSL2上へRocky Linuxを導入し、ホストOS側のメモリ圧迫を抑えるためのリソース制御を実装しました。
本記事では、そのRocky Linux環境をサーバー基盤として利用するため、AnsibleによるDocker環境構築と、Systemd有効化に伴って発生した起動エラーへの対応を記録します。
1. rootログインとディレクトリパスの不一致
Rocky Linux環境への移行完了後、初期構築のためPowerShell経由でログインを実行した際、WSL特有の挙動を観測しました。
本記事では、実際に実行する操作を COMMAND、設定ファイルを CONFIG、正常な実行結果を OUTPUT、発生したエラーを ERROR LOG として分けて記録します。
// 1. rootログインとディレクトリの不一致
Linux環境へアタッチした状態でありながら、カレントディレクトリがホスト(Windows)側の C:\Users\user を参照しています。また、手動インポートしたOSイメージの仕様上デフォルトユーザーが未定義のため、強制的に root 権限でログインされる状態を確認しました。
wsl -d Rocky9
pwdPS C:\Users\user> wsl -d Rocky9
wsl: Processing /etc/fstab with mount -a failed.
[root@WIN-VTG7SBKQG11 user]#
[root@WIN-VTG7SBKQG11 user]# pwd
/mnt/c/Users/userroot権限での恒常的なオペレーションは重大なインシデントを招くリスクがあるため、ホームディレクトリへ移動後、運用操作用の一般ユーザーをプロビジョニングします。
cd ~
pwd
useradd haruuu
passwd haruuu
usermod -aG wheel haruuu[root@WIN-VTG7SBKQG11 user]# cd ~
[root@WIN-VTG7SBKQG11 ~]# pwd
/root
[root@WIN-VTG7SBKQG11 ~]# useradd haruuu
[root@WIN-VTG7SBKQG11 ~]# passwd haruuu
Changing password for user haruuu.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@WIN-VTG7SBKQG11 ~]# usermod -aG wheel haruuu// 2. wsl.confの設定と再起動の仕様
Dockerデーモンの常駐化に必要な systemd の有効化、およびデフォルトユーザーの指定を実施します。/etc/wsl.conf を生成し、以下の構成を定義しました。
vi /etc/wsl.conf
cat /etc/wsl.conf[boot]
systemd=true
[user]
default=haruuu設定の適用にはWSL仮想マシンの再起動が必要です。しかし、ゲストOS側から wsl —shutdown を発行してもコマンドは認識されません。
wsl --shutdown
wsl -shutdown[root@WIN-VTG7SBKQG11 ~]# wsl --shutdown
-bash: wsl: command not found
[root@WIN-VTG7SBKQG11 ~]# cd ..
[root@WIN-VTG7SBKQG11 /]# wsl -shutdown
-bash: wsl: command not foundWSLの管理コマンドはホスト側の実行ファイルであるため、ホスト側のPowerShellからシャットダウンコマンドを発行する必要があります。再起動後、指定した一般ユーザーでログインが行われ、Systemdが active 状態へ移行したことを確認しました。
2. WSL2におけるSystemd有効化の技術的要件
// 1. Systemdがデフォルトで無効化されている技術的背景
WSL2は本来、「ホストOSと密結合した軽量な開発環境」として設計されており、起動速度を最適化するため、Microsoft独自の init プロセスを PID 1 として稼働させています。一方、systemd も PID 1 としての動作を要求するアーキテクチャであるため、標準のWSL環境では競合が発生し、初期状態では無効化されている仕様となっています。
// 2. サーバー運用におけるSystemd有効化の合理性
本環境の構築要件は、Ansibleによるサービス構成管理とDockerコンテナの常駐化を前提とした「サーバーインフラの構築」です。Systemdを無効化した状態では、ホスト再起動のたびに手動で dockerd を起動するオペレーションが発生し、運用保守性が著しく低下します。
IaCによる構成管理を完結させ、Dockerエンジンの自動起動を担保するためには、Linux標準のサービス管理デーモンである systemd の導入が必須要件となります。WSL2の「動的リソース割り当て」の恩恵を維持しつつ、サーバーとしての可用性を確保するためのアーキテクチャ設計です。
3. Ansibleの導入とPlaybookの実行
マニュアルオペレーションによる構成ドリフトを排除するため、以降のDockerエンジンのデプロイはすべて Ansible(IaC) による自動化パイプラインへ委譲します。事前準備として、EPELリポジトリおよびAnsibleパッケージを導入します。
sudo dnf install epel-release -y
sudo dnf install ansible -y// 1. Playbookの作成と確認
続いて、Dockerのインストールからサービス起動までのステート(状態)を定義したPlaybookを記述します。
cat docker-install.yml---
- name: Install Docker and Docker Compose on Rocky Linux
hosts: localhost
connection: local
become: yes
tasks:
- name: Install dnf-plugins-core
dnf:
name: dnf-plugins-core
state: present
- name: Add Docker CE repository
command: dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
args:
creates: /etc/yum.repos.d/docker-ce.repo
- name: Install Docker CE and related packages
dnf:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
- name: Start and enable Docker service
systemd:
name: docker
state: started
enabled: yes
- name: Add current user to docker group
user:
name: "{{ ansible_user_id }}"
groups: docker
append: yes
Dockerのインストールからサービス起動、ユーザーのグループ追加までを定義
// 2. Playbookの実行とエラー
Playbookの定義完了後、ansible-playbook docker-install.yml -K コマンドを発行し、プロビジョニングを実行します。
ansible-playbook docker-install.yml -K
Dockerサービスの起動タスクで「Job for docker.service canceled」が発生し処理が中断
プロビジョニングの過程において、Dockerサービスの起動タスクで Job for docker.service canceled. エラーが出力され、タスクが中断されました。原因特定のための切り分け作業へ移行します。
4. Systemdによる起動キャンセルとfstabの修正
Dockerデーモンの起動キャンセルを引き起こした根本原因(Root Cause)の特定プロセスを記録します。
// 1. dockerdによる切り分け調査
対象がDockerエンジン側の不具合か、Systemd側の制御によるものかを切り分けるため、Systemdをバイパスし sudo dockerd コマンドによるデーモンの直接起動を検証しました。
sudo dockerd[haruuu@WIN-VTG7SBKQG11 ~]$ sudo dockerd
INFO[2026-04-18T04:10:35.992869846+09:00] Starting up
INFO[2026-04-18T04:10:35.995305823+09:00] containerd not running, starting managed containerd
(中略)
INFO[2026-04-18T04:10:36.569376121+09:00] Daemon has completed initialization
INFO[2026-04-18T04:10:36.569463368+09:00] API listen on /var/run/docker.sock検証の結果、デーモンは正常に初期化され API listen 状態へ移行しました。これによりDockerバイナリ自体は正常であり、Systemd側の制御シーケンスによって起動要求がブロックされている状態であることが確定しました。
// 2. journalctlによるマウントエラーの特定
Systemdが起動プロセスを中断した理由を追跡するため、journalctl コマンドを発行し、システム全体のジャーナルログを解析します。
journalctl -xbApr 18 14:48:57 WIN-VTG7SBKQG11 systemd[1]: Timed out waiting for device /dev/disk/by-uuid/42A7-33E4.
Apr 18 14:48:57 WIN-VTG7SBKQG11 systemd[1]: Dependency failed for Local File Systems.
Apr 18 14:48:57 WIN-VTG7SBKQG11 systemd[1]: Reached target Emergency Mode.
タイムアウトによりLocal File Systemsの依存関係に失敗し、Emergency Modeに到達しているログ
解析の結果、手動インポートに使用したRocky Linuxイメージ内の /etc/fstab に、ビルド環境の古いディスク識別子(UUID)が残留していることが判明しました。
Systemdを有効化したことにより、起動シーケンスにおいてディスクボリュームの整合性チェックが厳格化され、存在しないUUIDのマウント試行によるタイムアウトが発生。結果としてOS全体が Emergency Mode へフォールバックし、依存関係にあるすべてのサービス(Docker含む)の起動がシステムレベルでリジェクトされる事象に至りました。
対応策として、/etc/fstab を編集し、不要なマウント設定を無効化(コメントアウト)しました。本インシデントの発生は、WSL環境上のRocky Linuxが正常にSystemd配下の厳密なプロセス管理下へ移行したことを証明する挙動でもあります。
# /etc/fstab
# UUID=22de856b... / xfs defaults 0 0
# UUID=78dc1719... /boot xfs defaults 0 0
fstabの修正とOS再起動後、Dockerサービスが正常に active (running) になったことを確認
5. タスクの冪等性確認とIaC運用方針
fstabの修正によるインシデント解消後、再度 Playbook を実行し、中断されたプロビジョニングタスクを完了させます。
// 1. 差分のみを適用する冪等性
ansible-playbook docker-install.yml -KPLAY RECAP *******************************************************************
localhost : ok=6 changed=1 unreachable=0 failed=0
ok=6 changed=1 failed=0。前回失敗したタスクのみが実行され、冪等性が確認できる
実行ログの通り、前回のエラーで未実行となっていたタスクのみが適用(changed=1)され、インストール済みのパッケージタスクはスキップ(ok=6)されました。システムの現在状態を評価し、差分のみを収束させるAnsibleの「冪等性(べきとうせい)」が正常に機能していることを確認しました。
// 2. 今後の運用とGit連携について
今後の運用ルールとして、インフラ構成の変更はすべてPlaybookのコード修正を起点とします。ホスト内での直接的なコマンド実行(手動オペレーション)を避けることで、コードと実環境の乖離(構成ドリフト)を抑制します。
現在は初期プロビジョニングフェーズのためローカルホスト上でPlaybookを実行していますが、基盤構築完了後はこれらをGitHubリポジトリへ統合し、GitをSingle Source of Truth(信頼できる唯一の情報源)とするGitOpsの運用形態へ移行する計画です。
6. Minecraft(Pixelmon)サーバーのコンテナデプロイ
インシデント対応を完了し、WSL2上のRocky Linux環境へ正常なDockerエンジンがデプロイされました。これにより、コンテナをホストするためのインフラ基盤構築フェーズが完了しました。
次回のログでは、構築したDocker基盤上へ docker-compose.yml を定義し、主要ワークロードであるMinecraft(Pixelmon)サーバーコンテナのデプロイを実施します。Volumeマウントによるデータの永続化や起動制御など、アプリケーション層のコンテナ運用要件を実装します。