【SvelteKit 入門】アダプター設定・ホスティング・コンテナ運用
なぜ序盤にデプロイの解説かというと
新規プロジェクトを作成し外部アクセス可能な状態に持っていく
という一連の作業を先にやってしまい、自分のアプリケーションを稼働させる感覚を掴んだ方が全体の理解が深まるというのが私の持論だからです。
シリーズまとめ(随時追加・更新)
【SvelteKit 入門】はじめに | |
【SvelteKit 入門】作業の前に | |
【SvelteKit 入門】アダプター設定・ホスティング・コンテナ運用 | now reading |
【SvelteKit 入門】ルーティング | |
【SvelteKit 入門】データハンドリング(+page.js) | |
SvelteKit + microCMS でブログ構築 |
この記事では実際にファイルを編集していくので、適当なプロジェクトを作って下さい。
## テンプレートはデモアプリ
? Which Svelte app template?
> SvelteKit demo app
Skeleton project
Library skeleton project
## 続く選択項目
何でもかまいませんが、全て `no` にしておくと以降の参考画像とズレがなくなると思います。
1. アダプター設定
公式ドキュメントの該当部分はこちら日本語ドキュメントならこっち
デプロイ用の設定「アダプター」
- SvelteKit は適用されているアダプターに従いビルドを行う
- デフォルトでは
adapter-auto
がセットされている - デプロイ先に合わせて各種
adapter-○○
が用意されている - 各アダプターは npm パッケージとしてインストール
- 既存パッケージを使わず、自分でカスタマイズする事も可能
ジョイントパーツを付け換えるイメージ。
最初に付いてるパーツadapter-auto
からの換装を解説します。
アダプターの選択肢
公式のリポジトリに、用意されているアダプターが見やすく一覧になってる部分があります。
GitHub 公式リポジトリ README.md
有名どころのホスティングサービス向けは用意されていますね。
※サービス名ではないアダプターについては後ほど補足
ファイル編集
編集するファイルは2つあります。
① package.json
package.json
の devDependencies
内
ここに使用するadapter-○○
がないといけません。adapter-auto
は既に入ってますね。
このadapter-auto
を書き換える or 下の行に追記 どちらかをしてください。
Vercel用アダプターに書き換えた例
ファイルを編集して保存したら、再度
npm install
を実行して下さい。
② svelte.config.js
ここもデフォルトはadapter-auto
になっていると思うので、使用するものに合わせて書き換えます。ここは追記ではなく書き換えです。(残すならコメントアウト)
ちなみに下の adapter: adapter()
部分はこのままでokです。
詳細な設定をする場合はオプションをJSON形式で入れることになります。
アダプター設定まとめ
以上がアダプター設定の流れです。要するに
- 使う
adapter-○○
のパッケージがインストール済で -
svelte.config.js
でそれをimport
&config.kit.adapter
に設定
これがクリアされていればジョイントパーツの付け換えは完了です。
ホスティングサービスに慣れてる方は、もうデプロイしてみて下さい。
adapter-auto
はダメなの?
【補足】実はたいていadapter-auto
のままでいけます
しかしデプロイ先でエラーが出た時の原因切り分けや、アプリケーションの構成に合わせてアダプターを変更する必要が出てきた場合等、理解しておけば何かと便利なので早い段階で触っておいて欲しかった という私個人の押し付けが発動したせいです。すみません。
ホスティングサービス向け 以外の アダプターについて少し解説
atapter-auto | 自動判別。大手ホスティングサービスなら無設定でいける可能性が高い |
adapter-static | 静的ファイル群で出力。nginx やGitHub Pages といった(非Nodeの)WEBサーバーでも運用可能サーバー側でjsが動くようなレンダリングをしないという事であって、ブラウザ駆動のjsは動く。SPAも可。 |
adapter-node | Node環境向け。 コンテナでNode.jsメージに入れて稼働、PM2でクラスター化して稼働、などなど |
自分でカスタマイズ |
adapter をimportするのではなく、JSONで設定を記述 |
アダプターの使い分けにおいては 実装するレンダリングの種類 も少し関わってきますので、SvelteKit の理解が深まったら色々検証してみてください。
2. ホスティングサービスにデプロイ
SvelteKit を動かす環境は色々と考えられますが、まずはシンプルなホスティングサービスを利用するのが良いかと思います。GitHub と連携さえすれば、push するだけでビルド&デプロイを回してくれる環境は非常に快適です。
Vercel
, Cloudflare Pages
, Netlify
の3サービスで設定時の要所のみまとめました。
準備
- プロジェクトをGitHub管理
- Vercel / Cloudflare / Netlify いずれかのアカウント
- ↑ サービスに向けてGitHubの権限許可
この部分は解説しませんので、自力解決でお願いします。
では各サービスでの作業を簡単に。
Vercel
FRAMEWORK PRESET
で SvelteKit
を選択する だけ。
(しかも多分最初から自動で選択されてる)
Cloudflare Pages
フレームワーク プリセット
で SvelteKit
を選択。
続いて 環境変数(アドバンスド)
を展開します。
+変数を追加する
をクリックし、NODE_VERSION
= 16
に設定
ちなみに17でもいけます。18は未対応(2022年10月時点)
Netlify
プリセットの選択すら無い。値はデフォルトから変更不要。
Base direcroty
はブランクのままでok。
Build command
は自動で判別したのだろうか
比較
サービスごとでビルド環境等に若干違いはありますが、設定し直さなくてもadapter-auto
が柔軟に調整してくれているようです。当然専用のアダプターに変えても正常に稼働します。
Vercel | Cloudflare Pages | Netlify | |
---|---|---|---|
出力ディレクトリ (初期値) |
/public | /.svelte-kit/cloudflare | /build |
Nodeバージョン (初期値) |
16 ※設定で12,14,16が選択可 |
12 ※環境変数で17まで指定可 |
16 ※環境変数で18まで指定可 |
ビルド速度 | ◎ | ▲ → ◎ ( 初回 → 2回目〜) |
○ |
アクセス速度 | ◎ | ◎ | ○ |
※Vercel
とNetlify
はデフォルトのNodeバージョンが16
以上なのでそのままいけますが、Cloudflare Pages
はデフォルトが12
なので、環境変数で16
以上の値にすることで対応できます。
3. コンテナ運用
docker-compose
は無し、Dockerfile
からのイメージビルド→立ち上げ の流れで行きます。
準備
コンテナ稼働で必要なSvelteKit
側の設定は
アダプターを adapter-node
に変更する
これだけです。
起動条件の確認
各段階で必要なファイル・ディレクトリは以下のようになってます
実行コマンド | 必要 | 出力される(影響を受ける) |
---|---|---|
npm install | package.json | .svelte-kit/ node_modules/ package-lock.json |
npm ci | package.json package-lock.json |
.svelte-kit/ node_modules/ |
npm run build | node_modules/ src/ static/ package.json svelte.config.js vite.config.js |
.svelte-kit/ build/ |
SvelteKit 起動 | build/ node_modules/ package.json |
---- |
これらを踏まえ、マルチステージビルドにすることでイメージサイズを何割か小さくできます。
イメージ作成
#### 前半はビルド用ステージ
FROM node:18-slim AS STAGE_NAME_OF_BUILD
WORKDIR /DIR_FOR_BUILD
COPY . .
RUN npm install && npm run build
#### 後半は起動用ステージ
FROM node:18-slim
WORKDIR /DIR_FOR_RUN
COPY /DIR_FOR_BUILD/package.json .
COPY /DIR_FOR_BUILD/build ./build
RUN npm install --omit=dev
# ↑ --produnction よりこちらが推奨になった模様
ENV PORT PORT_NUMBER
# ↑ ポートを変更したい場合は指定。3000のままで良いなら不要
CMD ["node","build"]
大文字スネークケースの部分は好きなものに変更してください。
全体
Docker
ファイルが複雑になりすぎない、程々のパターンにしました。これでも十分イメージサイズは削減できます。
イメージは私がslim
派なだけで、alpine
でも可。Googleのdistroless
を使う場合はステージングがもっと複雑になるので今回は見送りました。
マルチステージの場合、最後のステージに持ってくるファイルがイメージサイズに直結します。.dockerignore
でビルドステージへのコピーを減らしてもイメージサイズには影響ありません。
パッケージのインストール
npm install
とnpm ci
の使い分けについては長くなるのでここでは割愛します。
依存関係がシビアな場合はnpm ci
に変えてください。
NODE_ENV
ENV NODE_ENV production
等の記述は、プロジェクト内で環境変数を扱う段階になったら追記してください。少なくとも「環境変数?なにそれ」という段階では記述無しで大丈夫です。
EXPOSE
EXPOSE
でポート番号を入れている資料もありますが不要です。
(起動時の-p 外部ポート:内部ポート
オプションは必要です)
コンテナ起動
Cloud Run
等のCaaS利用だったり、昨今のコンテナ環境は様々だと思いますが…
マシン上で直接podman
を使う というなかなかニッチなケースの例を載せておきます。
# SvelteKit のディレクトリに上記 Dockerfile を配置
# そのディレクトリで以下のコマンド
# --squash-all はお好みで
podman build -t イメージ名:タグ --squash-all .
# コンテナ起動
podman run -d --init -p 受け付けたいポート:3000 イメージ名
ちなみにpodman
の場合、Dockerfile
ではなくContainerfile
というファイル名でもいけます。
運用時の構成
接続のSSL化やテスト環境との振り分けなどを考えると、リバースプロキシを挟むのが現実的です。
外からのhttps接続をnginx
で受け、内部はhttp接続でSvelteKit
のコンテナに回す という構成が最もシンプルかと思います。私はpodman
ユーザーですが、nginx
-SvelteKit
の通信は同一podで接続するパターン、ネットワークを作成しIPを振って接続するパターン、どちらも問題ありませんでした。
ここで格好良くアーキテクチャ図とともにサンプルコードを記載できれば良いのですが、オレオレ設定も非常に多くお見せするには散らかり過ぎているので見送らせていただきます。
【補足】"デプロイ"という表現
この記事ではデプロイを結構広い意味で使いましたがご了承ください。
例えば Vercel を利用する場合、
- GitHub と連携 & 設定
push
- Vercel が自動でビルド & デプロイ
というフローが流れていきます。
つまり厳密に言えば、デプロイは Vercel 内部で行われている工程の一つなわけですが・・・
この 外部アクセスが可能な状態まで持っていくこと をデプロイと呼びました。
まとめ
デモアプリはサーバー上で動いてますか?
これで今後 SvelteKit で何か作ってみた際、ローカルに限らず動作検証ができますね。
本記事の内容(特にコンテナのDockerfile
まわり)について、何かお気づきの点があれば気軽にコメントください。
Discussion