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

執筆者: あんどう

最終更新: 2023/03/05

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
IP=$(ip route | grep 'eth0 proto' | cut -d ' ' -f9)

function forward() {
    PORT=$1
    # 2つめのポート指定なければ同じポートを使う
    PORT2=${2:-$PORT}
    # まず削除
    netsh.exe interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=$PORT2
    netsh.exe interface portproxy add v4tov4 connectaddress=$IP connectport=$PORT listenaddress=0.0.0.0 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とホストで違うポートを使う(22 → 2222)
    2. 渡されなかったら単に同じポートを使う。
  4. SSHサービス毎回再起動。しないとゲストのIPが変わってreset by peer と怒られる


状況確認

netsh.exe interface portproxy show v4tov4


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

Address         Port        Address         Port
--------------- ----------  --------------- ----------
0.0.0.0         2222        WSLのIP         22
# 後略


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

削除

netsh.exe interface portproxy delete v4tov4 listenport=ポート


なんか間違えたときはこれで削除。

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-sandbox にLaravel一式がクローンされ、勝手に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 WSLマシンの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