タケユー・ウェブ日報

Ruby on Rails や Flutter といったWeb・モバイルアプリ技術を武器にお客様のビジネス立ち上げを支援する、タケユー・ウェブ株式会社の技術ブログです。

VSCode Remote - SSH と WSL2 でリモートFlutter開発

f:id:uzuki05:20181215091555j:plain

この記事について

できたこと

  • VSCode の Remote SSH で Flutter 開発をするAndroidアプリをビルド)
    • Remote SSH で WSL2 の Ubuntu で開発する
    • Remote SSH 接続先である WSL2 のホスト機は Android端末と同じネットワーク内にある

できないこと

  • 遠隔地やクラウド上にあるWindows PC上のWSL2に入ったFlutter SDKで、手元にあるAndroid端末を使ってデバッグ実行する
    • WSL2 のホスト機からAndroid端末に対してTCP/IPで接続できる必要があります。もしかするとトンネリングなどの手法で遠隔地でもできるかもしれないが

構成図

f:id:uzuki05:20210130030106p:plain
構成図

手順

これを実現するには次のステップが必要です。

  1. WSL2で動くUbuntuSSH で接続できるようにする
  2. VisualStudioCodeで Remote SSH 設定をする
  3. WSL2で動くUbuntu の adb devices でAndroid 端末を認識させる

1. WSL2で動くUbuntuSSH で接続できるようにする

WSL2でSSHサーバを起動する

systemctl status ssh
// もし動いていなかったら
sudo apt install openssh-server
systemctl start ssh
systemctl enable ssh

SSH公開鍵認証の設定

VSCode を動かすゲストのSSH公開鍵を WSL2 の ~/.ssh/authorized_keys に追記する。 鍵の作成は ssh-keygen で行うが、最近のWindows 10はOpenSSH内蔵なので、標準で使えるとのこと。

# VSCodeを動かすゲストで鍵ペアを作る
 ssh-keygen

C:\Users\[Account]\.ssh\id_rsa.pubC:\Users\[Account]\.ssh\id_rsa が生成した秘密鍵の場合)を、WSL2 の ~/.ssh/authorized_keys に追記しておく。

ホスト機へのTCP22番ポート接続をWSL2に転送する

私はPortForwarding用のPowerShellスクリプトをタスクスケジューラを使ってスタートアップ時に実行しています。

PowerShell
# 対象のWSL2ディストリビューション
$DISTRO = "Ubuntu-18.04"
# ホストのローカルIPアドレス。私は固定で運用しているので
$HOSTIPAddress = "192.168.108.103"

# wsl を通常起動しないと sshd が起動しないためのワークアラウンド
# 私の環境ではこれがないとダメ
Start-Process wsl.exe -ArgumentList "-d $DISTRO" -WindowStyle Hidden

# WSL2のIPアドレスを取得
$WSLIPAddress = (wsl.exe -d $DISTRO exec ip -4 address show eth0 | wsl.exe -d $DISTRO exec grep 'inet ' | wsl.exe -d $DISTRO exec  awk '{print \$2}').trimStart().trimEnd().Split('/')[0]

# ホストの22番ポートへの着信をWSL2へ転送する
netsh.exe interface portproxy delete v4tov4 listenport=22 listenaddress=$HOSTIPAddress
netsh.exe interface portproxy add v4tov4 listenport=22 listenaddress=$HOSTIPAddress connectaddress=$WSLIPAddress
# このPowerShellスクリプトを手動実行するならこうすれば sudo っぽい動きになるので、いちいち『管理者で実行』しなくてよい
#Start-Process -Verb runas netsh.exe  -ArgumentList "interface portproxy delete v4tov4 listenport=22 listenaddress=$HOSTIPAddress"
#Start-Process -Verb runas netsh.exe  -ArgumentList "interface portproxy add v4tov4 listenport=22 listenaddress=$HOSTIPAddress connectaddress=$WSLIPAddress"

タスクスケジューラ(ホスト機起動時に自動実行したいとき)

スタートメニューのタスクスケジューラ taskschd.msc を起動し、『タスクの作成』

f:id:uzuki05:20210130021336p:plain
ユーザーがログインしているかどうかにかかわらず、最上位の特権で

f:id:uzuki05:20210130021455p:plain
『スタートアップ時』トリガーを作成

f:id:uzuki05:20210130021533p:plain
『プログラムの開始』操作を作成し、上のスクリプトを実行

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass C:\wsl\start_ssh_server.ps1

2. VisuaoStudioCode で Remote SSH 設定をする

f:id:uzuki05:20210130022017p:plain
Remote - SSH プラグインをインストール

f:id:uzuki05:20210130022158p:plain
リモートエクスプローラーで SSH Targets を選択。歯車アイコンをクリックし設定に進みます。

f:id:uzuki05:20210130022317p:plain
Remote SSH の設定は .ssh\config に書きます。ユーザーごとのものを選択

f:id:uzuki05:20210130022553p:plain
接続設定を書くとリモートエクスプローラーにホストが追加されます。

f:id:uzuki05:20210130022801p:plain
接続に成功すると、WSL2でVSCodeのサーバが起動し、ローカルのVSCodeはクライアントとして動きます。『フォルダーを開く』からWSL2内の任意のプロジェクトを選んで開発できます。

3. WSL2で動くUbuntu の adb devices でAndroid 端末を認識させる

DNMC | Setting up Flutter natively with WSL2, VS Code & Hot-Reload 🔥 - DNMC

↑の記事に、Java JDKのインストール、Flutter SDKのインストール、Android SDK / ADB のセットアップ、ADBにAndroid端末を接続する方法まで詳しく紹介されています。

ポイントは Windows PC にも WSL2 にもそれぞれ Android SDK / ADB を使えるようにする必要があること、ネットワーク接続でのデバッグを使う必要があること、です。

  • WSL2からWSL2ホストにUSB接続されているAndroid端末に直接接続することは現状できない
  • まずWindows PCにUSBデバッグ接続して、 Windows PCのADBでAndroid端末をTCP/IP接続可能な状態にする( adb tcpip ポート番号
  • Android端末がTCP/IP接続可能な状態になったら、WSL2のADBからでTCP/IPで接続( adb connect Android端末のローカルIPアドレス:ポート番号
  • ADBで端末を認識できたら Flutter から使う

まとめ

WSL2はローカルのメインマシンとしてWindowsを使う私のような開発者には非常に便利なものですが、リモートホストのWSL2への接続、ウェブ以外の開発ではなかなか嵌まり所が多く、できはしましたが結構大変です。

VSCode Remote - SSH で使うなら素直に(WSL2でない)Ubuntuで良いように思いました。リモートを使わずローカルで済むのがWSL2の良いところなのですから。