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 で動かす必要がある場合に限ります。