Docker Desktop for Windows と WSL (Windows Subsystem for Linux) の導入は(オレ以外には)簡単だったぜっ、というか Docker の前提となる WSL2 がそもそもステキ、な話

遅ればせながら過ぎやしないか、なんてツッコミは入れないこと。こういうのに気付くのが遅れるヒトなのです、ワタシは。

2022-03-15 17時追記:
いきなり追記からですまん。最初に後ろのほうの「2022-03-15 17時追記」から読んでもらえると助かる。

もっと整理できてから書く手もあるんだけれど、「導入の苦労は人柱だけの特権」部分は熱いうちに、と思ったんで、ざっくりとした話だけでもと思って。

まずざっくりと前提の話:

  • Docker と WSL は、一応テクノロジーとしては各々独立したもの
  • Docker for Windows は WSL を利用する形で「linux 対応コンテナ」を成立させている
  • ともに大きく言えば「仮想化」のテクノロジだが、コンセプトがかなり違う
  • WSL は従来型の仮想化にほぼ同じコンセプト、VirtualBox みたいなの相当
  • Docker は同じ仮想化でも、たとえば Python でいうところの venv/virtialenv/pyvenv のような「隔離環境」がキーコンセプト

説明はちょっと雑かもしんない。間違いなく個々の公式に出向いたほうがいい。遥かに簡単に理解できるハズ。Docker は、Windows のケースだと、「Windows の中と、WSL 上に乗っけた linux (ubuntu など)の両方に小さな独立国を作る」(→2022-05-24追記参照)。「オールインワンほにゃらら」というプロジェクトはこれまで経験してきたかな? Docker が担うのは、いわばそれ。個々人の実行環境に振り回されないアプリケーション開発の助けになるもの、てこと。「動作に必要なものを全部同梱して配布する」ということをしたい、がためのものね。

Docker Desktop for Windows の導入の際の問題、というのがね、実に「知ってれば避けられる」の。簡単だよ、

この Microsoft による導入手順手順6(または「ディストリビューションのダウンロード」)まで全部終わらせてから Docker Desktop をインストールすること

これだけ。

Docker が「クロスプラットフォームで動作するアプリケーション」を主目的としてるから「WSL 必須」なんてことになっちゃってるんだけど、本当はこれ、おかしいんだよね。コンテナの概念は、何も「クロスプラットフォームねばならぬ」ものに限定されるもんでもないわけだよ、Windows どうしですら「ランタイム環境問題」というのは付き物なのだから。けどとにかく Docker Desktop は WSL2 が動作していることを大前提としてしまう(→「2022-05-22追記」参照)、てこと。そして、それだけならまぁいいんだけれど、「WSL が動作していない状態で先に Docker Desktop を起動してしまうと「docker desktop is shutting down.」から二度と抜け出せなくなる」というのが問題なのよ、しかもこいつ、オートスタートアップの常駐ものだもんで、再起動だののたんびにこのエラーを食らい続け、「手順6を終わらせても解消しない」。これは作りが悪いね。

異常状態を永続化してしまうという、まぁかなり基礎的なチョンボだし、ちゃんと issue には上がってるので、きっとすぐに修正されるだろうと思う。けれども「Docker Desktop は WSL が予め動作していることを前提としている」ということだけだからさ、ワタシのあとで興味を持って入れてみたい人にとっては、そのバグは「どうでもいい」ものであるハズ。「手順6を終わらせても解消しない」については、ワタシの場合は

  • c:/Users/hhsprings/AppData/Roaming/Docker
  • c:/Users/hhsprings/AppData/Roaming/Docker Desktop

というフォルダを消すだけ。消して起動しなおすなりマシン再起動で Docker Desktop は動作するようになる。措置も簡単だけれど、そもそも WSL の導入には個々のステップが時間がかかるものもある上に、本当に何度も再起動を要求されるヘビィなタスクなので、こういう「些細な手間」だって、ない方が良いでしょそら。

Docker Desktop については、ワタシはまだ getting-started がちゃんと動作するのを確認しただけ。さっと終わらせたんでちょっと記憶あいまいだけど、たぶん Windows 側のだけを動かしたんだと思う。node.js による http サーバの例で、Docker 自身のドキュメントをサービスするもの、だったかと思う。コンテナ内のポート80とホストのポート80をマッピングして、ブラウザで…、みたいな。まだ Docker についてはあんましピンと来てないがとにかく「これから Docker れるぜ」の環境は出来上がった模様、として、そちらについては一旦満足しておいた。これから、こっちは。

なお、細かいことを言えば、(今回の主題でもある)「Docker はいいからとにかくまずは WSL だぜ、きゃーすてきー、使い倒したるぜっ」のつもりなら、「好き勝手に汚し続けたい環境とクリーンな環境を分けておきたい」のために distro の複製を先に考えといたほうがいい。export でコピー、import で取り込んで、distribute で実行ね、ドキュメント参照。最初にやっといたらいいんじゃないかな。あとからクリーン環境を作り直すのが若干面倒なのよ、Microsoft Store の振る舞いの関係で。(「インストール」ボタンが完了しないように見える変な事象がある。)

2022-03-15 15時追記:
今気づいた。人によっては凄まじく大事な話。

WSL 導入によって「c:/Windows/System32/bash.exe」が組み込まれてしまうので、ほかの似非 Unix、たとえばワタシの場合なら MSYS を使っているユーザは注意。たぶん Git for Windows ユーザもそうじゃないかな。これ、wsl コマンドを使って bash を起動しようとするのと同じことをするものみたい。いらねー…。まぁ各々考えてくれ。人によって色々事情は違うと思うので。てことだが、そもそもコマンドプロンプト内だと PATH の指定を無視してこの WSL 版 bash.exe を優先するみたいなので、おそらく「望みの(ワタシのケースでは MSYS の)bash.exe を起動したいならフルパスで」かなぁと思う。

「コンテナの概念と「クロスプラットフォーム」の概念は本来独立じゃない?」と思うので、Docker が WSL に必須依存してしまうこと自体は、ワタシはちょっと理解できないところはあるんだけれど、けどね、怪我の功名よ、「あ、なんかこの WSL/WSL2、ぱねー」。

ひとつ前のネタでちょっと書いたけれど、もしも SFU (Windows Services for UNIX) の経験があるなら是非あれを思い出してもらいたい。仮想化は仮想化でも、VirtualBox などで「フルスペックで動作させようとするエミュレーション」よりは、エンドユーザ目線だと SFU に近い体験となる。あの「すさまじく使いにくかった SFU が強烈に使いやすくなったもの」と言えば、きっとわかる人はわかる。あるいは MSYS や cygwin を日常使いしてるなら、「msys や cygwin のようなまがい物でなくちゃんと本物の Unix が MSYS や cygwin と大差ない使用感で使える」と思ってくれればいい。Unix にある Windows エミュレーションの wine とか知ってるなら、それを思い浮かべてもいい、使用感はそれに近い。いや、見てもらったほうがいいと思うんだよね:

WSL2 内でのネットワークの問題と、wsl.exe と MSYS の相性の問題はあったけれどね、でも、もうね…、ほんとに「完全な Windows 上で完全な linux がかなりシームレスに動いてる」のってっばさ、かなり格別よ、とてつもなく快適。ファイルのやり取りとかもかなりシームレスに出来るし、クリップボード連携も直観通りに振る舞い、通信も VirtualBox 等の経験があれば、それと変わらない。うん、ステキ。
しかもねこいつ、

Windows 上で linux コマンドが動くというのみならず
linux 上で Windows コマンドが動く

のよ。だからね、たとえば ffmpeg の Unix と Windows での振る舞いの違い、なんてのを、同じ ubuntu.exe のコンソールで確認出来たりするんだ、これが。

一番最後の絵の wsl -d での起動は専用ランチャからの起動とちょっと振る舞いが違って少し気持ち悪いところもあるんだけれど、まぁそういうもんだと思っておこう。ただ… wsl –export で例えばある時点でのスナップショットをとるとかしたものを wsl --import して使う、みたいなシナリオではランチャがないので wsl -d (wsl --distribute) しか選べなくてね、これはちょっとだけ不満かも。


Windows 11 にしないと linux の GUI が WSL2 では使えないので「フルスペックのデスクトップ linux」を乗っけた VirtualBox (など)との比較は単純には出来ないけれど、けどね、ほんっと「二つの OS が動いてる」なんて風には全然思わないほど軽い。正直 MSYS 使ってんのと全然変わらない。こいつぁいいオモチャを見つけたわい。というかさ、昔を知ってると、ほんと、いい時代になった、と思う。ありがとう、Microsoft さま、て感じ。

GUI が使えないとはいえ「それ以外は完全な linux」なので、たとえば「linux でしか動かない or Windows では構築が超絶にめんどい」もので遊び放題、てことだよ。今でも「Windows では出来ない」とか「Windows でだけ面倒くさい」という OSS なんぞ山ほどあるわけよ、そういうときに、かなりこれは救世主なわけね。あとワタシみたいにちょっと OSS に関与してたりすると、まさに「クロスプラットフォームで動作するもの」を書く必要がある機会が多いので、その時の検証や開発の手助けにもなる、てことね。Docker はそのもう一歩先。そちらは「実ホストと実 WSL ディストリビューションを汚さないサンドボックス環境で開発する」ためのもの。なので当然すさまじくありがたいものだよ、だけど、ワタシとしてはまず「WSL さんありがとう」てことね。

色んなこと出来るよね。C/S アーキテクチャを採用しているものの「サーバ側」が Unix 系でしかちゃんと保守されてない、なんてのは非常に多くて、ワタシが最近やったやつなら Redis の Spatial 拡張がそうね。うん、これ、あとでやってみようかなぁ。

「PHP for Windows」なんてのは「トラウマになる体験」のワースト5には入るんじゃないかというほどヒドいものだが、こういのも、linux でやるなら驚くほどシンプルだったりするでしょ。地図サーバとかの類もそうね、Windows と Unix とでは簡単さに天と地ほどの違いがある。cartopy ネタを始めとする GIS ネタや気象ネタなどの学問分野系にはたぶんそんなのが大量にある。GDAL/OGS 関連のものとか PostGIS、あるいは機械学習系なんぞも、「Windows でも出来ないことはないが linux の方が一億倍は楽」なんてのはとても多い。

あ…危ない、一つ言い忘れた。「本物の linux」と言ってきたけど、むろん厳密には違うよ。一つ層が余計に挟まってるのは話として無視できるとしても、「ブート・ログイン」の一連はまったくノリが違う。最初にユーザを作ったあとは、そのユーザでの「認証不要の自動ログイン」になるので。ここは「本当の本物 Unix」とは違うので一応注意ね。けど MSYS/cygwin に比較すればはるかに何億倍も「ちゃんと本物」であることには違いはないわけだけれども。


ところで、「遅ればせた理由」なんだけれど、当然積極的に情報収集してこなかったワタシ自身の問題もあるにはあるけれど、多くの人にとっても共通なのは、これが「Windows 10 からのテクノロジであること」てことね。Windows 10 より前は、こんなのはなかったので、VirtualBox などに頼るしかなかった。いっとき太っ腹に VirtualPC を無料で使えるようにしていた Microsoft も、「プロフェッショナルエディション限定」みたいなことをしてたので、実質 VirtualBox 一択の時代が長かったかと思う。

「Windows 10 ではまだ linux GUI が使えないので」というのと、Microsoft 管理外のディストリビューションを使いたい場合などもあるので、WSL の存在が VirtualBox の意義をなくすことにはならないけれど、でもね、ワタシ個人としては割と「Unix 依存の 70~80% くらいは CUI だけでまかなえるツールに収まる」の。だからワタシの場合は、VirtualBox を使う機会は格段に減ると思う。

いつもながら気づくの遅くて人生損してたなー、とは思う、けど、「人生これからだ、たぶん」。


ところで、Docker を使うにあたって、Windows をホストにする場合はこんな感じで「Windows と linux の二つに対応」するようなコンテナを作れる、てことになるわけだよねきっと、けど、そういやぁホストが Unix や Mac の場合って、Windows 環境はどうなるんだ? そうのはなさそうに思うんだけど…。そういうのがあるなら、もっと .net とかも積極的に使えるんだけどねぇ。どうなんだろ? さすがに linux 実機を作ろうとは思わんからなぁ、ましてや WSL を手にした今、「デュアルブート」なんて、選択肢に入れないよね、もはやマインドセットとして。

Windows をサポートしたいアプリケーションを開発する場合は Windows を買え、なのか…、ということではないよね。そういや GitHub は Windows 環境のテストもやってたわ。クラウドで、てことか、そういうことか、なるほど。


話それたけれど、えとね、導入はちょっとだけ時間がかかるけれど、得るものが非常に大きいので、

まずは四の五の言わずに今すぐ WSL2 を導入しよう、
今すぐに、そしてハッピーになろう

と強く強く言っておこうと思う。で、そうなってくれば、「MSYS だぁ cygwin だぁ」という話は、ワタシのサイトではトーンダウンしてくことになろうと思う。MSYS には MSYS の責務はずっとワタシにはあり続けるけれど、少なくとも「Unix では」の例として MSYS や cygwin を登場させる必要はなくなる。本物をいつでも使えるんだもの。


2022-03-15 17時追記:
思わぬ副作用が、もしかしたら色々出てくるかもしれない。ひとつ前の追記で書いた。

てなわけなので、直前に「強くオススメ」したその口が乾かないうちに、「ちょっとこの件があるので、慎重に考えてね」と言っとく。ワタシはこのままなんとか WSL を使う生活をしていくけど、そのノウハウは、今後ちょいちょい書いてくつもり。もしこわいなら、あなたはそれを待ってるといい。最低でも Microsoft 自身によるこの FAQ は読むべきね(VirtualBox などとの共存の話)。


2022-03-17 19時30分追記:
Windows 11 に乗り換えた。「ほっといても時間がかかる環境(ネットワーク的にも PC スペック的にも)」だったのに加えて、昨晩だよ、だから東京23区の大規模停電に「当たった」の、河の向こうは電気灯いてるじゃん、とうらめしかった。3時間止まってしまった。乗り換え終了は今日の夕方ようやく。

Microsoft による説明に従って WSL2 を更新して、イザ、と。gedit も動くし、入れれば ffplay も動くし、てことなのだけれど、やっぱね、色々あるわ。エディタ関係なら、フォント関係と dbus 関係(?)で何かしら、ffplay は最初は SDL 関係だったが、数回起動してたら起動し、でも「動いたり動かなかったり」て感じ。不安定みたい。どういう仕組みなんだろうかこれ。X Windows System ベースなんだとしたら X サーバが動いてる前提で動作するわけだが、X が動いてるのか、それとも「X 相当のエミュレーション」が動いているのか? 後者だとすると今の不安定な感じもなんとなくわからんでもないかなと思う。(→ 2022-05-26の追記参照。)

ひとつ前の追記と同じような感じになるかなぁ。正直ワタシはかなり気に入っているけれど、まだとても万人に薦められるもんではないなぁと。少なくとも色んな環境を渡り歩いた経験が豊富な人にはオススメるけど、それ以外の人は、最低でも「覚悟して使ってね」て感じ。最低でも「WSL/WSL2 が何をしているのか」の理解がまったく出来ない人は手を出してはいけない。何か問題があった場合に、そうした人は絶対に問題の切り分けが出来ないから。(なのでそういう人はいろんなコミュニティに迷惑をかけるかもしれない。Windows, Linux, WSL/WSL2 と各 OSS の「全部」にね。)

それでも、だ。ワタシはやっぱしこの WSL/WSL2、特に WSL2 on Windows 11 は素晴らしいと思っているのでね、日常使いするつもりだよ。(ワタシの場合特に「クロスプラットフォームなプログラム」を書く機会が多いので、そのための検証環境としてかなりあてに出来るの。)

おそらく、Docker に期待するのと似た、「ある特定の OSS アプリケーション専用の WSL2 インスタンス」みたいな考え方、つまり –export した distro を「別名で都度 import してそこに特定のアプリケーションを入れる」的な使い方を許容出来る人であれば、結構快適に使えるんじゃないかな。「この一つの ubuntu で何でも出来る」みたいな期待の仕方をしちゃうとガッカリするけれど、「使いたい OSS があって、たまたまちゃんと動く組み合わせがある」という期待の仕方だけでいいなら、「この ubuntu では動かないものがたくさんある」という事実はどうでもいいわけでしょ、だって。(先にほかの場所で Redis を例にした。そういうやつ。)


2022-03-22 14時追記:
寒い…、3月下旬に真冬並みって…。札幌に住んでた頃をちょっと思い出してるよ。

wsl.exe なんだけど、--help の出力でちょっと困ってた。less が使えないんだもん。これは「utf-16 で出力してる」から。Windows ネイティブのメモ帳も utf-16 は正しく扱えない。なので、たとえばリダイレクトでファイルに書き出してから例えば以下 Python スクリプトで変換:

wsl –help の出力を「wsl-help.txt」に突っ込んだとして
1 import io
2 d = io.open("wsl-help.txt", encoding="utf-16le").read()
3 io.open("wsl-help.txt", "w", encoding="utf-8").write(d)

ちょっとこれは不便よね。というか最近の less が utf 系なら解釈出来る、みたいなことってあるのかな、ないのかな。それ次第よね。

毎度これをやるのは馬鹿げてるので、(本日時点での)wsl –help の内容をはりつけとく:

  1 Copyright (c) Microsoft Corporation. All rights reserved.
  2 
  3 
  4 
  5 使用法: wsl.exe [Argument] [Options...] [CommandLine]
  6 
  7 
  8 
  9 Linux バイナリを実行するための引数:
 10 
 11 
 12 
 13     コマンドラインを指定しない場合、wsl.exe によって既定のシェルが起動されます。
 14 
 15 
 16 
 17     --exec, -e <CommandLine>
 18 
 19         既定の Linux シェルを使用せずに、指定したコマンドを実行します。
 20 
 21 
 22 
 23     --
 24 
 25         残りのコマンドラインをそのまま渡します。
 26 
 27 
 28 
 29 オプション:
 30 
 31     --cd <Directory>
 32 
 33         指定したディレクトリを現在の作業ディレクトリとして設定します。
 34 
 35         ~ が使用されている場合は、Linux ユーザーのホーム パスが使用されます。パスの先頭が
 36 
 37         / の場合は、Linux の絶対パスと解釈されます。
 38 
 39         それ以外の場合、この値は Windows の絶対パスである必要があります。
 40 
 41 
 42 
 43    --distribution, -d <Distro>
 44 
 45         指定したディストリビューションを実行します。
 46 
 47 
 48 
 49    --user, -u <UserName>
 50 
 51         指定されたユーザーとして実行します。
 52 
 53 
 54 
 55      --system
 56 
 57         システム配布用のシェルを起動します。
 58 
 59 
 60 
 61 Windows Subsystem for Linux を管理するための引数:
 62 
 63 
 64 
 65     --help
 66 
 67         使用状況に関する情報を表示します。
 68 
 69 
 70 
 71     --install [Options]
 72 
 73       追加の Windows Subsystem for Linux ディストリビューションをインストールします。
 74 
 75       有効なディストリビューションの一覧を表示するには、'wsl--list--online' を使用してください。
 76 
 77 
 78 
 79         オプション:
 80 
 81             --distribution, -d [Argument]
 82 
 83                 名前を指定して配布をダウンロードしてインストールします。
 84 
 85 
 86 
 87                 引数:
 88 
 89                    有効なディストリビューション名 (大文字と小文字は区別されません)。
 90 
 91 
 92 
 93                 例:
 94 
 95                     wsl --install -d Ubuntu
 96 
 97                     wsl --install --distribution Debian
 98 
 99 
100 
101     --set-default-version <Version>
102 
103          新しいディストリビューションの既定のインストールバージョンを変更します。
104 
105 
106 
107     --shutdown
108 
109         直ちに、すべての実行中の配布および WSL 2
110 
111  軽快なユーティリティの仮想マシンを終了します。
112 
113 
114 
115     --status
116 
117         Linux の Windows Subsystem の状態を示します。
118 
119 
120 
121     --update [Options]
122 
123         オプションが指定されていない場合、WSL 2 カーネルは更新され
124 
125  、最新バージョンになります。
126 
127 
128 
129         オプション:
130 
131             --rollback
132 
133                 以前のバージョンの WSL 2 カーネルに戻します。
134 
135 
136 
137 Windows Subsystem for Linuxのディストリビューションを管理するための引数:
138 
139 
140 
141     --export <Distro> <FileName>
142 
143         ディストリビューションを tar ファイルにエクスポートします。
144 
145 ファイル名には、標準出力として - を使用できます。 
146 
147 
148 
149     --import <Distro> <InstallLocation> <FileName> [Options]
150 
151         指定した tar ファイルを新しいディストリビューションとしてインポートします。
152 
153 ファイル名には標準入力として - を使用できます。
154 
155 
156 
157         オプション:
158 
159             --version <Version>
160 
161                 新しいディストリビューションに使用するバージョンを指定します。
162 
163 
164 
165     --list, -l [Options]
166 
167         ディストリビューションの一覧を表示します。
168 
169 
170 
171         オプション:
172 
173             --all
174 
175                 現在インストールまたはアンインストールされているディストリビューションを含む、すべてのディストリビューションを表示します。
176 
177 
178 
179             --running
180 
181                 現在実行中のディストリビューションのみを表示します。
182 
183 
184 
185             --quiet, -q
186 
187                 ディストリビューション名のみを表示します。
188 
189 
190 
191             --verbose, -v
192 
193                 すべてのディストリビューションに関する詳細な情報を表示します。
194 
195 
196 
197             --online, -o
198 
199                 'wsl --install' を使用してインストールするために使用できるディストリビューションの一覧を表示します。
200 
201 
202 
203     --set-default, -s <Distro>
204 
205        ディストリビューションを既定として設定します。
206 
207 
208 
209     --set-version <Distro> <Version>
210 
211         指定されたディストリビューションのバージョンを変更します。
212 
213 
214 
215     --terminate, -t <Distro>
216 
217         指定されたディストリビューションを終了します。
218 
219 
220 
221     --unregister <Distro>
222 
223         ディストリビューションの登録を解除し、ルートファイルシステムを削除します。
224 
225 
226 
227     --mount <Disk>
228 
229         すべての WSL2 配布に物理ディスクをアタッチしてマウントします。
230 
231 
232 
233         オプション:
234 
235             --bare
236 
237                 ディスクを WSL2 に接続しますが、マウントしません。
238 
239 
240 
241             --type <Type>
242 
243                 ディスクのマウント時に使用するファイルシステムです。指定しない場合は、既定で ext4 になります。
244 
245 
246 
247             --options <Options>
248 
249                 追加のマウントオプション。
250 
251 
252 
253             --partition <Index>
254 
255                 マウントするパーティションのインデックスです。指定しない場合、既定でディスク全体が指定されます。
256 
257 
258 
259     --unmount [Disk]
260 
261         すべての WSL2 ディストリビューションからディスクのマウントを解除してデタッチします。
262 
263         引数なしで呼び出された場合は、ディスクをマウント解除してデタッチします。

誤訳っぽい部分や不自然な日本語もあるが、まぁなんとなく言いたいことがわかる、でも良かろう。


2022-03-22 16時追記:
WSL で GUI、はさておくとしても「WSL ると日々がオイシイぜ」の例がね、「無限に」あるはずなのだけれど、すぐさまお試せてすぐさま紹介出来るものとなると、そんなにすぐには見つからんなぁと。「サーバ型のアプリケーションは Windows では凄まじく大変だが linux だととてつもなく簡単」というものは本当にたくさんあって、おそらく squid とかもそうなんだけど、「日常用途に squid」が大変なのよ、簡単に動かして試すことは簡単だとしても。そんなわけで「即戦力として日常に組み込めるもの」の例はワタシはすぐには思いつかなかった。

とりあえず jupyter の例を紹介しとくと興味をそそられる人はいるかな?

貼り付けた画像は fedoraremix on WSL2 に「sudo dnf install python3-jupyter'*'」で導入した jupyter を動かして、Windows の chrome から使ってるの図。

これは「Windows だと大変」というよりは、「linux のパッケージマネージャのごった煮志向に頼ると簡単」てことね。依存物が凄いことになるので、これ。Docker を考えなくても「wsl --export でバックアップしたインスタンスを wsl --import して wsl --distribute で実行」みたいに、やりたいことごとの独立国を作るノリでやれば、作ったり壊したりを気軽に出来るでしょ。こういう依存物が大きいものほど WSL や Docker が真価を発揮する、と思う。


2022-03-29 14時追記:
「Windows では凄まじく大変だが linux だととてつもなく簡単」というタイプの OSS は、たぶん大きく3パターンが多い。ひとつが依存物がとても多いもの。pandoc とかなんかは、linux のパッケージマネージャ任せにするとかなり楽。もう一つがサーバ型のアプリケーション(特に SSL が関係するもの)かなと。て話は上で書いた通り。あと当たり前だが「もともと Windows 向けに考えられてないもの」。このパターンは昔に比べればかなり割合としては減ってはいるけれど、今だってかなり多い。

で、「サーバ型のアプリケーション」が「linux だと楽」の話。果たして「WSL(2)だと楽」に直結してるのだろうか? てことなんだけれど、その反例を見つけたのでその話を。

System has not been booted with systemd as init system (PID 1). Can’t operate.」。Unix の仕組みに基づいた話なので当然「WSL でしか起こらないこと」ではないのだけれど、でも十中八九 WSL 固有。正確な理解はちゃんとリンク先の説明なりを読んで欲しいけど、要するに「WSL が linux のブートのシーケンスで特別なことをしている」ことが理由で起こる事象。英語のエラーメッセージは「PID=1 の始祖プロセスから始まるという前提が崩れてて困るぜ」と言っている。実際 wsl 起動している体験から薄々感じていたけれど、やはり WSL はかなり特殊なブートをしているということ。

これを喰らったのはまさに squid をお試していたとき。systemctl もしくは server コマンドでサービスの活殺を制御しようとするとこのエラーを喰らう。どのサービスだろうが同じと思うけれど、まだあまり多くを試してないのでわからん、けど少なくとも squid でそうなる。

Ubuntu だと /etc/init.d/squid がインストールされ、これだと問題なく動作する。なのでたぶん apt ベースの distro なら squid を問題なく動かせる。fedoraremix (なので dnf) だと /etc/init.d/squid がないので…、試してないけどおそらく Ubuntu というか apt でインストールされる /etc/init.d/squid をコピーして動かせば動くんじゃないかな、ただのシェルスクリプトだし。

こんな感じで、「linux だと楽 ≠ WSL(2)だと楽」というケースは少なからずありそうなんだよね。まぁこういうのは仕方ないかとは思う、んだけれど、だからこそ「玄人向け」てことになっちゃうんだろうなぁと思うとちょっと哀しい。本当に良いものであるし、とてもいろいろ救世主なんだけどねぇ…。


2022-05-22追記:
ここまで Docker の話を全然してないのに唐突に Docker のハナシになってごめんな。「Docker Desktop for Windows が WSL2 を必須としちゃってるのってヘンじゃない?」と思ってたんだけれど、これは Docker のアーキテクチャの根幹らしいので、どうやらどうしようもない模様。

Docker の説明でわかりやすいのがないかなーと思ってたのだが、これがとてもわかりやすかった:

このビデオに限らず、アーキテクチャの説明は見つかるけれど、このビデオで言うなら「Docker on Windows」「Docker on Mac」のセクションを参照。linux カーネルに依存してるてことみたい。なので、あるのかは知らんけど「Docker on BSD」があるなら、BSD だろうと linux 機能が必要になる、ということみたい。同じくあるかわからんけど、「Docker for android」なら、あ、これはもともと linux ベースだからいいのか、「Docker for iOS」なら…これも on Mac と同じか。

あとこのビデオで紹介されてる通り、「Windows コンテナ」が選べる、Docker Desktop on Windows を選ぶなら。まだ試してないけど、たぶんこれが「Windows どうしでも依存物問題はあるろ」へのソリューションに使えるものなのかなと思う。

あとね。ざっとビデオをみて思ったんだけど、どうもね、ワタシが「先に WSL を紹介しちゃるぜ」としたのは、結果としては良かった気がしてる。だってね Docker って、今は linux コマンドの知識が必須なんだわ。linux コマンドに慣れてれば一瞬で理解出来るけど、まったくやったことがない人向けの説明って、すぐに見つけた説明では見当たらなかった。ので、先に WSL/WSL2 で linux に馴染んでから Docker、という理解の仕方は悪くないと思う。


2022-05-24追記:
上のほうで「Windows の中と、WSL 上に乗っけた linux (ubuntu など)の両方に小さな独立国を作る」なんて書いちゃったが、間違ってた、と思う。というか「作れるか?」の問いには「作れる」となるかもしれないが、「linux コンテナを使うか Windows コンテナを使うかの二択」として使うものなので、デフォルトの状態で使う限りは「WSL 上に乗っけた linux (ubuntu など)に小さな独立国を作る」だけと思う。というか「概念」で理解しようとすると混乱しちゃうけれど、Windows ファイルシステムとして見える実体を覗き込んでみれば。Windows の場合は AppData/Local の下に Docker が管理されるが、そこの wsl に仮想ディスク(vhdx)があって、これが実体だと思う。この仮想ディスクの中に仮想環境をぶち込んでってるてことだと思う。(あと「二択」の一方は、無料エディションでは使えない気がしてきた。Docker Desktop の GUI にそれをコントロールする設定が見当たらないし。)

「思う」ばっかですまんが、あやふやなのよ、まだ。

それはそうと、「Docker 事始め」としてどんなネタが相応しいだろうか、と考えてたんだけれど、「自分でアプリケーションを作る」ネタよりも先にただのユーザとしての初めの一歩から始めればいいんだよな、てことで言うなら redis や memcached がオススメかなと思った。redis についてはさっきやったのを書いておいた(ただし基礎的なところじゃなくて GEO* 部分しかやってないけれど)。pandoc もやってみたが、一番最初のものとして相応しいかといえばそうでもなかった


2022-05-26 追記:
「Docker で linux GUI」の道筋を立てたくて、「Windows 11 + WSL2 の linux GUI」について、ちゃんと考えるところから始めよう、と思った。

で、どんな検索したかは既によくわからんのだが、このサイト:

を「読み始めて」ふと気付いた。「あ、X サーバは任意だよなそういえば」。

「サーバ」とか「クライアント」という言葉に騙される代表格なのを忘れてたよ、X Window System。「linux で動く X Window System ベースの GUI アプリケーション」はこれは「クライアント」。たとえば emacs、たとえば gedit、たとえば xeyes。これが Windows 11 + WSL2 で「何の問題もなく動く」ということはこれは、「on WSL2 な distro 上で X サーバが動いていて、そいつがダイレクトに Windows のデバイスを透過的にコントロールしている(無論その X サーバにはその自覚がなく、Hyper-V がそれを担っている)」ということでしかないよな、と。たぶんそうだよなぁと。

もう少し細かく観察すると、「Microsoft による説明に従って WSL2 を更新して、イザ、と。gedit も動くし」という状態は、「DISPLAY」環境変数は「:0」つまり、その distro 本人からみた「ローカルホスト:0」を指していて、それでちゃんと動いとる。あぁ、確定。不思議に感じたものは、「どんな仕組みだ?」と言うようなものではなく、あるべき姿のものだった、ということだ。

で、「X サーバはそういえば任意だよな」。つまり、「ネットワーク越しの X サーバ」という話。WSL2 の世界では、ホスト(Windows)と WSL インスタンス(linux)は「別マシン」なので、「WSL インスタンス側」からみて「ホスト Windows」は「リモート機器」である。そして WSL 側からみたホストは /etc/resolve.conf に nameserver として識別されている。つまり、「リモート(つまり Windows)で X サーバが動いてれば、それも使えるハズだ」ということになる。それを実際に試みてるのがリンクしたサイトね。

本来は「ログイン」して信頼しあって接続しなければならないので「リモートの X サーバに接続する」ことはそんなに簡単に出来ちゃダメなわけね。でも紹介されてる VcXsrv はサーバ起動時にチェックボックス一つで制御出来る、てこと。https://skeptric.com/wsl2-xserver/ が試みているのはそれね。

実際にやってみた。

まず、「Windows 11 + WSL2」だけのまま、つまり「DISPLAY=:0」のままで動作するのを確認したあと、VcXsrv の XLaunch を起動し、説明の通り「Disable access control」にチェックを入れる。つまり「誰でも好き勝手に使い放題」という設定。例によってインジケータが見つけにくいが:

これで Windows 側で WSL2 側からアクセスし放題な X サーバが動作してる状態。ネットワーク、なので、ファイアウォールだのの問題が繊細だ、て話を https://skeptric.com/wsl2-xserver/ はこまごま書いてくれてるわけね、ただ、ワタシのケースはここまで複雑なことは必要なかった。例の「なんかアクセスしようとしてるけど許してみたりするかい?」に「はい」と答えただけ。

で、WSL2 (試したのは Ubuntu)にログインした状態で、たとえば /etc/resolve.conf に書かれてる「Windows 側」が 172.34.13.1 とかだったりするなら:

1 [me@wsl2-ubuntu: ~]$ export DISPLAY=172.34.13.1:0
2 [me@wsl2-ubuntu: ~]$ export LIBGL_ALWAYS_INDIRECT=1

LIBGL_ALWAYS_INDIRECT のほうはワタシは意味は把握してなくて猿真似。opengl が indirect に、…なるほどわからん。とにかくこの状態にして:

1 [me@wsl2-ubuntu: ~]$ emacs

DISPLAY=:0 の状態と全然変わり映えしないので、うまくいってるのかわからん、という場合は XLaunch を終了しちゃえばいい。emacs がちゃんとお亡くなりになる。

で。何が言いたいの?

つまり「linux GUI on Docker」でも同じだろうな、てことね。単に X クライアントだ、てことなら、「X Server on Docker」はあんまし考えなくて良くて VcXsrv みたいな「X Server on Windows」でも良くて、その場合は「DISPLAY の制御だけがキモ」てことになる、てことかなぁと。

Docker のはまだ試してないけれど、きっとそういうことだと思う。(→ 2022-05-26 15時追記: そういうことだった。)