WSL2+Ubuntu 20.04でGUIアプリを動かす
Windows 10のWSL2(Windows Subsystem for Linux)にインストールしたUbuntu 20.04で、GUIアプリが動くように環境を構築してみます。
大まかな手順としては、「Windows側にXサーバーをインストール」→「WSL2のUbuntuにGUI関連ソフトをインストール」→「UbuntuにDISPLAY環境変数を設定して、Windows側Xサーバーに出力させる」という感じです。
WindowsのInsider Preview参加者の方へ(追記)
Windows 10のInsider Preview(ビルド21362以降)やWindows 11のInsider Previewをお使いの方は、「WSLg (Windows Subsystem for Linux GUI)」のプレビュー版を利用してGUIアプリを利用することも可能です。
Windows 10 Insider Previewの方向けのインストール方法は別記事にまとめていますので、こちらをご覧ください。
また、Windows 11 Insider Previewをお使いの方は、こちらの記事をご覧ください。
2021/06/14時点の通常リリース版である「21H1」ではWSLgは利用できませんので、本記事(次項以降)の通りにセットアップを進めてください。
事前準備:WindowsにWSL 2をインストール
Windows 10へのWSL2のインストールはこちらの記事にまとめています。まだWSL 2をインストールされていない方は、こちらの記事を参考にインストールしてください。
Windows側にXサーバーをインストール
WSL2上のUbuntuでGUIアプリを動かしますが、その画面表示やマウス入力は、Windows側にインストールしたXサーバーを経由して行います。
Windows用のXサーバーアプリとして、VcXsrvをインストールします。
上のサイトからVcXsrvのインストーラーをダウンロードして実行します。インストールの設定はそのままで大丈夫だと思いますが、私はショートカットの作成はオフにしました。
インストールが終わったら、スタートメニューからXLaunchを開きます。ここで、VcXsrvの起動オプションを設定します。起動オプションですが、Display numberは後ほど指定する必要がありますので、自動(-1)ではなく明示的に「0」にしておきます。また、Additional parameters for VcXsrvに「-ac -nowgl」を指定します。この追加パラメーター「-ac」は、localhostで接続を受ける場合は不要らしいですが、WSL2は違うIPでネットワークにつながっていて別端末扱いのため、必要になります。「-nowgl」は、一部のGTKアプリを動かすときにエラーが出てしまうので、対策として指定しています。-nowglがなくても動くアプリもあると思います。
起動すると、Windowsのファイアウォールから警告があります。WSL2は、通常の物理イーサネットとは別のIPアドレス範囲でWindows側とつながっていますので、「パブリックネットワーク」にもチェックを入れてアクセスを許可します。(WSL用の仮想イーサネットはパブリックネットワーク扱いのようで、これにチェックを入れないと動きませんでした)
タスクバーにVcXsrvのアイコンが表示されたら完了です。アイコンにマウスを乗せると、「PC名:0.0」などと表示されます。このうち、「0.0」の部分は後の設定で必要ですので、覚えておきます。
WSL2 UbuntuでのGUIアプリを常用するなら、VcXsrvの設定を保存しておいて(Save configurationボタンで保存できます)、そのファイルをスタートアップに登録すると便利だと思います。ちなみに、スタートアップフォルダはWin+Rからshell:startupで
開けますので、このフォルダにconfig.xlaunchファイルを保存すればOKです。
Ubuntu側にGUIアプリをインストール
Windows側の用意が済んだら、次にWSL2上のUbuntu側でもGUIアプリを動かすための準備をします。
コマンドプロンプトやPowerShellからwsl
コマンドを実行して、Ubuntuを起動します。
PS C:\> wsl
bashのプロンプトが表示されたら、GUI関連のソフトをインストールします。参考サイト1によると、最低限sudo apt install libgl1-mesa-dev xorg-dev
をインストールすれば良いそうです。依存アプリも一緒にインストールするよう表示されますので、y
を入力して進めます。
username@host:/mnt/c$ sudo apt install libgl1-mesa-dev xorg-dev
[sudo] password for username:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
libdmx-dev libdmx1 libdrm-dev libegl-dev libegl-mesa0 libegl1 libfontconfig1-dev libfontenc-dev libfreetype-dev
libfreetype6-dev libfs-dev libfs6 libgbm1 libgl-dev libgles-dev libgles1 libgles2 libglvnd-dev libglx-dev libice-dev
libopengl-dev libopengl0 libpciaccess-dev libpixman-1-0 libpixman-1-dev libpng-dev libpng-tools
libpthread-stubs0-dev libsm-dev libwayland-server0 libx11-dev libxau-dev libxaw7-dev libxcb-xfixes0 libxcb1-dev
libxcomposite-dev libxcursor-dev libxcursor1 libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxfont-dev
libxfont2 libxft-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmu-headers libxmuu-dev libxpm-dev
libxrandr-dev libxrender-dev libxres-dev libxres1 libxss-dev libxss1 libxt-dev libxtst-dev libxv-dev libxvmc-dev
libxvmc1 libxxf86dga-dev libxxf86vm-dev mesa-common-dev pkg-config uuid-dev x11proto-core-dev x11proto-dev
x11proto-input-dev x11proto-randr-dev x11proto-record-dev x11proto-scrnsaver-dev x11proto-xext-dev
x11proto-xf86dga-dev x11proto-xf86vidmode-dev x11proto-xinerama-dev xorg-sgml-doctools xserver-xorg-dev xtrans-dev
Suggested packages:
freetype2-doc libice-doc libsm-doc libx11-doc libxaw-doc libxcb-doc libxext-doc libxt-doc
The following NEW packages will be installed:
libdmx-dev libdmx1 libdrm-dev libegl-dev libegl-mesa0 libegl1 libfontconfig1-dev libfontenc-dev libfreetype-dev
libfreetype6-dev libfs-dev libfs6 libgbm1 libgl-dev libgl1-mesa-dev libgles-dev libgles1 libgles2 libglvnd-dev
libglx-dev libice-dev libopengl-dev libopengl0 libpciaccess-dev libpixman-1-0 libpixman-1-dev libpng-dev
libpng-tools libpthread-stubs0-dev libsm-dev libwayland-server0 libx11-dev libxau-dev libxaw7-dev libxcb-xfixes0
libxcb1-dev libxcomposite-dev libxcursor-dev libxcursor1 libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev
libxfont-dev libxfont2 libxft-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmu-headers libxmuu-dev
libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxres1 libxss-dev libxss1 libxt-dev libxtst-dev libxv-dev
libxvmc-dev libxvmc1 libxxf86dga-dev libxxf86vm-dev mesa-common-dev pkg-config uuid-dev x11proto-core-dev
x11proto-dev x11proto-input-dev x11proto-randr-dev x11proto-record-dev x11proto-scrnsaver-dev x11proto-xext-dev
x11proto-xf86dga-dev x11proto-xf86vidmode-dev x11proto-xinerama-dev xorg-dev xorg-sgml-doctools xserver-xorg-dev
xtrans-dev
0 upgraded, 83 newly installed, 0 to remove and 0 not upgraded.
Need to get 6772 kB of archives.
After this operation, 29.6 MB of additional disk space will be used.
Do you want to continue? [Y/n]
続いて、.profile
にDISPLAY環境変数を設定します。WSL2から見てlocalhostのXサーバーに接続する場合は「:0」だけで良いらしいですが、WSL2はWindowsとは別IPでLANにつながっていますので、WSL2から見たWindows側のIPアドレスを指定しなければいけません。
その上、WSL2を起動するたびにWindows側のIPアドレスが変わるらしいので、起動ごとに適切なIPアドレスを指定するようにします。
まず、.
を開きます。profile
nano ~/.
を実行します。profile
username@host:/mnt/c$ nano ~/.profile
最終行に次の1行を書き足します。末尾の0.0は、VcXsrvアイコンにマウスを乗せたときの表示に合わせます。0.0でなければ、書き換えてください。
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0.0
良ければ、保存して閉じるため、Ctrl+X → y → Enterと入力します。
GUIアプリの起動を試してみる
上記で初期設定が済んだら、環境変数を反映するため一度Ubuntuのbashを閉じて、もう一度wsl
コマンドでUbuntuを起動します。
サンプルアプリをインストールするため、sudo apt install x11-apps
を実行します。
username@host:/mnt/c$ sudo apt install x11-apps
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
xbitmaps
Suggested packages:
mesa-utils
The following NEW packages will be installed:
x11-apps xbitmaps
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 685 kB of archives.
After this operation, 2763 kB of additional disk space will be used.
Do you want to continue? [Y/n]
インストールが終わったら、xeyes
を実行します。
username@host:/mnt/c$ xeyes
目玉が表示されたら完了です。
日本語フォントを扱えるようにする
このWSL2環境には英字フォントが6個しか入っていませんので、GUIで日本語を表示しようとすると文字化けしてしまいます。そのため、日本語GUIアプリを使いたい場合は、何らかの方法でWSL2環境に日本語フォントを追加する必要があります。
今回は、参考サイト[3]に従って、Windows側にインストールされているフォントをWSL2のUbuntu 20.04側でも使えるように設定してみます。
まず、デフォルトでWSL2に用意されているフォントを一覧表示してみます。
username@host:~$ fc-list
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book
この通り、6個しか入っていません。
WSL2のGUIアプリが使えるフォントの情報は、/etc/fonts/
内にあります。このフォルダにlocal.conf
という名前のXMLファイルを作成して、Windows側のフォントフォルダも参照するように設定すればOKです。
sudo nano /etc/fonts/local.conf
で新規ファイルを作成します。
username@host:~$ sudo nano /etc/fonts/local.conf
nanoテキストエディターが開きますので、次の内容をコピペします。WindowsのCドライブは、WSL2上では/mnt/c
にマウントされていますので、要はC:\Windows\Fonts
フォルダを参照するように設定しています。
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/mnt/c/Windows/Fonts</dir>
</fontconfig>
Ctrl+X → y → Enterで、保存して閉じます。
これで設定完了です。もう一度、GUIアプリで扱えるフォント一覧を表示してみると、見覚えのあるフォントも含めてたくさん表示されるようになります。(ここでは一部抜粋して掲載しています)
username@host:~$ fc-list
/mnt/c/Windows/Fonts/NotoSerifHebrew-Bold.ttf: Noto Serif Hebrew:style=Bold
/mnt/c/Windows/Fonts/verdana.ttf: Verdana:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/mnt/c/Windows/Fonts/EmojiOneColor-SVGinOT.ttf: EmojiOne Color:style=Regular
/mnt/c/Windows/Fonts/msmincho.ttc: MS Mincho,MS 明朝:style=Regular,標準
/mnt/c/Windows/Fonts/msgothic.ttc: MS PGothic,MS Pゴシック:style=Regular,標準
/mnt/c/Windows/Fonts/meiryob.ttc: Meiryo,メイリオ:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,ボールド,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/mnt/c/Windows/Fonts/yuminl.ttf: Yu Mincho,游明朝,Yu Mincho Light,游明朝 Light:style=Light,Regular
/mnt/c/Windows/Fonts/YuGothM.ttc: Yu Gothic,游ゴシック,Yu Gothic Medium,游ゴシック Medium:style=Medium,Regular
これで、WSL2上のGUIアプリで日本語が扱えるようになりました。
おすすめの記事
今回用意したGUIアプリ実行環境を使って、Google Chromeをインストールしてみました。
ここまでの情報だとChrome(やその他のGUIアプリ)上で日本語入力ができません。日本語入力もしたい場合は、こちらの記事をご覧ください。
また、コマンドライン・GUIアプリともに、WSL2上から音声を出すには追加で設定が必要です。音声を出す方法はこちらの記事にまとめました。
デスクトップ環境(Ubuntu Desktop)もインストールしてみました。
参考サイト
この記事は、主に参考サイト[1]を参考にして設定を行いました。参考サイトではWSL2にUbuntu 18.04をインストールして設定していますが、Ubuntu 20.04でも全く同じ方法で設定できました。
参考サイト[1]
参考サイト[2]
参考サイト[3]
記事の更新履歴
VcXsrvの追加パラメーター変更(2020/8/3)
VcXsrvの設定の「Additional parameters for VcXsrv」に「-nowgl」を追加しました。私の環境だと、一部のGTKアプリでエラーが出てきたので、対策として追加しています。
日本語フォントを呼び込む設定を追加(2020/8/5)
日本語フォントを表示できるように、UbuntuからWindows側のフォントフォルダを参照する設定を追記しました。
日本語フォントを追加しておかないと、アプリ中の日本語が文字化けします。
export文を.bashrcから.profileに移動(2020/8/14)
Bash環境変数のexport文を、.bashrc
から.profile
に移動しました。
UbuntuのBashを立ち上げていない状態でも、Windows上のコマンドプロンプトやショートカットからwsl.exe -d "Ubuntu-20.04" <Ubuntu上のコマンド>
を実行すればUbuntu上のアプリが起動できます。例えば、Ubuntu 20.04にインストールしたGoogle Chromeを起動するなら、wsl.exe -d Ubuntu-20.04 bash -lc google-chrome
というショートカットをつくっておけば、ダブルクリックで起動できます。
ただし、この起動方法だと.bashrc
は読み込まれないため、.bashrc
にexport DISPLAY文を入れていると「Xサーバーが見つからない」というエラーが出てしまいます。この対策として、export DISPLAY文を.profile
に移しました。
Waylandが移植され、RDP経由で使えるようになるらしい (2020/9/30)
現在、WSL上のLinuxでGUIアプリを動かすには、本記事で説明したとおりXサーバーを動かしてそこに表示する、という方法をとらなければなりません。
それが下記の記事によると、将来的にはXサーバー不要でGUIアプリが動かせるようになるらしいです。技術的には、Waylandを移植してRDP経由でGUIアプリを表示するらしく、IDEやブラウザを動かすことも確認できているそうです。
2ヶ月以内くらいでベータ版が配信されるとのことなので、配信されたらWayland経由でのGUIアプリ表示もやってみたいと思います。
Insider Preview(ビルド21362以降)の方向けの案内を追記しました(2021/6/14)
Windows 10 Insider Preview(ビルド21362以降)ではWSLgのプレビュー版が利用できるようになりました。これに関する案内を追記しました。
Windows 11 Insider Previewの方向け案内を追記しました(2021/7/10)
Windows 11 Insider PreviewでのWSLgインストール方法の紹介記事も執筆しましたので、その案内を追記しました。
Bashシェルスクリプトをイチから学べる本です。よく見かけるものの一見トリッキーな「ifの条件式にコマンドを書く」、「&&や||でコマンドをいくつか並べる」などの書き方も、一つ一つ細かく動きを解説していて分かりやすかったです。また、grep、sed、xargs、getoptなどの使い方や正規表現についても、詳細に説明があります。
網羅的に書かれており、辞書的に使えるおすすめの書籍です。
ディスカッション
コメント一覧
続いて、.profileにDISPLAY環境変数を設定します。WSL2から見てlocalhostのXサーバーに接続する場合は「:0」だけで良いらしいですが、WSL2はWindowsとは別IPでLANにつながっていますので、WSL2から見たWindows側のIPアドレスを指定しなければいけません。
その上、WSL2を起動するたびにWindows側のIPアドレスが変わるらしいので、起動ごとに適切なIPアドレスを指定するようにします。
まず、.profileを開きます。nano ~/.profileを実行します。
username@host:/mnt/c$ nano ~/.profile
最終行に次の1行を書き足します。末尾の0.0は、VcXsrvアイコンにマウスを乗せたときの表示に合わせます。0.0でなければ、書き換えてください。
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk ‘{print $2}’):0.0
良ければ、保存して閉じるため、Ctrl+X → y → Enterと入力します。
————————————————————————–
上記の通りやっているのですが、GUIに表示できません。上記のやり方で「
WSL2から見たWindows側のIPアドレスを指定しなければいけません。
その上、WSL2を起動するたびにWindows側のIPアドレスが変わるらしいので、起動ごとに適切なIPアドレスを指定する
」
ができるのでしょうか?
コメントありがとうございます!
ご質問の件、一応そのようなexport行を書き足せば、「起動ごとに適切なIPアドレスを指定する」というのができるはずです。(少なくとも私の環境では正常に動いています)
export行のカッコ内のコマンド
cat /etc/resolv.conf | grep nameserver | awk '{print $2}'
を実行すると、私の環境では「172.22.96.1」と帰ってきます。(このIPアドレスは、Windowsを再起動するたびに変わります)
なので、exportのコマンドとしては、
export DISPLAY=172.22.96.1:0.0
となって、DISPLAY変数に「IPアドレス:0.0」がセットされます。echo $DISPLAY
などと打てば、私の場合だと「172.22.96.1:0.0」と帰ってきて、正常にセットされていることが分かります。単純な所としてはこれらが考えられますが、いかがでしょうか?
・WSLの再起動を行っていない:
.profileファイルを変更しても即時には適用されませんので、
.profileファイルを再読み込みする必要があります。
WSLを閉じる→もう一度開く で、.profileが読み込まれると思います。
(
source ~/.profile
でも大丈夫だと思います)・ファイアウォールでVcXsrvへのアクセスを弾いてしまっている:
Windowsのファイアウォールの場合、パブリックからのアクセスを許可する必要があります。
パブリックにチェックを入れずに進めてしまった場合は、
https://astherier.com/blog/2020/08/wsl2-ubuntu-sound-setting/#paplay-not-work
の「Ubuntu側でpaplayが動かない」の箇条書き三つ目を参考に、
パブリックネットワークからのアクセスを許可してください。
(pulseaudioをVcXsrvと読み替えてください)
その他、原因切り分けのため、いくつか情報をシェアしておきます。
・タスクマネージャーの[パフォーマンス]タブを見ると、
「vEthernet (WSL)」というアダプター名のネットワークがあります。
ここに表示されているIPアドレスが「WSL2から見たWindows側のIPアドレス」のようです。
・DISPLAY変数が間違っている場合は、xeyesを起動するとすぐに
「Error: Can’t open display: (DISPLAY変数の内容)」を返してくるようです。
・VcXsrvが起動していない、もしくはVcXsrvへのアクセスを弾いているという場合は、
xeyesを起動すると1分くらい待って同様のエラーを返してくるようです。
VcXsrvの件ですが、IPアドレスではなくホスト名で接続できました。従って、.profile への追加行は「export DISPLAY=”ホスト名:0.0″」ホスト名はもちろん hostname の戻り値でした。VcXsrvの仕様変更のような感じです。環境は ASUS TUF, AMD RYZEN, Windows10, WSLです。なぜかAMD用のWSL2アップデートのインストーラーが起動せず、WSLのままですので参考になるかどうか。
TSaitoさま、コメントありがとうございます!
こういうことで合ってるでしょうか?
う~ん、どうもうちの環境ではうまくいきませんでした。
もしかしたらWindows側のネットワーク設定とかも関係してくるかもしれませんが、理由までは追い切れませんでした。。。
すみません。再現できないですか。VcXsrvを起動してタスクバーに表示されるアイコンをマウスオーバーしたときに表示される内容は、(ホスト名);0.0 でして、そのとおりに記述すると確かにXが起動できた次第です。
そうですね、、、前述の「z390:0.0」というのはVcXsrvアイコンにマウスを乗せたときに出てくる文字列でもあるのですが、うちの環境では動きませんでした。
「ファイアウォールにて、パブリックネットワークでも許可が必要」
うまくいかず調べていたところこの情報にたどり着きました。
ありがとうございました!
一見するとループバックの通信なのでパブリックネットワークからの許可はいらないように見えますが、必要みたいですね。
私も最初、そこに引っかかりました。
ピンバック & トラックバック一覧
[…] ひとつ注意しないといけないのが、ファイアウォール設定でパブリックネットワークでも許可しておかないとX11サーバとWSL2が通信不可。参考リンクを確認すること […]
[…] […]
[…] なんとかGUIを・・、と思って調べると、できるじゃないか!皆さん、こちらとこちらの記事を見るようですね。”VcXsrv Windows X Server”というのをインストールするようです。 […]
[…] WSL2+Ubuntu 20.04でGUIアプリを動かす | AsTechLog (astherier.com) […]
[…] Windowsで動作するXサーバはいくつかあるようですが、VcXsrv X Serverがよく使われているようです。インストール方法は下記が参考になります。WSL2+Ubuntu 20.04でGUIアプリを動かす […]