Node.js アプリをデプロイする(Express)
Lizard (lizard.build) で Node.js アプリをホストするには、package.json を含むフォルダーをデプロイします。lizardpack は lock ファイルからパッケージマネージャーを選び、依存関係をインストールし、build スクリプトがあれば実行して、start スクリプトでアプリをポート 3000 で起動します。.nvmrc や engines.node で別のメジャーバージョンを指定しない限り、Node.js 22 を使います。Lizard はポートを PORT で渡すので、そのポートで待ち受けてください。
テスト状況: 以下の Express サンプルは Express 5.3.0 を使ってローカルで動作し、データベースのルートは pg 8.23.1 を使って PostgreSQL 14 に対して動作しました。ビルドプランは、Lizard が使う lizardpack で確認しました。このガイドのデプロイ手順は、まだ最初から最後まで試していません。
始める前に
- lock ファイルの作成とローカルでのテストに使う、手元のコンピューターの Node.js と npm。
lizard loginでサインイン済みで、Pro または 7 日間の Pro トライアル(カードが必要)を利用している Lizard CLI。料金を参照してください。
Next.js、Nuxt、Astro、SvelteKit、Vite のアプリには専用のガイドがあります。フレームワークガイドを参照してください。
最小構成の Express アプリ
package.json:
{
"name": "express-app",
"private": true,
"type": "module",
"scripts": {
"start": "node server.js"
},
"engines": {
"node": "22.x"
},
"dependencies": {
"express": "^5.1.0"
}
}server.js:
import express from "express";
const app = express();
const port = Number(process.env.PORT) || 3000;
app.get("/", (req, res) => {
res.send("Hello from Express on Lizard");
});
app.get("/healthz", (req, res) => {
res.json({ status: "ok" });
});
app.listen(port, "0.0.0.0", () => {
console.log(`listening on ${port}`);
});npm install を実行して package-lock.json を作成し、両方のファイルをコミットして、node_modules と .env を .gitignore に追加します。ローカルで確認します:
npm start
curl http://localhost:3000/healthzlizardpack が Node.js アプリに対して行うこと
| ステップ | 内容 |
|---|---|
| パッケージマネージャー | bun.lock または bun.lockb: Bun。pnpm-lock.yaml: pnpm。yarn.lock: Yarn。package-lock.json: npm ci。lock ファイルなし: npm install。 |
| Node.js のバージョン | .nvmrc、次に .node-version、次に .tool-versions、次に engines.node。使われるのはメジャーバージョンだけで、node:<major>-slim 上でビルドされます。デフォルトは 22。 |
| ビルド | package.json に build スクリプトがあれば、devDependencies を含む別のステージで実行 |
| 起動 | start スクリプト。なければ node <main>。それもなければ server.js、index.js、app.js、main.js、dist/index.js のうち最初に見つかったもの |
| ランタイム | NODE_ENV=production、ポート 3000 |
build スクリプトがない場合、イメージはパッケージをインストールする前に NODE_ENV=production を設定するため、devDependencies はインストールされません。そのため、devDependencies にある nodemon、tsx、ts-node を呼び出す start スクリプトは失敗します。TypeScript では、build でコンパイルし、その出力を起動してください:
{
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
}バージョンファイルと注意点は ランタイムバージョン で説明しています。サービスのビルドコマンドと起動コマンドは空のままにしてください。どちらかが設定されていると、Lizard は node:22-alpine をベースに独自の Dockerfile を生成し、バージョンファイルを無視します。ビルドパイプラインを参照してください。
デプロイ
アプリのルートから実行します:
lizard init --name node-app
lizard add --service web
lizard up --service web --port 3000lizard up はフォルダーをアップロードし、Lizard 上でビルドして URL を表示します。git リポジトリ内では .gitignore に書かれたものをスキップします。git の外では node_modules はスキップしますが、.env ファイルはアップロードします。ローカルコードからデプロイするを参照してください。
git push to deploy を使う場合は、リポジトリを GitHub に push し、lizard add -r your-org/your-app -n web で接続します。GitHub からデプロイするを参照してください。
変数を設定する
lizard secrets set SESSION_SECRET="$(openssl rand -hex 32)" --service web値は process.env.SESSION_SECRET で読み取ります。変数を変更すると、再ビルドなしでサービスが再起動します。変数とシークレットを参照してください。
Managed Postgres を追加する
lizard add postgres
lizard secrets set DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' --service web
npm install pgシングルクォートで囲むと、シェルは ${{…}} を解釈しません。Lizard はデプロイ時に 参照 を、プロジェクトのプライベートネットワーク上のデータベースのアドレスに解決します。server.js にプールとルートを追加します:
import pg from "pg";
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
app.get("/db", async (req, res) => {
const { rows } = await pool.query("SELECT now() AS now");
res.json(rows[0]);
});Express 5 はルートで reject された promise をエラーハンドラーに渡すため、クエリが失敗してもプロセスはクラッシュせず、HTTP 500 を返します。マイグレーションは、データベースのパブリック URL を使って手元のコンピューターから実行します:
lizard run --service postgres -- npm run migrateキャッシュやジョブキューには、同じ方法で Managed Redis を追加します。lizard add redis を実行してから、REDIS_URL='${{redis.REDIS_PRIVATE_URL}}' を設定してください。
動作を確認する
lizard logs --build --service web
lizard logs --service web --tail 100
lizard psランタイムログには listening on 3000 が表示されます。lizard up が表示した URL で /healthz と /db をリクエストしてください。
よくある問題
| 症状 | 対処 |
|---|---|
lock ファイルが同期していないため npm ci が失敗する | ローカルで npm install を実行し、package-lock.json をコミットします。 |
nodemon: not found または tsx: not found | これらのツールは devDependencies なので、起動用にはインストールされません。build ステップを追加するか、ツールを dependencies に移します。 |
| デプロイがいつまでも healthy にならない | process.env.PORT で待ち受けてください。5000 のような固定ポートはサービスポートと一致しません。サービスが healthy にならないを参照してください。 |
| Node.js のバージョンが違う | .nvmrc にメジャーバージョン(例: 24)を書き、もう一度デプロイします。 |
Cannot use import statement outside a module | package.json に "type": "module" を追加するか、require を使います。 |
キューコンシューマーや Discord bot のように HTTP を提供しない Node.js プロセスは、バックグラウンドワーカー として実行します。
関連項目
更新日