2026年7月27日

2026年7月27日

VPSにヘッドレスChromeをインストールする方法|Ubuntuでスクリーンショット・PDF・Puppeteer

Google Chrome は、画面を表示しない「ヘッドレスモード」で動かせます。VPS のようにデスクトップ環境の無いサーバーでも、Web ページのスクリーンショットや PDF の作成、JavaScript で描画されるページの HTML の取得、Puppeteer を使った自動操作などができます。

この記事では、Ubuntu 24.04 LTS の VPS(x86_64 / amd64)を例に、Google Chrome の安定版を入れてコマンドと Puppeteer から使うまでを説明します。バージョンなどの情報は 2026年11月時点のものです。

前提

  • CPU は x86_64(amd64)。 Google が配布している Linux 版 Chrome の .deb は amd64 向けです。ARM の VPS ではこの手順は使えないため、配布物の有無を公式サイトで確認してください。
  • sudo が使える一般ユーザーで作業する。 Chrome は root で動かすとサンドボックス(ページを隔離する仕組み)が使えず、そのままでは起動しません(後述)。
  • メモリに余裕を持たせる。 Chrome はページを開くたびにメモリを使います。メモリの少ない VPS では、同時に開くページ数を絞るか、スワップを用意します。

手順1: Google Chrome をインストールする

Google が配布している .deb パッケージをダウンロードし、apt で入れます。apt install にファイルのパスを渡すと、Chrome が必要とするライブラリもまとめて入ります。

cd /tmp
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt update
sudo apt install -y ./google-chrome-stable_current_amd64.deb

# バージョンを確認
google-chrome --version

このパッケージを入れると、Google のリポジトリが apt に登録されます。以後は sudo apt update && sudo apt upgrade で Chrome も更新されます。Chrome は更新が頻繁なブラウザーなので、サーバーでも定期的に更新してください。

鍵がうまく登録されず NO_PUBKEY のエラーが出る場合は、Google の案内(Linux Software Repositories のページ)にある方法で署名鍵を登録します。

wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo tee /etc/apt/trusted.gpg.d/google.asc >/dev/null
sudo apt update

手順2: 日本語フォントを入れる

サーバーに日本語フォントが無いと、スクリーンショットや PDF の日本語が四角(いわゆる豆腐)になります。Noto の CJK フォントを入れます。絵文字も表示したい場合は絵文字フォントも入れます。

sudo apt install -y fonts-noto-cjk fonts-noto-color-emoji

# フォントが認識されているか確認
fc-list :lang=ja | head

手順3: コマンドでスクリーンショットと PDF を作る

--headless を付けて起動すると、画面を出さずに動きます。ファイルの保存先はフラグに = で指定します。

# スクリーンショット(幅1280×高さ800で描画)
google-chrome --headless --window-size=1280,800 \
  --screenshot=/tmp/example.png https://example.com/

# PDF
google-chrome --headless --print-to-pdf=/tmp/example.pdf https://example.com/

# JavaScript 実行後の HTML を標準出力に出す
google-chrome --headless --dump-dom https://example.com/ > /tmp/example.html

ls -lh /tmp/example.*

Chrome 132 以降、以前のヘッドレスモード(いわゆる old headless)は Chrome 本体から外され、chrome-headless-shell という別のプログラムとして配布されています。現在の Chrome では --headless だけで新しいヘッドレスモードになるため、古い記事にある --headless=new を付ける必要はありません。

手順4: Puppeteer から使う

ページを操作したり、読み込みを待ってから撮影したりする場合は、Node.js のライブラリ Puppeteer を使います。Puppeteer には次の2つのパッケージがあります。

パッケージ 内容
puppeteer インストール時に、動作確認済みの Chrome(Chrome for Testing)をダウンロードする
puppeteer-core ブラウザーをダウンロードしない。使う Chrome の場所を自分で指定する

手順1で Chrome を入れたので、ここでは puppeteer-core を使います。2026年11月時点の puppeteer-core(25系)は Node.js 22.12 以上が必要です。Node.js が入っていない場合は、NodeSource のリポジトリから LTS 版(ここでは 24 系)を入れます。

curl -fsSL https://deb.nodesource.com/setup_24.x -o /tmp/nodesource_setup.sh
sudo bash /tmp/nodesource_setup.sh
sudo apt install -y nodejs
node --version

作業用のフォルダーを作り、puppeteer-core を入れます。

mkdir -p ~/capture && cd ~/capture
npm init -y
npm install puppeteer-core

capture.mjs として次の内容を保存します。

import puppeteer from 'puppeteer-core';

const url = process.argv[2] ?? 'https://example.com/';

const browser = await puppeteer.launch({
  executablePath: '/usr/bin/google-chrome', // 手順1で入れた Chrome
  headless: true,                            // 既定値。新しいヘッドレスモード
});

try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });
  await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await page.pdf({ path: 'page.pdf', format: 'A4', printBackground: true });
  console.log('saved: shot.png, page.pdf');
} finally {
  await browser.close();
}

実行します。

node capture.mjs https://example.com/
ls -lh shot.png page.pdf

Puppeteer の headless の指定は、true(既定値、新しいヘッドレスモード)、'shell'(chrome-headless-shell を使う)、false(画面を表示する)の3つです。古い記事にある headless: 'new' は現在の説明には出てこないため、true を使います。

起動しないときの確認点

「Running as root without --no-sandbox is not supported」と出る

root で Chrome を起動したときのエラーです。一般ユーザーで実行し直すのが基本です。Web アプリから呼び出す場合も、専用のユーザーを作ってそのユーザーで動かします。

sudo useradd -m -s /bin/bash chrome-runner
sudo -u chrome-runner google-chrome --headless --screenshot=/tmp/test.png https://example.com/

どうしても root で動かす場合だけ --no-sandbox を付けます。Puppeteer の公式の説明でも、サンドボックス無しでの実行は強く非推奨とされています。サンドボックスを外した状態で、内容を信用できないページを開かないでください。

共有ライブラリが見つからない

.deb を apt で入れていれば通常は依存ライブラリも入ります。それでも起動しない場合は、足りないライブラリを調べます。

ldd /opt/google/chrome/chrome | grep "not found"

表示されたライブラリを含むパッケージを apt install で入れます。

Docker コンテナーの中でクラッシュする

Docker のコンテナーでは、共有メモリ(/dev/shm)が初期設定で 64MB と小さく、大きなページでタブがクラッシュすることがあります。コンテナーを起動するときに --shm-size=1g のように広げるか、Chrome の起動オプションに --disable-dev-shm-usage を付けて、共有メモリの代わりに /tmp を使わせます。

const browser = await puppeteer.launch({
  executablePath: '/usr/bin/google-chrome',
  args: ['--disable-dev-shm-usage'],
});

コンテナーではない通常の VPS では、/dev/shm は物理メモリに応じた大きさになっているため、このオプションは通常不要です。df -h /dev/shm で大きさを確認できます。

日本語が四角になる

手順2のフォントが入っているか、fc-list :lang=ja で確認します。フォントを入れた後は、動いている Chrome を終了してから撮り直します。

運用での注意

  • Chrome を更新し続ける。 ヘッドレスでも中身は通常の Chrome と同じで、脆弱性の修正も同じように出ます。apt upgrade を定期的に実行します。
  • 終了処理を入れる。 browser.close() を呼ばずにスクリプトが終わると、Chrome のプロセスが残ってメモリを使い続けます。上の例のように try と finally で閉じます。残ってしまったプロセスは pgrep -a chrome で確認できます。
  • アクセス先のサイトの規約を守る。 スクレイピングに使う場合は、相手のサイトの利用規約や robots.txt を確認し、短い間隔で大量にアクセスしないようにします。

まとめ

  • Ubuntu の VPS では、Google の .deb を sudo apt install ./ファイル名 で入れると依存ライブラリとリポジトリも設定されます。
  • 日本語を表示するには fonts-noto-cjk を入れます。
  • google-chrome --headless に --screenshot・--print-to-pdf・--dump-dom を付けると、コマンドだけで撮影や PDF 作成ができます。
  • Puppeteer から使う場合は puppeteer-core を入れ、executablePath に /usr/bin/google-chrome を指定します。headless は true を使います。
  • Chrome は一般ユーザーで動かし、--no-sandbox は root で動かす必要がある場合に限ります。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲