はじめに

Qiitaにも投稿しました。

VSCode + DockerでPlatformIOの開発環境を構築した際、PlatformIOのHome画面(PIO Home)が表示されなくなるという問題に遭遇しました。

解決方法

VSCodeの設定であるremote.autoForwardPortsSourceprocessに変更します。

設定画面からその項目の設定をリセットするか、settings.jsonからその設定項目を削除してください。

問題発生の経緯

以下のようなDockerfileで環境を構築しています。devcontainer.jsondocker-compose.ymlは記事の下に記述しておきます。

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt update && \
    apt install -y tzdata && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apt install -y build-essential gdb

RUN apt update && \
    apt install -y software-properties-common && \
    add-apt-repository ppa:deadsnakes/ppa && \
    apt update && \
    apt install -y python3.11 python3.11-venv && \
    update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1 && \
    update-alternatives --install /usr/bin/py py /usr/bin/python3.11 1

RUN apt update && \
    apt install -y git vim locales-all

最初にビルドした際は、正常に動作しておりPIO Homeも問題なく表示されていたため、そのコンテナーをそのまま使用していました。

ある日、イメージの軽量化を目的にDockerfileを少し修正してコンテナーをリビルドしたところ、PIO Homeが真っ白になり、何も表示されなくなってしまいました。

最初はPlatformIOやPython環境を疑っていました。しかしDockerfileの内容は以前と同じものであり、PlatformIOのバージョンもPythonのバージョンも変わっていません。

また、pip install -U platformio でPlatformIOを再インストールすると一度だけ正常に表示されたのですが、すぐに再発してしまいました。

問題の原因

VSCodeの開発者ツールでNetworkタブを見ながらPIO Homeを開いてみました。
(Ctrl + Shift + PDeveloper: Toggle Developer Toolsで開発者ツールを開けます)

すると、送られたリクエストの中の1つに、statusが(failed)net::ERR_CONNECTION_REFUSEDとなっているものを見つけたのです。

調べたところ、StorybookでlazyCompilationを使うとエラーになるという記事を見つけました。
この記事の通り、この問題の原因はremote.autoForwardPortsSourceというVSCodeの設定において、process以外を設定しているという点にあるようでした。

なぜこの設定が問題だったのか?

PIO Homeが表示される仕組み

PIO Homeは、内部的にWebサーバーを起動してその画面をVSCode内に表示する、WebViewという仕組みで動いています。

VSCodeはDockerコンテナ内で起動したWebサーバーのポートを、ホストOSに自動で転送(ポートフォワーディング)しています。
そこで転送されたポートをVSCodeのタブで開くことで、PIO Homeが表示されるのです。

ここで、VSCodeがポートを自動的に転送するという点において、remote.autoForwardPortsSourceの設定が密接に関わってきます。

remote.autoForwardPortsSourceとは

remote.autoForwardPortsSourceのそれぞれの選択肢は以下のように説明されています。

  • process: ポートは、開始済みで、ポートが含まれるプロセスを監視することによって検出された時に自動的に転送されます。

  • output: ポートは、ターミナルとデバッグの出力を読み取ることによって検出されたときに自動的に転送されます。 ポートを使用するすべてのプロセスで統合ターミナルまたはデバッグ コンソールに出力されるわけではないため、一部のポートは見逃されます。出力に基づいて転送されたボートは、再度読み込むか、ユーザーがポート ビューでポートを閉じない限り、"転送を解除"されることはありません。

  • hybrid: ポートは、ターミナルとデバッグの出力を読み取ることによって検出されたときに自動的に転送されます。 ポートを使用するすべてのプロセスで統合ターミナルまたはデバッグ コンソールに出力されるわけではないため、一部のポートは見逃されます。ポートは、終了するこのポートをリッスンするプロセスをモニタリングすることで“転送が解除されます。

つまり、outputもしくはhybridに設定していた場合、ターミナルもしくはデバッグコンソールにポート番号が出力されない限り、VSCodeはそのポートを転送してくれません。
一方でprocessに設定していると、プロセスの監視によってポートを検出し、転送してくれます。

しかし私の場合では、この設定項目がhybridに設定されていました。
そしてPlatformIOはPIO Homeのポート番号をターミナル・デバッグコンソールのいずれにも出力してくれないため、ポートの転送は行われず、VSCodeで開くことも出来ないというわけでした。

まとめ

PlatformIOに限らず、WebViewによって表示されるはずのタブに何も表示されない、という症状がある方はこの設定項目を見直してみてください。

おまけ

前述のDockerfileと下記の2つのファイルを.devcontainerディレクトリに入れてコンテナーを起動しています。

devcontainer.json

{
  "name": "pio",
  "dockerComposeFile": "./docker-compose.yml",
  "service": "pio",
  "workspaceFolder": "/pio",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-vscode.cpptools-extension-pack",
        "formulahendry.code-runner",
        "leodevbro.blockman",
        "streetsidesoftware.code-spell-checker",
        "usernamehw.errorlens",
        "MS-CEINTL.vscode-language-pack-ja",
        "PKief.material-icon-theme",
        "christian-kohler.path-intellisense",
        "shardulm94.trailing-spaces",
        "vscodevim.vim",
        "tal7aouy.indent-colorizer",
        "mhutchie.git-graph",
        "eamodio.gitlens",
        "donjayamanne.githistory",
        "platformio.platformio-ide"
      ]
    }
  }
}

docker-compose.yml

{username}には適宜入力してください。

version: '3.9'

services:
  pio:
    tty: true
    build:
      dockerfile: ./Dockerfile
      context: .
    volumes:
      - type: volume
        source: pio
        target: /pio
      - type: bind
        source: C:/Users/{username}/.ssh
        target: /root/.ssh/
    command: [ "bash" ]

volumes:
  pio: