K Kristopher Baker iOS · グロース · 東京
← 記事一覧へ

2026.04.01 · 1 分で読了

制約ありきで組んだリモート開発環境

日本の電車の中でスマートフォンを取り出して、自宅のMacで動かしている開発セッションに再接続し、そのまま作業を続ける。今となっては、そこまで突飛な話ではありません。

ただ、それを「ちゃんと使える状態」にする——しかもスマホから、既存の環境を壊さずに、安定して動かす——となると、話は少し変わってきます。

そしてちょうど環境が安定してきた頃に、Claude Codeに Claude Code Remote ControlClaude Code Dispatch がリリースされました。この話は後半で触れます。

なぜTailscaleを使わなかったのか

個人のマシンに安全にリモートアクセスしたい、という相談を受けたら、おそらく私は「Tailscaleを使えばいい」と答えて終わりにすると思います。それくらい優秀なツールですし、多くのケースではそれで十分です。

ただ、自分の状況は少しだけややこしいものでした。

自宅のMacでは業務用VPNが常時動いており、個人用と会社用のTailscaleアカウントを同一マシンで混在させたくありませんでした。また、自宅ネットワークをインターネットからの直接接続にさらすのも避けたかった。さらに、スマホ(しかもWi-Fiとモバイル回線を頻繁に切り替える環境)から使う前提だったので、通常のSSHセッションが切れてしまうような状況でも耐えられる必要がありました。

どれか一つだけなら簡単に解決できる制約です。ただ、それらが重なると、見た目がきれいな構成から順番に候補から外れていきます。最終的に残ったのは、最もエレガントな構成ではなく、実際の制約にちゃんとフィットする構成でした。

全体の構成

最終的な構成はシンプルな「連鎖」です。それぞれの要素には明確な役割があります。

flowchart LR
    phone[Phone]
    mosh[mosh]
    vps[VPS]
    reverse[reverse SSH]
    mac[Mac]
    tmux[tmux]
    tools[Claude Code]

    phone --> mosh --> vps --> reverse --> mac --> tmux --> tools

スマートフォンからは mosh を使ってVPSに接続します。モバイル回線ではIPが変わったり、Wi-Fiとセルラーが切り替わったり、接続が一時的に切れたりと、通常のSSHが苦手な状況が頻発しますが、moshはそこをうまく吸収してくれます。

VPSは唯一パブリックに公開されているポイントです。自宅のMacからはアウトバウンドのリバースSSHトンネルでVPSに接続しているため、Mac側はインターネットからの着信を一切受ける必要がありません。

そしてMac上の tmux によって、接続は単なる「一時的なセッション」ではなく、「いつでも戻ってこられる状態」に変わります。

この点は意外でした。セッション自体が持続するようになると、スマホは「制限された入口」ではなくなります。どこかに再接続しているというより、進行中の作業にそのまま戻っている感覚に近くなります。

実際にハマったポイント

学びの大半は、最初の設計ではなく、うまくいかなかった部分から来ています。

リバースSSHトンネルは、しばらく放置すると半死状態になることがありました。VPS上ではポート22は開いているように見える。でも実際にはセッションが裏で切れていて、Macに接続しようとするとハングする。

これを解決したのは単一の設定ではなく、「生存確認」をちゃんと扱うことでした。Mac側からのSSH keepalive、接続が落ちたときに再構築する autossh、そしてVPS側で localhost:22 が実際に応答しているか確認してから接続するスクリプト。

このジャンプ用スクリプトも学びの一つでした。最初はVPSに接続するたびにMacへSSHしようとしていたのですが、トンネルが落ちているとただハングするだけで何もできません。

改善後は、ポートを事前にチェックし、短いタイムアウトを設定し、ダメならVPSのシェルにフォールバックするようにしました。小さな変更ですが、「たまに使える」状態から「安心して使える」状態への差はここにありました。

tmux も同様です。ある環境で作ったセッションを別の環境から再接続すると、うまく表示されないことがありました。自分の場合はMac側の xterm-ghostty が原因で、モバイル側クライアントとの相性問題が出ていました。より汎用的なterminal設定に変更することで解決しましたが、「持続するセッション」はその前提条件に依存する、という当たり前のことを改めて実感しました。

どれも大きな問題ではありません。ただ、この手の「半分だけ解決されている問題」が積み重なると、結局その環境は使われなくなります。

その頃、ツール側も進化していた

ちょうどこの構成が安定したタイミングで、同じ領域をカバーする機能が登場しました。

Claude Code Remote Control は、ローカルで動いているClaude Codeのセッションをスマホやブラウザからそのまま操作できる機能です。ファイルシステムや開発環境はローカルのまま、スマホは単なる「窓」として機能します。ポートフォワーディングもVPSも不要です。

Claude Code Dispatch はさらに一歩進んでいて、スマホからタスクを投げると、自宅のMac上で新しいセッションを立ち上げて処理してくれます。そもそも事前にセッションを立ち上げておく必要すらありません。

では、この構成を作ったのは無駄だったのか。

正直、そうは思っていません。

Remote Controlは1セッション1接続に制限されており、ネットワーク断が10分ほど続くとタイムアウトします。地方の電車などで不安定な回線を使う場合には、やや心許ない。一方、自分の構成は mosh と autossh によって長時間の切断にも耐えられます。

また、VPSという足場があることで、単にClaude Codeに限らず、「とりあえず入れるシェル」が手元にある状態になります。

ただし、今ゼロから同じことをやるかと言われたら話は別です。安定した回線環境で、スマホからClaude Codeを触りたいだけなら、まずRemote Controlを試して、そのまま終わる可能性が高いと思います。

残った学び

インフラでも、AIツールでも、そして昨年建てた家でも、同じパターンを何度も見ています。

最初の設計はきれいに見える。まだ現実とぶつかっていないからです。

実際の制約に向き合った結果できあがるものは、少し歪んで見えることもある。でも、実際に使い続けられるのはそちらの方です。

そしてもう一つ。ツールは進化し、前提条件は変わります。

今回の構成は今でも役に立っていますが、この話で伝えたいのは「これを作るべき」ということではありません。「なぜこの構成になったのか」を理解していれば、新しい選択肢が出てきたときに、どこを捨てていいか判断できる、ということです。

ツールが変わっても、その部分は残ります。

もっと読む メールで返信