OpenCode + Cloudflareで外出先から進捗確認や指示ができるようにした

OpenCode + Cloudflareで外出先から進捗確認や指示ができるようにした

私は自宅ではOpenCodeでコーディングをしていますが、仕様の確認や権限確認などで知らない間に止まってることがあります。
そこで、入浴中でも外出先でも進捗確認やAIの質問への回答などできるようにして、AIのタスクが止まらないようにしたいという気持ちがありました。
今回、自宅PCで動かしているOpenCodeを、Cloudflare Zero Trust経由でiPhoneから安全に確認・操作できるようになりましたので、ここにメモを残します。

ネットワーク構成はこんな感じ。自宅ではWindowsのWSL環境にUbuntuを入れて、Docker Sandboxes + OpenCodeを使っています。

d1b8426e-1ad5-4d22-a05a-e42008e26d99
d1b8426e-1ad5-4d22-a05a-e42008e26d99

シンプルにテキストで書くとこうなる。

iPhone
  ↓ Cloudflare One Agent / WARP
Cloudflare Zero Trust
  ↓ Private CIDR Route
Windows
  ↓ WSL / Docker Sandbox
OpenCode Web

公開URLは作らず、Cloudflare Zero Trustに登録したWARP端末からだけ接続できる構成にする。

この記事では説明用に接続先IPを 192.168.0.100 としている。実際には自分の環境のIPへ置き換える。
また、プロジェクト名は HogeTara としています。これもご自分の環境で読み替えてください。

環境

今回使ったWindows・WSL・Docker・OpenCode・Cloudflareの構成。

  • Windows 11
  • WSL2 / Ubuntu 24.04
  • Docker Desktop
  • Docker Sandboxes
  • OpenCode
  • Cloudflare Zero Trust
  • iPhone + Cloudflare One Agent

例:

Sandbox: opencode-HogeTara
Project: /home/hiroe/src/HogeTara
Port: 4096
Private IP: 192.168.0.100

1. Docker Sandboxのポートを公開

Sandbox内のOpenCodeをWindows側の localhost:4096 からアクセスできるようにする。

WSLで実行。

sbx ports opencode-HogeTara --publish 4096:4096

確認。

sbx ports opencode-HogeTara

以下のようになればOK。

127.0.0.1:4096 -> 4096/tcp4

2. OpenCode Webのパスワードを保存

OpenCode Webを外部から操作するため、Basic認証用のパスワードを安全なファイルに保存する。

以下を実行。

mkdir -p ~/.config/opencode

read -rsp "OpenCode password: " OC_PASS; echo
umask 077

printf 'OPENCODE_SERVER_PASSWORD=%s\n' "$OC_PASS" \
  > ~/.config/opencode/server.env

unset OC_PASS
chmod 600 ~/.config/opencode/server.env

起動確認。

sbx exec \
  --env-file "$HOME/.config/opencode/server.env" \
  opencode-HogeTara \
  opencode web --hostname 0.0.0.0 --port 4096

Windowsから確認。

curl.exe -i http://localhost:4096

以下ならOK。

HTTP/1.1 401 Unauthorized

3. OpenCode Webを自動起動

WindowsへログインしたときにOpenCode Webが自動でバックグラウンド起動するようにする。

WSLに起動スクリプトを作成。

mkdir -p ~/bin

cat > ~/bin/start-opencode-web.sh <<'EOF'
#!/usr/bin/env bash
set -u

LOG="$HOME/.local/state/opencode-web-startup.log"
mkdir -p "$(dirname "$LOG")"
exec >>"$LOG" 2>&1

for i in $(seq 1 60); do
  if sbx ls >/dev/null 2>&1; then
    exec sbx exec \
      --env-file "$HOME/.config/opencode/server.env" \
      opencode-HogeTara \
      opencode web --hostname 0.0.0.0 --port 4096
  fi

  sleep 5
done

exit 1
EOF

chmod 700 ~/bin/start-opencode-web.sh

Windowsに非表示起動用VBSを作成。

$dir = "$env:LOCALAPPDATA\OpenCode"
New-Item -ItemType Directory -Force -Path $dir | Out-Null

@'
Set shell = CreateObject("WScript.Shell")
shell.Run "wsl.exe -d Ubuntu-24.04 -- bash -lc ""~/bin/start-opencode-web.sh""", 0, False
'@ | Set-Content "$dir\start-opencode-hidden.vbs" -Encoding ASCII

ログイン時に実行するタスクを登録。

$vbs = "$env:LOCALAPPDATA\OpenCode\start-opencode-hidden.vbs"

$action = New-ScheduledTaskAction `
  -Execute "$env:SystemRoot\System32\wscript.exe" `
  -Argument "`"$vbs`""

$trigger = New-ScheduledTaskTrigger `
  -AtLogOn `
  -User "$env:USERDOMAIN\$env:USERNAME"

$principal = New-ScheduledTaskPrincipal `
  -UserId "$env:USERDOMAIN\$env:USERNAME" `
  -LogonType Interactive `
  -RunLevel Limited

$settings = New-ScheduledTaskSettingsSet `
  -StartWhenAvailable `
  -MultipleInstances IgnoreNew `
  -ExecutionTimeLimit ([TimeSpan]::Zero)

Register-ScheduledTask `
  -TaskName "OpenCode Web" `
  -Action $action `
  -Trigger $trigger `
  -Principal $principal `
  -Settings $settings `
  -Force

4. Cloudflare TunnelをWindowsに導入

Cloudflare側から自宅Windowsへ安全に到達するためのTunnelを作る。

winget install --id Cloudflare.cloudflared

Cloudflare Zero TrustでTunnelを作成し、表示されたWindows用コマンドを管理者PowerShellで実行する。

cloudflared.exe service install <Cloudflareが表示したトークン>

Tunnelが Connected になればOK。

今回は Published Applicationは作らない。

5. Windows側でOpenCodeへ転送

Cloudflare Tunnelから届く通信を、Windowsの内部IPから localhost:4096 へ転送する。

内部向けIPを確認。

Get-NetIPAddress -AddressFamily IPv4 |
  Where-Object {
    $_.IPAddress -notlike "127.*" -and
    $_.AddressState -eq "Preferred"
  } |
  Select-Object InterfaceAlias, IPAddress, PrefixLength

この記事では説明用に以下を使用する。

192.168.0.100

Windowsの portproxy を設定。

netsh interface portproxy add v4tov4 `
  listenaddress=192.168.0.100 `
  listenport=4096 `
  connectaddress=127.0.0.1 `
  connectport=4096

確認。

curl.exe -i http://192.168.0.100:4096

401 Unauthorized が返ればOK。

6. CloudflareにPrivate CIDR Routeを追加

WARP端末から 192.168.0.100 宛ての通信をCloudflare Tunnelへ流す。

Cloudflare Zero Trustで:

Networking
→ Routes
→ Create route
→ Tunnel CIDR

以下を登録。

Connector: 作成したTunnel
Network:   192.168.0.100/32

7. iPhoneをZero Trustに登録

iPhoneを自分のCloudflare Zero Trust環境へ参加させる。

iPhoneへ Cloudflare One Agent をインストールし、Team Nameを入力してログインする。

接続後、

https://help.teams.cloudflare.com/

で以下を確認。

Your network is fully protected

Device Profileは、

Traffic and DNS mode

にする。

8. Split Tunnelを調整

OpenCode用IPだけはローカル除外せず、WARP経由でCloudflareへ送るようにする。

Split Tunnelsが、

Exclude IPs and domains

の場合、192.168.0.100 が除外範囲に含まれているとCloudflareへ流れない。

その場合は除外設定を調整して、

192.168.0.100/32

だけはWARPを通るようにする。

設定後、iPhoneのCloudflare One Agentを再接続する。

反映されない場合はiPhoneを再起動する。

9. iPhoneからOpenCodeへ接続

WARP接続中のiPhoneからWindows上のOpenCode Webへ直接アクセスする。

WARPをONにしてSafariから:

http://192.168.0.100:4096

OpenCodeのBasic認証:

ユーザー名: opencode
パスワード: OPENCODE_SERVER_PASSWORD

OpenCode Webが表示されれば完成。

WARPをOFFにすると接続できない。

10. PCのTUIも同じOpenCodeへ接続

PCのTUIとiPhoneのWeb UIを同じOpenCodeサーバーへ接続し、同じセッションを共有する。

read -rsp "OpenCode password: " OC_PASS; echo

sbx exec -it opencode-HogeTara -- env \
  OPENCODE_SERVER_PASSWORD="$OC_PASS" \
  opencode attach http://127.0.0.1:4096 \
  --dir /home/hiroe/src/HogeTara

これで:

PCのOpenCode TUI
        ↕
同じOpenCode Server
        ↕
iPhoneのOpenCode Web

PCでOpenCodeに作業を任せて外出し、iPhoneから進捗確認や追加指示ができる。

完成

WARPに登録したiPhoneだけがCloudflareのPrivate Routeを通って自宅OpenCodeへ接続できる構成になる。

iPhone
  │
  │ Cloudflare One Agent / WARP
  ▼
Cloudflare Zero Trust
  │
  │ Private CIDR Route
  ▼
192.168.0.100:4096
  │
  │ Windows portproxy
  ▼
127.0.0.1:4096
  │
  ▼
Docker Sandbox
  │
  ▼
OpenCode Web

公開ホスト名は使用しない。

Cloudflare Zero Trustに登録したWARP端末からだけOpenCodeへアクセスでき、OpenCode側のBasic認証も有効にしている。

© 2025 Hiroe Tech Notes. All rights reserved.

コメント

まだコメントはありません。