トップ画像
RAMが足りないので、Dockerだけ別PCのWSLに任せてリモート開発する

執筆者: アンドウ

最終更新: 1/5/2023

RAMちゃん「〽ああ〜〜


男の人って〜〜〜


いくつも〜〜〜


RAMを持って〜いるのね〜〜〜」




→持ってねえよ!

だが無駄にPCが複数ある!!!

DockerのRAM消費をケチるため、PCを2台使って分担する。

---

概要

以下、2台のPCと3種類のターミナルが登場する。

  • WSLマシン
    • ホスト: WSLを動かすWindows
    • ゲスト: WSLのLinux
  • メインPC: 任意のPC。IDEやブラウザはここで動かす


WSL用マシンのIPを固定

ルータをいじって、WSLのマシンのIPを固定する。
Buffaloだったら「詳細設定→LAN→DHCPリース」から設定できる。

以下、このIPは 固定したIP とするが、流石にスクリプトにハードコーディングはしない。

WSL用マシンの準備 (WSLホスト側)

前提として以下を済ませる。

  • Windows Terminalを入れておく
    • ストアはめんどいのでGitHubから
    • 背景写真とかいじれて楽しいよ
  • WSL2の有効化
  • Docker Desktopのインストール
    • 俺、これ知らなくてUbuntuにDocker入れちゃった
    • そもそもDocker Desktopのインストーラが全部やってくれるので、WSL側で何かすることはない
    • Hyper-VではなくWSL2バックエンドを選択すること

なおRDP(リモートデスクトップ)やOpenSSHサーバーは不要。まあ画面がしょぼいとかの理由で、RDPがあればベターだが、Proライセンスいるんよな。

wsl.exe -l -v してWSL1だった場合、以下のようにアップグレードする

wsl.exe --set-version ディストロ 2
wsl.exe --set-default-version 2


あと不確実性排除のためにディストロ固定する。お使いのディストロに合わせて適宜調整すること。

wsl --set-default ディストロ


スクリプトを書く (WSLゲスト側)

以下、ホストのexe叩くだけなので、任意のディストロで動くはず。

ポートフォワード設定

sudo vi bin/port_forward.sh


ユーザ関係ないのでbinに置いたが、適宜変えてくれ!ベターな場所があるはず

#!/bin/bash
# ポート開放の自動化
# Usage: ログオン時にやれ!

# ホストのIP
HOST_IP=$(ipconfig.exe | sed -e 's/\r//' | grep 'IPv4 Address' | head -n 1 | cut -d ':' -f 2 | awk '{print $1}')
# ゲストのIP
IP=$(ip route | grep 'eth0 proto' | cut -d ' ' -f9)

function forward() {
    PORT=$1
    # 2つめのポート指定なければ同じポートを使う
    PORT2=${2:-$PORT}
    # まず削除
    netsh.exe interface portproxy delete v4tov4 listenaddress=$HOST_IP listenport=$PORT2
    netsh.exe interface portproxy add v4tov4 connectaddress=$IP connectport=$PORT listenaddress=$HOST_IP listenport=$PORT2
}

forward 22 2222 # SSHは2222に転送
# 以下はLaravel Sail用なので適宜変更
forward 3306 # mysql
forward 6379 # redis
forward 7700 # meilisearch
forward 8025 # mailhog
forward 8000 # web

# 自動起動
sc.exe config iphlpsvc start=auto
sc.exe start iphlpsvc
sudo service restart ssh


上記のスクリプトを書く。以下のことをしている

  1. ホストのipconfig.exe を叩いてIPを取る。先程固定したが念の為。
  2. ゲストのIPを取る。
  3. netsh.exe でポートフォワードを設定する。ドキュメントはこちら
    1. forward関数に2つ目の引数を渡したら、VMとホストで違うポートを使う(222222)
    2. 渡されなかったら単に同じポートを使う。
  4. SSHサービス毎回再起動。しないとゲストのIPが変わってreset by peer と怒られる


状況確認

netsh.exe interface portproxy show v4tov4


ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
固定したIP      2222        WSLのIP         22
# 後略


こんな感じになるはず。この場合 2222 番ポートにSSHすればWSLに入れる。

削除

netsh.exe interface portproxy delete v4tov4 listenaddress=固定したIP listenport=ポート


なんか間違えたときはこれで削除。ホストIPも指定せなあかんので注意。

SSH使えるようにする (WSLホスト側 2)

次に、ログオン時にポート開放するタスク設定と、ファイアウォール。

タスクスケジューラ

タスクスケジューラで以下のタスクを定義する。

  • 名前は「WSLポートフォワード」など
  • 「ユーザーがログオンしているときのみ」
  • 「最上位の特権で実行」
  • トリガーはログオン + 1分遅延を入れる
    • さもないと、何故か実行時にパラメータ不足で失敗する


wsl -u root --exec /bin/port_forward.sh

操作は上記のコマンド。


多分これでいいはず。

ファイアウォール

control firewall.cpl


ファイアウォールを開ける。「詳細設定」→「受信の規則」から新しいルールを追加し、

  • ポート
  • TCP
  • 2222,3306

という風に必要なポートを開ける。

リモート開発 (WSLゲスト側2)

あとは、リモート開発をする。
開けたポートを使うようなコンテナを動かしていく。

cd 任意の開発用ディレクトリ
curl -s https://laravel.build/laravel-sandbox | bash


面倒なので一発で立ち上がるやつ。これをやらかすと laravel-sandboxLaravel一式がクローンされ、勝手にdocker-compose.ymlに書いてあるコンテナのビルドや、.envのコピーまで始めてくれる。一式というと、PHPもComposerもDBもここでビルドするので、割と時間がかかる。

cd laravel-sandbox
sed -i 's/APP_URL=http:\/\/localhost/APP_URL=http:\/\/localhost\nAPP_PORT=8000/' .env
./vendor/bin/sail up

80番になっているので APP_PORT=8000 に変えて起動。

メインPC

vi ~/.ssh/config


Host wsl
  HostName 固定したIP
  Port 2222
  User WSLのユーザ名


ssh wsl


これでWSLに入って開発できるはず。VSCodeやJetBrainsのSSH機能も使える。


SSHだけじゃなく、8000番台とかも開放したのでWebアプリの動作確認もできる。

PhpStormがRAM4GB要求してくる

JetBrains系IDEはみんなこうなのか試してないが、PhpStormは4GM要求してきた。
俺のWSLマシンのRAMが4GBしかなく、フルにWSLに割り振る必要が出てきた。

wsl --exec vi /mnt/c/Users/ユーザー/.wslconfig


[wsl2]
memory=4GB


wsl --shutdown


まあ実際は4GB割り振れないんだが、誤魔化せる

▲passwordはpasswordではない(多分翻訳ミス)

参考


取得に失敗しました

2021年度 入部

Twitter GitHub