Playwrightを使ってアプリを開発しているときにデバッグ起動したりUIモードで起動したりする場合、コンテナ上で起動するGUIをホストOS上に表示する必要があるため、X Window Systemが必要(Playwrightをコマンドラインのみで利用する場合いらない)。
Dev Containersを使ってる環境だと何も設定をせずにコンテナ上でGUIを起動しようとするとMissing X server or $DISPLAYのようなエラーが発生します。これを回避するにはホストOS側でXクライアントを用意してあげればいいです。
というわけで自分の場合はホストOSとしてMacを利用しているため Xquartz を使って環境を作ります。Playwrightのインストールなどのセットアップ自体はここでは触れません。
とりあえずHomebrewでXquartzをインストールします。
# Install Xquartz $ brew install --cask xquartz
インストールしたらXQuartzを起動して、設定から以下のようにチェックを入れて、認証を不要にしつつ、コンテナからのアクセスを許可するためネットワーク・クライアントからの接続を許可します。

下記のようにコマンドラインから実行してもいい。
$ defaults write org.xquartz.X11 nolisten_tcp 0
次にDev Container側でX Window System関連の設定をします。
/tmp/.X11-unixをホスト側とコンテナ側で共有することにより、ドメインソケットを共有します。 devcontainer.jsonに以下を追加します。
"mounts": [
{
"type": "bind",
"source": "/tmp/.X11-unix",
"target": "/tmp/.X11-unix"
}
]
実行時はホストOSのディスプレイを利用するために以下のように実行時のターミナルで環境変数を設定します。
$ export DISPLAY=host.docker.internal:0.0
もしくはこれもdevcontainer.jsonで指定してしまうこともOKです。
"containerEnv": {
"DISPLAY": "host.docker.internal:0.0"
}
devcontainer.jsonを変更したらコンテナ自体はリビルドしてください。
あとは試しに実行してみます。以下はPythonのテストコード。
from playwright.sync_api import sync_playwright
def run():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False) # headless=True で非表示起動
page = browser.new_page()
page.goto("https://www.google.com")
print(page.title()) # "Google" が出力されれば成功
browser.close()
if __name__ == "__main__":
run()
無事に動いた。