Skip to main content

ビルドとデプロイ

Node サーバー

Edit this page on GitHub

スタンドアロンな Node サーバーを作る場合は、adapter-node を使います。

使い方

npm i -D @sveltejs/adapter-node を実行してインストールし、svelte.config.js にこの adapter を追加します:

svelte.config.js
ts
import adapter from '@sveltejs/adapter-node';
Cannot find module '@sveltejs/adapter-node' or its corresponding type declarations.2307Cannot find module '@sveltejs/adapter-node' or its corresponding type declarations.
export default {
kit: {
adapter: adapter()
}
};

デプロイ(Deploying)

まず、npm run build でアプリをビルドします。これによって adapter のオプションで指定した出力ディレクトリ (デフォルトは build) に本番環境用のサーバーが作成されます。

アプリケーションを実行するには、出力ディレクトリ、プロジェクトの package.jsonnode_modules の本番向けの依存関係(production dependencies)が必要です。本番向けの依存関係は、package.jsonpackage-lock.json をコピーしてから npm ci --omit dev を実行すると生成することができます (あなたのアプリが何の依存関係も持たない場合はこのステップをスキップできます)。そして、このコマンドでアプリを起動することができます:

node build

Rollup を使うと開発用の依存関係(Development dependencies)もアプリにバンドルされます。パッケージをバンドルするか外部化するかコントロールするには、そのパッケージを package.jsondevDependenciesdependencies にそれぞれ配置します。

環境変数

devpreview のときは、SvelteKit は .env ファイル (または .env.local.env.[mode]Vite によって決定されているもの) から環境変数を読み取ります。

プロダクションでは、.env ファイルは自動的に読み取れらません。そうするには、プロジェクトに dotenv をインストールします…

npm install dotenv

…そしてビルドされたアプリを実行する前にそれを呼び出します:

node build
node -r dotenv/config build

PORT、HOST、SOCKET_PATH

デフォルトでは、サーバーは 0.0.0.0、port 3000 でコネクションを受け付けます。これは環境変数の PORTHOST を使ってカスタマイズすることができます。

HOST=127.0.0.1 PORT=4000 node build

その他の方法としては、指定したソケットパスでコネクションを受け付けるようサーバーを設定することができます。環境変数の SOCKET_PATH を使用して設定する場合、環境変数の HOSTPORT は無視されます。

SOCKET_PATH=/tmp/socket node build

ORIGIN、PROTOCOL_HEADER、HOST_HEADER

HTTP は SvelteKit に現在リクエストされている URL を知るための信頼できる方法を提供しません。アプリがホストされている場所を Sveltekit に伝える最も簡単な方法は、環境変数 ORIGIN を設定することです:

ORIGIN=https://my.site node build

# or e.g. for local previewing and testing
ORIGIN=http://localhost:3000 node build

これにより、パス名 /stuff に対するリクエストは正しく https://my.site/stuff に解決されます。別の方法として、リクエストプロトコルとホストを SvelteKit に伝えるヘッダーを指定し、そこから origin URL を組み立てることもできます:

PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build

x-forwarded-protox-forwarded-host は事実上の標準となっているヘッダーで、リバースプロキシー (ロードバランサーや CDN などを考えてみてください) を使用している場合に、オリジナルのプロトコルとホストを転送します。これらの変数は、あなたのサーバーが信頼できるリバースプロキシーの後ろにある場合にのみ設定すべきです。そうしないと、クライアントがこれらのヘッダーを偽装することが可能になってしまいます。

adapter-node があなたのデプロイの URL を正しく判断することができない場合、form actions を使用するとこのエラーが発生することがあります:

クロスサイトの POST フォーム送信は禁止されています

ADDRESS_HEADER と XFF_DEPTH

hooks とエンドポイントに渡される RequestEvent オブジェクトにはクライアントの IP アドレスを返す event.getClientAddress() 関数が含まれています。デフォルトでは、これは接続中の remoteAddress です。もしサーバーが1つ以上のプロキシー (例えばロードバランサー) の後ろにある場合、この値はクライアントの IP アドレスではなく、最も内側にあるプロキシーの IP アドレスを含むことになるため、アドレスを読み取るために ADDRESS_HEADER を指定する必要があります:

ADDRESS_HEADER=True-Client-IP node build

ヘッダーは簡単に偽装されます。PROTOCOL_HEADERHOST_HEADER と同様、これらを設定する前に自分が何をしているのか知るべきです。

ADDRESS_HEADERX-Forwarded-For の場合、ヘッダーの値にはカンマで区切られた IP アドレスのリストが含まれます。環境変数 XFF_DEPTH には、あなたのサーバーの前に信頼できるプロキシーがいくつあるか指定する必要があります。例えば、3つの信頼できるプロキシーがある場合、プロキシー3はオリジナルのコネクションと最初の2つのプロキシーのアドレスを転送します:

<client address>, <proxy 1 address>, <proxy 2 address>

一番左のアドレスを読め、というガイドもありますが、これだとスプーフィング(なりすまし)に対し脆弱なままです:

<spoofed address>, <client address>, <proxy 1 address>, <proxy 2 address>

代わりに、信頼できるプロキシーの数を考慮してから読み込みます。この場合、XFF_DEPTH=3 を使用します。

もし、一番左のアドレスを読む必要がある場合 (そしてスプーフィングを気にしない場合) — 例えば、位置情報サービスを提供する場合、つまり IP アドレスが信頼できることよりもリアルであることが重要な場合、アプリの中で x-forwarded-for ヘッダーを検査することでそれが可能です。

BODY_SIZE_LIMIT

ストリーミング中も含め、受け付けるリクエストボディの最大サイズを byte で指定します。デフォルトは 512kb です。もっと高度な設定が必要な場合は、このオプションの値を 0 にして無効化し、handle にカスタムのチェックを実装することができます。

Options

この adapter は様々なオプションで設定を行うことができます:

svelte.config.js
ts
import adapter from '@sveltejs/adapter-node';
Cannot find module '@sveltejs/adapter-node' or its corresponding type declarations.2307Cannot find module '@sveltejs/adapter-node' or its corresponding type declarations.
export default {
kit: {
adapter: adapter({
// default options are shown
out: 'build',
precompress: false,
envPrefix: ''
})
}
};

out

サーバーをビルドするディレクトリです。デフォルトは build です。つまり、node build を指定すると、サーバが作成されローカルで起動します。

precompress

アセットやプリレンダリングされたページを gzip や brotli を使って事前圧縮(precompress)するのを有効にします。デフォルトは false です。

envPrefix

デプロイの設定に使用される環境変数の名前を変更する必要がある場合 (例えば、あなたのコントロール下にない環境変数との競合を解消するため)、接頭辞(prefix)を指定することができます:

ts
envPrefix: 'MY_CUSTOM_';
MY_CUSTOM_HOST=127.0.0.1 \
MY_CUSTOM_PORT=4000 \
MY_CUSTOM_ORIGIN=https://my.site \
node build

カスタムサーバー

この adapter は、ビルドのディレクトリに2つのファイルを作成します — index.jshandler.js です。デフォルトのビルドのディレクトリを使用している場合、node build などで index.js を実行すると、設定された port でサーバーが起動されます。

別の方法として、ExpressConnectPolka (またはビルトインの http.createServer) を使用するためのハンドラーをエクスポートする handler.js ファイルをインポートし、独自のサーバーをセットアップすることもできます。

my-server.js
ts
import { handler } from './build/handler.js';
Cannot find module './build/handler.js' or its corresponding type declarations.2307Cannot find module './build/handler.js' or its corresponding type declarations.
import express from 'express';
Cannot find module 'express' or its corresponding type declarations.2307Cannot find module 'express' or its corresponding type declarations.
const app = express();
// add a route that lives separately from the SvelteKit app
app.get('/healthcheck', (req, res) => {
Parameter 'req' implicitly has an 'any' type.
Parameter 'res' implicitly has an 'any' type.
7006
7006
Parameter 'req' implicitly has an 'any' type.
Parameter 'res' implicitly has an 'any' type.
res.end('ok');
});
// let SvelteKit handle everything else, including serving prerendered pages and static assets
app.use(handler);
app.listen(3000, () => {
console.log('listening on port 3000');
});
my-server.ts
ts
import { handler } from './build/handler.js';
Cannot find module './build/handler.js' or its corresponding type declarations.2307Cannot find module './build/handler.js' or its corresponding type declarations.
import express from 'express';
Cannot find module 'express' or its corresponding type declarations.2307Cannot find module 'express' or its corresponding type declarations.
const app = express();
// add a route that lives separately from the SvelteKit app
app.get('/healthcheck', (req, res) => {
Parameter 'req' implicitly has an 'any' type.
Parameter 'res' implicitly has an 'any' type.
7006
7006
Parameter 'req' implicitly has an 'any' type.
Parameter 'res' implicitly has an 'any' type.
res.end('ok');
});
// let SvelteKit handle everything else, including serving prerendered pages and static assets
app.use(handler);
app.listen(3000, () => {
console.log('listening on port 3000');
});

トラブルシューティング

サーバーが終了する前にクリーンアップするための hook はありますか?

SvelteKit にはこれに対応するためのビルトインで組み込まれているものはありません。なぜなら、このようなクリーンアップの hook はあなたの実行環境に大きく依存しているからです。Node の場合は、ビルトインの process.on(..) を使用して、サーバーが終了する前に実行されるコールバックを実装することができます:

ts
function shutdownGracefully() {
// anything you need to clean up manually goes in here
db.shutdown();
Cannot find name 'db'.2304Cannot find name 'db'.
}
process.on('SIGINT', shutdownGracefully);
process.on('SIGTERM', shutdownGracefully);