Tutorial
10 min read
53 views

DevContainersのサイドカー プロキシ トンネル:安全なローカル開発の最新標準

IT
InstaTunnel Team
Published by our engineering team
DevContainersのサイドカー プロキシ トンネル:安全なローカル開発の最新標準

ホストマシンにトンネリングツールをインストールするのはやめましょう。ngrokcloudflared、またはその他のトンネリングデーモンをノートパソコン上で不正に実行するのはアンチパターンであり、過去の話です。2026年には、ネットワークトポロジー全体 — パブリックトンネルアクセスも含めて — をdevcontainer.json内にコード化するのが正しいアプローチです。このガイドでは、その方法、選ぶべきツール、そしてこのアーキテクチャの変化がなぜ重要かについて解説します。


なぜ従来の方法は破綻するのか

従来の開発者のワークフローは次のようなものです:リポジトリをクローンし、依存関係をインストールし、ngrokをグローバルにインストールし、トンネルを立ち上げ、URLを貼り付け、セッションが切れるたびに繰り返す。これは動作しますが、問題もあります。

チームが大きくなるにつれて、問題は複雑化します:

  • 再現性の欠如。 マシン上のトンネルツールのバージョンが同僚と異なる。挙動が分岐し、バグの原因が誤った層に責任を押し付けられる。
  • セキュリティのずれ。 グローバルにインストールされたデーモンがネットワークアクセスを持ち、コンテナの境界外に存在します。その資格情報はホームディレクトリに保存され、暗号化されていないことも多い。
  • ポートの衝突。 30008080のようなハードコーディングされたポートがプロジェクト間で競合します。どのプロジェクトがどのポートを所有しているか覚え始める。これはエンジニアリングではなく、考古学です。
  • オンボーディングの摩擦。 新しい開発者はトンネルツール用の別個のセットアップガイドを必要とし、そのガイドは古くなる。

Microsoftとコミュニティが共同で管理するDevContainer仕様は、環境レベルでこれを解決します。devcontainer.json内にdockerComposeFileを定義し、サイドカーサービスを追加することで、トンネルをソフトウェアサプライチェーンの一級品、バージョン管理されたコンポーネントにします — デフォルトでは一時的、設計上再現可能です。


アーキテクチャ:サイドカーコンテナの仕組み

サイドカーのパターンはマイクロサービスアーキテクチャに由来します。サイドカーは、メインのアプリケーションコンテナの横に実行される補助的なコンテナで、ネットワーク名前空間を共有しますが、異なる運用上の関心事を処理します — この場合はトンネリングです。アプリケーションコードはトンネルに触れず、トンネルもアプリケーションコードに触れません。両者とも使い捨てであり、スノーフレークではありません。

Docker Composeの観点からは、次のようなレイアウトになります:

.devcontainer/
├── devcontainer.json
├── docker-compose.yml
└── (任意) Dockerfile

メインのappサービスはコードを実行します。トンネルのサイドカー — cloudflaredzrok、または代替品 — は依存サービスとして動作し、アプリが正常になった後に起動し、Composeスタックが破棄されるときにきれいに終了します。


オプション1:Cloudflare Tunnel(cloudflared)

Cloudflare Tunnelは、cloudflaredデーモンを介してアクセスされ、DNSに既にCloudflareを使用しているチームに最も広く展開されている選択肢です。アウトバウンド専用の接続をCloudflareのエッジネットワークに確立し、インバウンドのファイアウォールルールやパブリックIPアドレスは不要です。

トークンの取得

Cloudflare Zero Trustダッシュボードから名前付きトンネルを作成します。セットアップ中にCloudflareがTUNNEL_TOKENを生成します。すぐにコピーしてください — もう表示されません。これをローカル環境変数やシークレットマネージャー(GitHub Codespacesのシークレット、GitLab CIの変数など)に保存し、リポジトリには絶対に保存しないでください。

docker-compose.yml

version: '3.8'

services:
  app:
    image: mcr.microsoft.com/devcontainers/node:20
    volumes:
      - ../:/workspace:cached
    command: sleep infinity
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s

  cloudflared:
    image: cloudflare/cloudflared:latest
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
    depends_on:
      app:
        condition: service_healthy
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

devcontainer.json

{
  "name": "Node.js + Cloudflare Tunnel",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",

  "remoteEnv": {
    "CLOUDFLARE_TUNNEL_TOKEN": "${localEnv:CLOUDFLARE_TUNNEL_TOKEN}"
  },

  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint"
      ]
    }
  }
}

${localEnv:VARIABLE_NAME}構文は、DevContainerエンジンに対し、起動時にホスト環境から値を読み込み、Composeのコンテキストに注入するよう指示します。資格情報はリポジトリに触れません。トンネルは認証され、接続され、最初のnpm run devの前に準備完了です。

セキュリティ注意: cloudflaredコンテナのnetwork_modeは、内部Dockerネットワークを通じてのみ通信できるように設定してください — network_mode: hostは避けてください。これにより、トンネルサイドカーはサービス名でappコンテナに到達できますが、ホストのネットワークスタックを直接調査することはできません。


オプション2:Zrok — ゼロトラスト一時トンネル

Cloudflareが管理環境で圧倒的なシェアを持つ一方、zrokはOpenZitiのゼロトラストネットワーキングオーバーレイ上に構築され、インフラの完全な制御や完全に一時的なURLを望む開発者に支持されています。Zrokは2025年末に1.0に到達し、新しいエージェントコンソール、予約済みシェアの永続性、自動TLS対応のCaddyを使った自己ホスティングオプションを提供します。

最大の特徴は、zrokのシェアを停止すると、そのURLは即座に消えることです。DNSレコードやゾンビトンネル、資格情報の孤立はありません。これはエフェメラルなDevContainerのコンテキストにおいて、まさに理想的な挙動です。

また、プライベートシェアもサポートしており、リソースは公開エンドポイントに露出せず、すべての通信はzrokクライアント間でエンドツーエンド暗号化されます。これは、チーム内のレビュー環境で公開URLを一切使いたくない場合に有用です。

docker-compose.yml

version: '3.8'

services:
  app:
    image: mcr.microsoft.com/devcontainers/python:3.11
    volumes:
      - ../:/workspace:cached
    command: sleep infinity
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s

  zrok-sidecar:
    image: openziti/zrok:latest
    environment:
      - ZROK_ENABLE_TOKEN=${ZROK_TOKEN}
    depends_on:
      app:
        condition: service_healthy
    command: 
      sh -c "zrok enable $$ZROK_ENABLE_TOKEN 6
             zrok share public http://app:8000 --headless"

スタック起動時に、サイドカーはトークンを使ってzrok環境を有効化し、すぐにポート8000のPythonアプリにルーティングされる一時的な公開URLをプロビジョニングします。URLはコンテナのログに出力されます。docker compose downを呼び出すと、zrokプロセスは終了し、シェアは破棄されます。

生成されたURLを取得するには、サイドカーのログを確認します:

docker logs <project>-zrok-sidecar-1

または、サイドカーにURLを書き込み、postStartCommandで共有ボリュームから読み取ってVS Codeのターミナルに表示させる設定も可能です。


オプション3:pgrok — セルフホスト型マルチテナントトンネル

エンタープライズレベルのトンネリングをコストを抑えて実現したいチーム向けに、pgrokは自社ドメイン上でホストするSSHベースのマルチテナントソリューションを提供します。OIDC認証をサポートし、開発者は既存のSSOプロバイダー(Okta、Auth0、Google Workspaceなど)を通じて認証し、その後にトンネルURLが発行されます。URLはhttps://feature-x.alice.dev.example.comのようなパターンで、安定していて人間にも読みやすく、個々の開発者にスコープされます。Kubernetesのオペレーターはpgrokをサイドカーとして自動挿入でき、各ポッドにレビュー可能なURLを付与します。

既にドメインとSSOプロバイダーを運用しているチームには、これがほぼ”エンタープライズngrok”の体験をインフラコスト数ドル/月で提供します。


2026年のトンネリングツールの動向

ngrokへの競争圧力は激化しています。2026年2月、DDEVのオープンソースプロジェクトは、無料枠の制限強化を理由に、ngrokをデフォルトの共有プロバイダーから外すことを検討するIssueを立てました。市場は、さまざまな価格帯で有効な代替手段を提供しています:

ツール モデル 最適な用途 無料枠
Cloudflare Tunnel マネージドSaaS Cloudflare DNSを利用するチーム あり(寛大)
zrok オープンソース / SaaS 一時的、ゼロトラスト、セルフホスト あり
pgrok セルフホスト 独自ドメイン+SSOのチーム インフラコストのみ
Tailscale Funnel メッシュVPN プライベートチームアクセス、WireGuardベース あり(個人用)
Inlets セルフホスト / SaaS Kubernetesネイティブ、Prometheusメトリクス なし($25+/月)
ngrok マネージドSaaS ドキュメント充実、広くサポート 2026年に制限

Webhookテスト、つまり最も一般的なDevContainerのユースケースにおいては、Cloudflare Tunnel(永続的な名前付きURL)とzrok(一時的URL)が有力な選択肢です。Cloudflareは、サードパーティサービス(Stripe、GitHub)のWebhookエンドポイントを一度設定すれば、その後変更しない場合に最適です。zrokは、永続性のないセッションごとのURLと最大の隔離を求める場合に適しています。


ベストプラクティス

1. ヘルスチェックとdepends_on条件を常に使用する

サイドカーのトンネル設定で最もよくある失敗は、アプリケーションの起動前にトンネルがオンラインになり、502 Bad Gatewayエラーが発生することです。これを防ぐには、appサービスに明示的なヘルスチェックを設定し、サイドカーのdepends_onブロックにcondition: service_healthyを記述します。これが必須です。

depends_on:
  app:
    condition: service_healthy

これがなければ、Docker Composeはコンテナの起動順序だけを保証し、アプリの準備完了は保証しません。

2. ホストのポートマッピングは避ける

トンネルをサイドカー経由でルーティングする場合、ports: - "3000:3000"のようなコンテナのポートをホストに公開する必要はありません。これらのマッピングを削除してください。これにより、ポートの衝突は完全に解消され、同じマシン上の別のプロジェクトがポート3000を使っても競合しません。開発中にローカルブラウザからアクセスしたい場合は、VS Codeのポートフォワーディング機能を使い、静的なDockerポートマッピングは避けてください。

3. シークレットの安全な注入

devcontainer.json${localEnv:VARIABLE_NAME}パターンは、すべての環境で正しいアプローチです。GitHub Codespacesでは、CLOUDFLARE_TUNNEL_TOKENZROK_TOKENをCodespacesのユーザシークレットインターフェースに保存してください。起動時に自動的に環境変数として注入され、${localEnv:...}がそれを読み取ります。資格情報を.envファイルに書き込み、それをgitで追跡することは絶対に避けてください。.gitignore.envを追加し、ローカル専用のファイルとして扱います。

4. サイドカーコンテナのログ可視化

サイドカーはバックグラウンドコンテナとして動作するため、そのログはVS Codeのメインターミナルには表示されません。開発者は積極的に取得する必要があります。実用的な方法は以下の通りです:

  • VS CodeのDocker拡張を使ってサイドバーから個別のコンテナログを追尾
  • ホスト端末でdocker logs <project>-zrok-sidecar-1 --followを実行
  • devcontainer.json内にpostStartCommandを設定し、サイドカーが書き込むURLを共有ボリュームから読み取り、ターミナルに表示させる

3つ目の方法が最も開発者体験に優れ、コンテナ起動時に自動的に公開URLがVS Codeのターミナルに表示され、手動のログ確認が不要になります。

5. 本番環境のイメージバージョン固定

個人の実験にはcloudflare/cloudflared:latestopenziti/zrok:latestでも問題ありませんが、リポジトリにコミットされたチームのDevContainerでは、特定のダイジェストやバージョンタグに固定してください。これにより、上流のイメージの自動更新による環境破壊を防ぎます。特にcloudflaredzrokは頻繁にリリースされるためです。

image: cloudflare/cloudflared:2025.2.0

まとめ:完全なワークフロー

これが正しく設定されたときのエンドツーエンドの開発者体験です:

  1. 開発者がリポジトリをクローン
  2. VS Codeが.devcontainer/devcontainer.jsonを検知し、コンテナで再オープンを促す
  3. Docker Composeがappコンテナとトンネルサイドカーを起動
  4. appコンテナがヘルスチェックを行い、正常になったらサイドカーが起動
  5. サイドカーが認証し、トンネルをプロビジョニングし、公開URLを共有ボリュームに書き込み
  6. postStartCommandがURLを読み取り、ターミナルに表示
  7. 数秒以内にhttps://my-project.example.comのようなURLがVS Codeのターミナルに表示される
  8. そのURLをStripeのWebhook設定に貼り付けてコーディング開始
  9. Ctrl+Cで停止すると、トンネルも破棄される。クリーンアップ不要。

ホストにツールをインストールする必要も、トークンを手動で管理する必要も、ポートの衝突も、古いURLもありません。これにより、ラップトップの蓋を閉じた後も古いURLが残ることはありません。


結論

DevContainerのサイドカー プロキシパターンは、2026年の標準的なlocalhostトンネリングの方法です。Cloudflare Tunnelの信頼性、zrokのゼロトラスト一時モデル、pgrokのインフラ所有権のいずれを選ぶにせよ、原則は同じです:トンネリングインフラはアプリケーションコードとともにバージョン管理されたコンテナ定義内に置くべきであり、開発者のホストマシンにアドホックにインストールすべきではありません。

これにより、オンボーディングの高速化、セキュリティの向上、ネットワーク挙動の再現性、そして”私のマシンでは動く”というトンネリングバグの根絶が実現します。Dockerはこの種の運用上の関心事をカプセル化するために設計されています。これを活用しましょう。

Continue from this article into the most relevant product guides and workflows.

Related Topics

#DevContainer sidecar proxy, docker localhost tunnel, devcontainer.json networking, isolated proxy container, ephemeral localhost tunnels, Cloudflared devcontainer sidecar, Zrok docker sidecar, zero-install dev networking, infrastructure as code tunnels, local development security, preventing host machine pollution, secure Docker networking, automated tunnel deployment, reverse proxy container, isolated development environments, cloud-native local development, tunneling inside containers, embedded proxy agent, developer environment standardization, devops localhost routing, immutable dev environments, secure webhook testing Docker, declarative development infrastructure

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles