Angular v17で簡単になったSSRを、Dockerでビルドしてデプロイできるようにする。やることは単純で、特に落とし穴になるようなことはない。
まずは ng new
コマンドでアプリケーションを作成する。 --ssr
フラグをつけなくても、プロンプトでSSRを有効にするかどうかは尋ねられるので、そこでYesと答えてもよい。
$ ng new ng17-ssr-docker --ssr
正しくアプリケーションを作成できていれば、この時点で ng build
を実行すればSSR用のサーバーを立てるのに必要なファイルと設定はすべて済んでいる。ビルドを実行して出力された dist/server
ディレクトリが存在すれば問題ない。
$ npm run build
$ tree dist/
dist/
└── ng17-ssr-docker
├── 3rdpartylicenses.txt
├── browser
│ ├── favicon.ico
│ ├── index.html
│ ├── main-XALV5XXG.js
│ ├── polyfills-LZBJRJJE.js
│ └── styles-5INURTSO.css
├── prerendered-routes.json
└── server
├── chunk-53JWIC36.mjs
├── chunk-KRLCULJA.mjs
├── chunk-VP7Q5FIC.mjs
├── chunk-YGUSPAT3.mjs
├── index.server.html
├── main.server.mjs
├── polyfills.server.mjs
├── render-utils.server.mjs
└── server.mjs
この中の server/server.mjs
をNode.jsで実行するとサーバーが起動する。試しに node
コマンドを実行して確認しよう。デフォルトではlocalhostの4000番ポートでサーバーが起動するので、ブラウザで開いてSSRされたHTMLが返却されていることがわかるはずだ。
$ node dist/ng17-ssr-docker/server/server.mjs
Node Express server listening on http://localhost:4000
あとはこれを任意のNode.js環境にデプロイすればいい。Dockerを使う場合、最小構成は次のようになる。やることは、ビルド後の dist
ディレクトリの中身をコピーし、 server/server.mjs
を実行するだけだ。サーバーサイドのスクリプトもAngular CLIによってバンドルされているため、実行環境で npm install
をする必要はない。
FROM node:20-buster-slim
WORKDIR /app
COPY dist/ng17-ssr-docker/ /app
CMD node server/server.mjs
ビルドもDockerに任せたい場合はマルチステージビルドを使ってもよいが、個人的にはおすすめしない。昨今いろいろなCLIツールは永続キャッシュによる高速化が図られていることが多く、Dockerでビルドさせるとその恩恵が得にくいケースが多い。工夫すればできないことはないだろうが、物事をシンプルに保つうえであらかじめ ng build
しておいた結果をコピーするだけに留めておくほうがよかろうと思う。
あとは適当にDockerイメージをビルドしてデプロイすれば終わりだ。いやあ簡単になったものだ。