✍️

PlaywrightがRenderでクラッシュした理由と対策(headless=FalseはPaaSでは動かない)録

に公開

はじめに

Playwrightを使ってWeb画面を自動操作するスクリプトを作成し、ローカルではGUI表示(headless=False)で問題なく動作していました。

ところがRenderにデプロイした途端、スクリプトは即クラッシュ。
「設定の問題?」と思って調べていくと、“headless”という仕組みそのものを分かっていなかったと気づかされました。

この記事では、PaaS(RenderやHeroku等)でGUIブラウザ処理を動かそうとすると発生するクラッシュの原因と、正しい対処法をまとめます。


現象:headless=Falseでクラッシュする

RenderにPlaywright入りDockerをデプロイしたところ、起動時に以下のようなエラーが発生:

playwright._impl._errors.TargetClosedError: BrowserType.launch: Target page, context or browser has been closed

Browser logs:
╔════════════════════════════════════════════════════════════════════════╗
║ Looks like you launched a headed browser without having a XServer ... ║
║ Set either 'headless: true' or use 'xvfb-run <your-playwright-app>'  ║
║ before running Playwright.                                            ║
╚════════════════════════════════════════════════════════════════════════╝

ローカルでは動いていたのに、RenderなどのPaaSに載せた瞬間にクラッシュするのには、

headlessモードと「表示先の環境」にありました。


原因:PaaSには「画面を表示する仕組み(Xサーバ)」が存在しない

ローカルで headless=False にしたとき、Playwrightは「本物のブラウザ画面」を描画しようとします。(我々が使っているPCにはディスプレイがあるので、それが可能です)

でもRenderのようなPaaSには、GUI描画用の仮想ディスプレイ(Xサーバ)が存在しません。

結果として、「描画先が存在しない」 → 「ブラウザ即終了」 → 「スクリプトクラッシュ」という流れになります。


ローカル→Paas移管:よくある誤解

勘違い 実際は…
Paasでheadless=Falseで動かせば、自分のPCにブラウザ画面が出る? ❌ 出ません。Renderから画面が飛んでくることはない
PaaSが勝手に仮想ディスプレイ(Xvfb)を用意してくれる? ❌ ありません。自分で用意する必要があるけど非推奨
xvfb-runで仮想画面作ればRender上でもGUIが動く? ❌ 技術的には可能でも、Render上では制約が多く現実的ではない
Dockerを使えばGUIも含めて全部持ち運べる? ❌ 表示先はDockerではなくホストに依存するので、Paasでは無理

正解:PaaS上ではheadless=Trueにする

最もシンプルで正しい解決策は、headlessモードを明示的にONにすること です。

# Playwright
browser = await playwright.chromium.launch(headless=True)

# Selenium
options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)

headless=True なら、ブラウザをバックグラウンドで動かし、GUI描画なしで操作ができます。

これはGUI描画が不要なサーバ用途に最適な設定です。

「xvfb-runを使えば?」という罠

仮想ディスプレイ(Xvfb)を使ってGUI動作を再現する方法もあります:

xvfb-run python app.py

Dockerfileでも以下のように準備可能です:

RUN apt-get install -y xvfb

が、PaaS環境(Renderなど)ではおすすめできません。

  • xvfbプロセスの制御が難しい
  • セキュリティやリソース面の制約がある
  • 公式にも非推奨、サポート対象外

PaaSで動かすなら、無理にGUIを再現しようとせず、headlessで済ませましょう。

じゃあIaaSなら動くの?

はい、動きます。

PaaSでは headless=False は基本使えませんが、IaaS(例:AWS EC2, GCP Compute Engine)なら可能です。

環境 headless=False 対応 理由
ローカルPC 物理画面あり
VPS(xvfb導入済み) 仮想ディスプレイを自分で構築できる
PaaS(Render, Herokuなど) Xサーバ非搭載・構築不可
IaaS(EC2, GCEなど) OSレベルから自由に構築可能

まとめ:描画できるかどうかが全て

目的 最適な環境
ローカルで挙動を見ながら開発したい ✅ PCで headless=False
自動処理をクラウドで動かしたい ✅ PaaS × headless=True
録画やGUI付きの重処理を本番で動かしたい ✅ IaaS(EC2など)+ Xvfb構成

まとめ

  • PaaSにはディスプレイ(Xサーバ)がないため、headless=Falseは動かない
  • Dockerを使っていても、描画先はPaaS側に依存している
  • 本番でGUIが不要なら、必ず headless=True にしよう
GitHubで編集を提案

Discussion