どうでも良い背景
WSLの登場でWindowsでもWeb開発がしやすくなったがいつからかdockerが動かなくなってしまったらしい.まぁdockerの思想や性質を考えるとWindowsでLinuxのコンテナが使えること自体が異常な気もするんだけども.ともあれ,WSL2とは相性が良くなったらしい.
僕は自宅でサーバーを動かしていて,MinecraftサーバーやらDiscordのミュージックボットやらを提供している.仕事でやっているわけではなく趣味の範囲なので,全部同居しているのだが,そうするとだんだん環境がカオスになってきて手に負えなくなりそうだったので,半年ぐらい前にdockerを導入してサービスを切り分けた.
そこまでは良かったんだが,サービスを立ち上げるまでの試行錯誤をサーバー上のviでガシガシ書くのは流石に骨が折れる.変数を少し変えるだけならいざ知らず,1から建てるとなるとなかなかのコストになるので,vscode使いとしては普段使いのPCで作業して,アップをしたいわけ.そこでいろいろ方法を考えた
- SFTPで接続してリモートとローカルを同期する
- セキュリティのためにrootでのSSHログインを許可していない
- rootしかアクセス許可してないディレクトリだとroot以外のユーザーはパーミションエラー
- 上記2点をクリアするためにはセキュリティを下げるしか無いため断念.
- GitHubでpush&pull
- とにかくめんどくさい
- そもそも動くかわかってないものを上げてるとなんでコミットしてるんだっけ?ってなる
- 今まではとりあえずなんとかやってきたんだが,限界を感じてしまった
- Windows desktop向けのdockerを導入してWSLから使えるようにする
- 色々設定が面倒くさそう
- そもそも設定したところで推奨されているわけではないので使えなくなる可能性がある
まぁこんなところで思案していて,dockerが普通に動かせるようになったと噂のWSL2を試してみることにした.
WSLとWSL2の違いについて簡単に解説
自分の情報整理のために,WSLとWSL2の違いが何なのか,dockerを使うという観点から解説する.厳密には間違っている可能性は多々あるので,正確な情報が知りたい人は公式ドキュメントを読むと良いだろう.
ざっくりと説明すると,WSLはLinuxのカーネルをエミュレートしていて,WSL2では仮想マシンを裏で立ち上げ,そのカーネルを使うという方式に切り替わったらしい.WSLからWSL2に変えるとファイルの読み込みが遅くなるというのはこのあたりに起因する.
LinuxとWindowsはそれぞれ違うファイルシステムを使っていて,WSLの時代では全てWindowsのファイルシステムで動いていたからファイルの読み込みに時間がかからなかったわけ.その代わりLinuxのファイルシステムをエミュレートするわけだから,コマンドの実効速度が遅いってわけ.
対してWSL2ではゲスト側のLinuxが仮想マシンとして動いていて(つまりファイルシステムがそもそもLinux),ホストマシンのディレクトリは/mnt/以下にマウントされているという状況になっている.だからコマンドの実効速度自体は速い.ただし,ホストマシンのファイルとのやりとりはどうやらTCPかなにかの通信をしてネットワーク越しの通信のようなことをしているらしい.だからホストゲスト間のディレクトリをまたいだやり方は問題が起きやすい(某白笛並感)
ちなみに,コマンド実行は速いとは言ったものの,そのコマンド自体がファイルアクセスを伴うコマンドだった場合にはとにかく実行が遅い.lsコマンドにしても数秒遅れるみたいな状況で,ともすれば画面をたたき割りかねないような環境になる.
今回やったこと(できたこと)
- WSLの環境をそのままWSL2にお引っ越しできた
- WSL時代にWindows側の%Users/(user name)/wslというディレクトリにおいてあったホームディレクトリをLinux側の/home/(user name)に移動した
- dockerを動かしてローカルで実験できる環境が整った
個人的に心配だったWSLの開発環境をそのままWSL2に持って行けるのか?という問題については,コンバートすればそのまま使えるという知見を得たので,心配な人は安心して欲しい.
WSL to WSL2
まず大前提としてWSL2を使いたかったら今ならWindowsのバージョンを2004に上げる必要がある.(プレビュー機能として使えなくは無いが,2004に上げてデフォルトで使えるようにする方が無難だろう.何を言ってるかわからない人はこのページを見ないとは思うが,万が一わからない場合はWinボタンを押してwinverと入力してEnterすれば幸せになれると思う)
WSL2の使用前にHyper-Vを有効にする必要があるが,WSLを使っていた人ならこの辺はONになっているはずで,特に操作は必要無いと思う.(ちなみに,Hyper-Vを有効にすると,サードパーティ製の仮想マシンはもれなく死ぬ)
次に,WSL2を有効にするにはWSL2向けのLinuxカーネルコンポーネントの更新がいるらしい.Microsoftのページから「最新のWSL2 Linuxカーネル更新プログラムパッケージをダウンロード」とあるので,そちらをインストールする.詳しくはリンク先に書いてある.
前準備が終わったら管理者権限でPowerShellを立ち上げて,以下のコマンドを入力する.必須ではないが,Web開発をするためにWSL使ってるならWSLを使いたい理由は特にないと思うし,やっちゃっても特に問題は無いんじゃないだろうか.言うまでも無いが,デフォルトのWSLのバージョンを2にするだけ.
wsl --set-default-version 2
既存のWSL環境をWSL2にコンバートするには以下のコマンドを実行する.コマンドを見る限りWSL2からWSLへもコンバートできるみたい(未検証).
wsl --set-version <distribution name> <version>
versionはWSL2にしたいなら2とする.distribution nameはWSLを入れるときにMicrosoft StoreからインストールしたLinuxの名前だが,わからない場合は以下のコマンドで確認できる.NAMEの欄がdistribution nameに対応している.
wsl --list --verbose
WSLがWSL2に切り替わったか確認したいときも同じコマンドでVERSIONの項目を見ればOKだ.
homeディレクトリを使いやすくしたい
さて,homeディレクトリの位置を弄ってない人は特に気にならないかも知れないが,僕はWSLを使っていたときにアクセスしやすいようhomeディレクトリの位置をWindowsのユーザーディレクトリの下に置いていた.そのせいで,WSLからWSL2にコンバートした直後は笑えるぐらいコマンド一つ一つに時間がかかった.
これでは使い物にならないと/home/(user name)にホームディレクトリの位置を戻した.ちなみにやった操作としては,/etc/passwdを直接viエディタで弄っただけだ.
しかしこれでめでたしめでたしと言うわけにはいかない(個人的こだわり).そもそもアクセスしにくいからホームディレクトリを移していたのに,元の位置に戻したらまたアクセスしづらくなる.ゲストtoホストのファイル操作はめったに無いが,ホストtoゲストのファイル操作はチョコチョコ必要になったりする.
上の方でも少し触れたが,ホストtoゲストはネットワーク越しのようにアクセスすることが出来る.\\wsl$\<distribution name>\home\<user name>
というアドレスをエクスプローラに入れる事で,アクセスが出来る.つまり,ネットワークドライブとして認識が出来るので,エクスプローラにネットワークドライブとして登録できる(というか登録した.毎回探すのは面倒だから)
余談だが,調べてみたらどうやらWSLにはあらかじめ特別なコマンドが用意されていて,explorer.exe .
と入力すればカレントディレクトリがホスト側のエクスプローラで開けるらしい.(今まで知らなかったが結構便利だなぁ・・・)
docker(は特に語ること無いけど少しだけ)
WSL2を入れた状態でdockerをインストールすると,WSL2にインテグレートするかどうかをインストール時に聞いてくれる.これにチェックを入れておくと,次回のWSL2起動からdockerkコマンドがLinux環境よろしく使えるようになっている.
ちなみに,この記事を書いている最中にdockerがアップデートに失敗してアンインストールだけ綺麗にしちゃってくれたのだが,その状態だとzshでdockerコマンドの予測は出るが,実行するとコマンドがないっていうギャグみたいな状況が発生した.
まとめその他
やはりdockerをローカルから使えると開発が捗る.業務ではMacを使っているのだが,わざわざ使う必要性もないのかなと感じている.Winのデフォルト文字コードがUTF8になったしね.
WSL2はWSLの単純な上位互換とはいかず,今のところ一長一短といった感じだ.が,Linux環境で閉じた作業しかしない人ならWSL2への以降をした方が絶対に良いと思う.WSL側からWinのファイルシステムを使うのがメインの人はWSLを維持した方が良い.どちらもやるというひとなら,WSLとWSL2の環境をそれぞれ用意するという方法が良さそうだ.ちゃんと調べてはいないが,コマンドの使い方などから察するに,そもそも複数環境セットアップできるような設計になっているような気がする.