この記事では任意のフォントをAWS Lambda + @serverless-chrome/lambda + Puppeteer 環境で使えるようにする方法を紹介します。
(**追記:**Puppeteerと書きましたがPuppeteerじゃなくてもAWS Lambda + @serverless-chrome/lambda を使っている環境であれば有効です。)
この記事を作成するに至った経緯
AWS Lambda上でserveless-chromeを動かすときにデフォルトだと日本語フォントが入っていないため日本語が表示されず四角いマーク(通称:豆腐)に化けてしまいます。
こちらの記事で日本語対応させる方法が紹介されていますが、より簡単な方法で好きなフォントを使うことができたのでその方法を記事に残します。
手順
- Lambdaにデプロイするパッケージのルートに
.fonts
というディレクトリを作成し、使いたいfontファイルを入れます。 - Lambdaの環境変数HOME(デフォルトだと
undefined
)に/var/task
と設定します。
これだけです!
自分でfontconfig
を作ったりfc-cache
コマンドでごにょごにょしたり~という必要はありません。
ただディレクトリを作って、環境変数を指定するだけです!
(ちなみにLambda関数ではtmp
ディレクトリ以外はアクセス権が制限されているので、Lambda関数実行時に普通にfc-cache
コマンドを使おうとしても失敗してうまくいかないはずです。)
より詳しい手順
例として、Noto Sans CJK JP
とNoto Serif CJK JP
を使えるようにする方法を順番に記載します。
手順1: Lambdaにデプロイするプロジェクトのルートに.fonts
というディレクトリを作ります。
mkdir .fonts
手順2: .fonts
の中にNotoSansCJKjp-Regular.otf
とNotoSerifCJKjp-Regular.otf
を入れます。
.fotns/
├ NotoSansCJKjp-Regular.otf
└ NotoSerifCJKjp-Regular.otf
手順3: Lambdaにデプロイするものをまとめてzipパッケージを作ります。
例)
rm パッケージ名.zip
zip -r パッケージ名.zip index.js node_modules/ .fonts/
- 注意点として、zipファイルを作るときに以前作った同名zipファイルがすでに存在する場合、そのzipファイルを消してから作らないとどんどんzipのサイズが肥大化していくので必ず同名のzipファイルを消すように気を付ける必要があります。
手順4: S3経由でLambda関数にデプロイします。
serverless-chromeとフォントファイルでパッケージのサイズはかなりギリギリになっていると思います。なのでほぼS3経由でのデプロイが必須になるでしょう。
手順5: Lambdaの環境変数HOME
に/var/task
と指定します。
コンソール画面またはCLIなどから環境変数を指定してもよいですし、ハンドラー関数のコードの中で指定してもよいです。
コードから指定する例)
process.env['HOME'] = '/var/task';
ちなみにこの/var/task
というのはパッケージがデプロイされるディレクトリです。(LAMBDA_TASK_ROOTというデフォルトで用意されている環境変数からも取得できます。)
デプロイ後は下図のようなディレクトリ構成になるイメージです。
/var/task
├ .fonts/
├ index.js
└ node_modules/
手順6: これで完了です!
あとはLambda関数上で煮るなり焼くなり好きなようにserverless-chromeを使いましょう!
読み込ませるページのCSSでフォントを指定してやればちゃんと反映されます!
またCSSで指定しなかったとしてもフォールバックとして日本語にnotoフォントが適用されるので豆腐化することもなくなります!
ポイントまとめ
- Lambda関数にパッケージをデプロイしたときに、
/var/task
直下に.fonts
ディレクトリがくるようになっていること。 - そしてその
var/task
が環境変数HOME
で指定されていること。
上記の二点が重要なポイントです。
もしうまくいかない場合は上の二つを見直すか、フォントファイルのアクセス権などをチェックするとよいかもしれません。