はじめに
システム開発の現場を中心に近年はコンテナ技術が広く使われるようになり、Docker
とか Kubernetes
というソフトウェアの利用が常識になりつつある空気を感じます。
BizRobo!も既にコンテナには対応しており、インストールフォルダの配下には docker-win
内に各種サーバ機能の Dokerfile
や docker-compose.yml
のサンプルが提供されています。
今後社内の環境も Docker
に移行していこうかなと考えており、今回はその準備運動として業務PCへ Docker
を構築してみます。
BizRobo!における Docker の利用は、選択肢の提供という観点でマテリアル一式を製品同梱提供しています。
一方で Docker はOSS製品であり、その利用については導入者の判断により各自が運用できる範囲で採用すべきことは前提として記述しておきます。
WSLの利用要件
WSLとは Windows Subsystem for Linux の略称で、Windows OS上で Linuxを稼働させる仕組みです。現在はWSL2というのが最新ですが、ここ数年で頻繁にバージョンアップしており、バージョンごとの差異が大きく利用できるWindowsのバージョン(Windows10であってもバージョンは複数あり、、、)にも制約があったりで、直近まで興味はあれど着手はしない状態でした。
とはいえ先日ついにMicrosoft Store版が正式リリースし、「機は熟した」という判断のもと社内で利用していく動きを始めた次第です。
WSL+Dockerの利用条件は上記の文脈を含め書き出す1のが面倒なので、今回は以下のPCを「正」として進めていきます。
敢えて言うならば、BIOSレベルで 仮想化テクノロジー
2 が有効になっているPCをご用意ください。
エディション Windows 10 Pro
バージョン 22H2
インストール日 2023/01/17
OS ビルド 19045.2604
シリアル番号 YZ940095
エクスペリエンス Windows Feature Experience Pack 120.2212.4190.0
また、インターネットで「WSL2 インストール」などのキーワード検索で得られるページには軒並み
「Windows の機能の有効化または無効化」において
- Hyper-V
- Linux用 Windows サブシステム
- 仮想マシン プラットフォーム
- コンテナー
を有効化してください。
と記載があるものの、解説されているページによって対象としている項目にばらつきがあり、最低限何が本当に必要か不明だったため、今回は敢えて上記の項目はすべて「無効化」してインストールを実施します。(必要なものはインストールの過程で自動的に有効化されました)
最後に、インストール開始前にWSLの状態を確認します。
PS C:\xx\xx> wsl -l -v
Copyright (c) Microsoft Corporation. All rights reserved.
使用方法: wsl.exe [Argument]
引数:
:
WSLインストール前なのに「コマンドがありません」ではなく「使用方法」が表示されるのは違和感ですが、そういうものらしいので異常ではありません。
作業は主にWindows上のPowerShell
とWSL上の bash
を使って実施します。コマンド行の冒頭PS
から始まるものはPowerShell
のコマンド、~$
から始まるものは bash
のコマンドです。
WSLのインストール
PowerShell
を管理者権限で起動しwsl --install
とコマンドを実行することにより、後は自動的にインストールが実行されます。
PS C:\xx\xx> wsl --install
要求された操作には管理者特権が必要です。
:
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。
ただ今回はうっかり通常モードで実行してしまいました。
それが理由かインストール処理中は進捗表記が文字化けして焦りましたが、最終的には無事インストールできました。
インストールを完了させるために、Windowsを再起動しましょう。
再起動後、Windowsへログインするとコンソールが表示されるのでユーザー名とパスワード3を設定します。
Ubuntu は既にインストールされています。
Ubuntu を開始しています...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username ・・・.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: xx
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
:
既にWSLがインストールされている端末に対して再インストールを実施した場合、以下のようなエラーが表示された際には個別の対応が必要になります。
ディスク 'C:\xx\xx\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx'を WSL2 に接続できませんでした: 指定されたファイルが見つかりません。
Error code: Wsl/Service/CreateInstance/MountVhd/ERROR_FILE_NOT_FOUND
続行するには何かキーを押してください...
個別の対応詳細
PS C:\xx\xx> wsl -l -v
NAME STATE VERSION
* Ubuntu Stopped 2
PS C:\xx\xx> wsl --unregister Ubuntu
登録解除。
この操作を正しく終了しました。
解除したうえでディストリビューションを再セットアップ
PS C:\xx\xx> wsl -l -o
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl.exe --install <Distro>' を使用してインストールします。
NAME FRIENDLY NAME
Ubuntu Ubuntu
Debian Debian GNU/Linux
kali-linux Kali Linux Rolling
Ubuntu-18.04 Ubuntu 18.04 LTS
Ubuntu-20.04 Ubuntu 20.04 LTS
Ubuntu-22.04 Ubuntu 22.04 LTS
:
PS C:\xx\xx> wsl --install Ubuntu-22.04
インストール中: Ubuntu 22.04 LTS
Ubuntu 22.04 LTS はインストールされました。
Ubuntu 22.04 LTS を開始しています...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username ・・・.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: xx
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
:
xx@xx:~$
再度確認
PS C:\xx\xx> wsl -l -v
NAME STATE VERSION
* Ubuntu-22.04 Running 2
WSLの初期セットアップ
OSの最新化
Windows Updateのようなものですね、インストールしたOSのパッケージリストを最新化します。
xx@xx:~$ sudo apt-get update
[sudo] password for xx:
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
:
Need to get 33.6 MB of archives.
After this operation, 121 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 motd-news…
:
その後、最新化したパッケージリストに基づいてパッケージを最新化します。
xx@xx:~$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
:
Systemdを有効にする。
Systemdを有効化し、dockerがWSL起動時に自動的に立ち上がるようにします。
xx@xx:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2296 1608 ? Sl 22:49 0:00 /init
root 4 0.0 0.0 2312 68 ? Sl 22:49 0:00 plan9 --cont…
root 27 0.0 0.0 2300 100 ? Ss 22:49 0:00 /init
root 28 0.0 0.0 2316 104 ? R 22:49 0:00 /init
rpat 29 0.0 0.1 6080 5096 pts/1 Ss 22:49 0:00 -bash
rpat 1537 0.0 0.0 7480 3140 pts/1 R+ 22:59 0:00 ps aux
WSLの設定ファイルを編集
wsl.confファイルを編集し、[boot]以下の記述を追加します。
追記したら Ctrl+O
で保存し、 Ctrl+X
でエディタを閉じましょう。
xx@xx:~$ sudo nano /etc/wsl.conf
[boot]
systemd=true
WSLの再起動
設定内容を反映させるために、一度 PowerShell
から WSLを終了させて、再度起動します。4
PS C:\xx\xx> wsl --shutdown
WSL再起動後、実行プロセスの状況を ps aux
コマンドで確認します。
xx@xx:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 1.8 0.3 101408 12232 ? Ss 23:02 0:00 /sbin/init
root 2 0.0 0.0 2296 1236 ? Sl 23:02 0:00 /init
root 5 0.0 0.0 2312 68 ? Sl 23:02 0:00 plan9 --cont…
root 36 0.7 0.3 39472 14908 ? S<s 23:02 0:00 /lib/systemd/sy…
root 64 0.8 0.1 22084 5728 ? Ss 23:02 0:00 /lib/systemd/sy…
:
root 352 1.0 0.1 14692 6264 ? Ss 23:02 0:00 /lib/systemd/sy…
root 388 0.0 0.0 2300 100 ? Ss 23:02 0:00 /init
root 390 0.0 0.0 2316 104 ? R 23:02 0:00 /init
rpat 393 0.5 0.1 6080 5088 pts/0 Ss 23:02 0:00 -bash
root 394 0.2 0.1 7524 4880 pts/1 Ss 23:02 0:00 /bin/login -f
rpat 425 1.2 0.2 16940 9052 ? Ss 23:02 0:00 /lib/systemd/sy…
rpat 426 0.0 0.1 104192 4324 ? S 23:02 0:00 (sd-pam)
rpat 431 0.5 0.1 6120 4952 pts/1 S+ 23:02 0:00 -bash
rpat 448 0.0 0.0 7480 3124 pts/0 R+ 23:02 0:00 ps aux
PIDの1が /init から /sbin/init に代わっており、systemdが起動していればOKです。
Dockerのインストール
Windows PC上でDockerを使うなら Docker Desktop を利用するのが一番簡単だと思いますが、せっかくなので直接Dockerを使う選択をしました。
WSLから docker.io と docker-compose をインストールします。
今回の実施範囲で docker-compose は使いませんが、今後 Dockerを使っていくうえで必要になることは間違いないので一緒にインストールしておきます。
xx@xx:~$ sudo apt-get install docker.io docker-compose
[sudo] password for xx:
Reading package lists... Done
:
After this operation, 294 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 pigz amd64 2.6-1 [6…
:
Processing triggers for man-db (2.10.2-1) ...
インストールした docker のバージョンを確認します。
xx@xx:~$ docker -v
Docker version 20.10.21, build 20.10.21-0ubuntu1~22.04.2
インストールした docker-compose のバージョンを確認します。
xx@xx:~$ docker-compose -v
docker-compose version 1.29.2, build unknown
インストール時の状態では以下の様に docker
コマンドが実行できません(管理者権限が必要)。
xx@xx:~$ docker container ls
Got permission denied while trying to connect to the Docker daemon socket at
unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
xx@xx:~$
ログインユーザでも docker
コマンドを扱えるようにするために権限の付与を行います。
xx@xx:~$ sudo usermod -aG docker $USER
権限付与を反映させるために、一度 WSLのコンソールを閉じて開きなおします。
xx@xx:~$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
OKです。
MKDocsを使ってみよう
今回はマテリアルデザインを反映した Material for MKDocs
をDockerでセットアップして使ってみましょう。
Dockerでセットアップ
まずは、Dockerイメージがまだ存在していないことを確認します。
xx@xx:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
Docker.hubからMaterial for MKDocs
のイメージを取得します。
xx@xx:~$ docker pull squidfunk/mkdocs-material
Using default tag: latest
latest: Pulling from squidfunk/mkdocs-material
c158987b0551: Pull complete
:
docker.io/squidfunk/mkdocs-material:latest
ダウンロードしたイメージを確認します。
xx@xx:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
squidfunk/mkdocs-material latest 6f5d2266a3b6 17 hours ago 137MB
ワークフォルダの作成
MKDocsを使ってドキュメントを作成・編集する作業領域を作成します。
Windowsログインユーザのドキュメントフォルダに MKDocs
というフォルダを作成します。
WSL上でワークフォルダを指定してMKDocsを初期化します。
xx@xx:~$ docker run --rm -v /mnt/c/Users/xx/Documents/MKDocs:/docs squidfunk/mkdocs-material new .
INFO - Writing config file: ./mkdocs.yml
INFO - Writing initial docs: ./docs/index.md
-
-v /mnt/c/Users/xx/Documents/MKDocs:/docs
において Dockerコンテナ上のパスとWSL上のパスを紐づけます。Windows上のフォルダを指定する際には区切り文字は\
ではなく/
とし、/mnt/
から始める必要があります。 - 例えば
C:\Users\xx\Documents\MKDocs
は/mnt/c/Users/xx/Documents/MKDocs
と表すことができます。
MKDocsの設定
前段初期化処理にて生成された mkdocs.yml の内容を編集します。
テキストエディタを使って以下の様に追記し保存します。
site_name: My Docs
+ use_directory_urls: false
動かしてみる
MKDocsのサーバを起動し、ドキュメントを編集してみます。
xx@xx:~$ docker run -rm -it -p 8000:8000 -v /mnt/c/Users/xx/Documents/MKDocs:/docs squidfunk/mkdocs-material
:
production-ready server instead.
INFO - Building documentation...
INFO - Cleaning site directory
INFO - Documentation built in 0.21 seconds
INFO - [15:07:40] Watching paths for changes: 'docs', 'mkdocs.yml'
INFO - [15:07:40] Serving on http://0.0.0.0:8000/
サーバが動作している状態でワークフォルダ配下の docs
フォルダ内にテキストファイルを作成し、拡張子を .md
に変更すると、リアルタイムでサイト側のドキュメントに反映されます。
同様に、.md
ファイルに markdown
形式で記入した情報もファイルを保存するたびにサーバへ反映されます。
制的サイトのビルド
編集したオンラインドキュメントをビルドし、静的ファイルとしてローカルで利用できるようにしましょう。
実行中のコンテナを Ctrl+C
で一度停止し、以下のコマンドを打ちます。
xx@xx:~$ docker run --rm -v /mnt/c/Users/xx/Documents/MKDocs:/docs squidfunk/mkdocs-material build
INFO - Cleaning site directory
INFO - Building documentation to directory: /docs/site
INFO - Documentation built in 1.92 seconds
ワークフォルダ直下に site
というフォルダが生成され、静的サイトとして変換されたリソースが一式展開されます。
フォルダ内のindex.html
をダブルクリックすると、ドキュメントが再現されます。
さいごに:運用のための準備
ここまでで環境の構築手順と大まかな使い方がわかりました。今後MKDocsを使ってドキュメントの開発・管理を実施していくためにやるべきことは多く、次回続きを書く際にはドキュメントの運用システム観点になると思います。
最後に明日からのドキュメント開発に向けた手順とスクリプトを備忘として載せておきます。
新規ドキュメントの作成手順
- PCに Visual Studio Code をインストールします。
- 新しいドキュメントを作成するためのフォルダを任意の場所に作成し、以下の2つのPowerShellスクリプトファイルを配置します。
- 作成したフォルダ上でコンテキストメニュー(右クリック)を表示し、
Code で開く
を選択します。(当該フォルダをカレントフォルダとして Visual Studio Code を開きます)
- Visual Studio Code が起動したら
Ctrl + Shift + @
を押し、ターミナルを表示させます。 - ターミナルに
.\Start-MKDocs.ps1
と入力しEnter
を押すと、MKDocs が動き始めます。 - 終了する場合には必ず
Ctrl + C
で MKDocsサーバを停止しましょう。
# 実行ポートの指定
$port = "8001"
# WSLのDockerイメージを実行するPowerShellコマンド
function Run-DockerImage {
param(
[string]$image,
[string]$workdir,
[string]$volume,
[string]$portForward,
[string]$cmd
)
$volumeStr = "/mnt/c" + $volume.Replace('\', '/').Substring(2) + ":" + $workdir
if( $cmd -eq "new ."){
$dockerCmd = "docker run --rm -v $volumeStr $image $cmd"
} else {
$dockerCmd = "docker run --rm -it -p $portForward -v $volumeStr $image"
}
# WSLのDockerにアクセスしてコマンドを実行
& wsl sh -c $dockerCmd
}
# 現在のディレクトリパスを取得する
$currentDir = Split-Path -Parent $MyInvocation.MyCommand.Path
# フォルダが存在するかどうかを確認する
$folderPath = Join-Path $currentDir "docs"
if( !(Test-Path $folderPath) ){
# 新しいMKDocsプロジェクトを作成する
Run-DockerImage `
-image "squidfunk/mkdocs-material" `
-workdir "/docs" `
-volume $currentDir + ":/docs" `
-cmd "new ."
}
# MKDocsサーバーを起動する
Run-DockerImage `
-image "squidfunk/mkdocs-material" `
-workdir "/docs" `
-volume $currentDir + ":/docs" `
-portForward ($port + ":8000")
# サーバーが起動したらブラウザで表示する
Start-Process "http://localhost:$port"
# WSLのDockerイメージを実行するPowerShellコマンド
function Run-DockerImage {
param(
[string]$image,
[string]$workdir,
[string]$volume,
[string]$cmd
)
$volumeStr = "/mnt/c" + $volume.Replace('\', '/').Substring(2) + ":" + $workdir
$dockerCmd = "docker run --rm -v $volumeStr $image $cmd"
# WSLのDockerにアクセスしてコマンドを実行
& wsl sh -c $dockerCmd
}
# 現在のディレクトリパスを取得する
$currentDir = Split-Path -Parent $MyInvocation.MyCommand.Path
# 新しいMKDocsプロジェクトを作成する
Run-DockerImage `
-image "squidfunk/mkdocs-material" `
-workdir "/docs" `
-volume $currentDir + ":/docs" `
-cmd "build"
既存ドキュメントの編集
新規ドキュメントの作成と手順は同じです。実行する .\Start-MKDocs.ps1
プログラムがフォルダの状況を判断し処理します。
作成したドキュメントのビルド
ドキュメントの新規作成と同様に Visual Studio Code のターミナルを開き、.\Build-MKDocs.ps1
と入力し Enter
を押します。
まとめ
DockerというとLinuxコンテナがメインストリームだと思います。Windowsコンテナという方法もありますが、自分たちでまず使用してみようと調べた範囲ではメリットが感じられませんでした。(PCで使う前提だったので)
ということで Docker を使用するための最低限の Linux の知識は必要ですね。
今後、開発環境や検証環境などできるだけ便利に Docker を活用していきたいと思います。
テクサポなどは不具合発生時に複数バージョンの環境で確認作業が必要になる場合もありますが、そのたびにサーバを準備するのは大変ですし、サーバも使い込めば環境が徐々に汚れていきます。
そんな時には Docker をうまく使っていつもクリーンな環境をコマンド一発で構築することで検証・再現テストの準備工数はだいぶ削減できるのかもしれません。(知らんけど)
-
各WSLのバージョンにより何がどう違うのかという情報は別途よくまとめられているページがインターネット上にはたくさんあるので、正確で詳しい解説はそちらに譲ります。 ↩
-
仮想化テクノロジーに対応しており有効かどうかについては、以下の様にタスクマネージャ > パフォーマンスの画面から確認ください。画面右下部分の「仮想化:」が
有効
であれば大丈夫です。
↩ -
WSL上で動作するディストリビューションのユーザ名とパスワードです。 ↩
-
WSLを起動する方法としては、
PowerShell
やcmd
から wslコマンドを実行して起動する方法の他、スタートメニューからWSLを選択してコンソールを起動する方法、インストールしたディストリビューション(Ubuntuなど)を同じくスタートメニューから選択してコンソールを起動する方法などがあります。 ↩