すべてのデプロイガイド デプロイ

Node.jsでSSL証明書を使用する方法

Node.jsはhttpsモジュールを通じて組み込みのHTTPSサポートを備えています。証明書ファイルを読み込み、HTTPSサーバーを作成します。このガイドでは、素のNode.js、Express、および推奨される本番環境のセットアップを解説します。

基本的なHTTPSサーバー

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('/etc/ssl/privkey.pem'),
  cert: fs.readFileSync('/etc/ssl/fullchain.pem'),
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('Hello HTTPS');
}).listen(443);

ExpressでのHTTPS

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send('Hello HTTPS');
});

const options = {
  key: fs.readFileSync('/etc/ssl/privkey.pem'),
  cert: fs.readFileSync('/etc/ssl/fullchain.pem'),
};

https.createServer(options, app).listen(443, () => {
  console.log('HTTPS server running on port 443');
});

HTTPからHTTPSへのリダイレクト

HTTPとHTTPSの両方のサーバーを実行します:

const http = require('http');
const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();
// ... ルートの定義

const options = {
  key: fs.readFileSync('/etc/ssl/privkey.pem'),
  cert: fs.readFileSync('/etc/ssl/fullchain.pem'),
};

// HTTPSサーバー
https.createServer(options, app).listen(443);

// HTTPリダイレクト
http.createServer((req, res) => {
  res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });
  res.end();
}).listen(80);

本番環境の推奨:リバースプロキシ

本番環境では、Node.jsで直接TLSを終端しないでください。前段にリバースプロキシ(NginxCaddy、またはロードバランサー)を配置してください:

Client ──HTTPS──→ Nginx (TLS termination) ──HTTP──→ Node.js (port 3000)

理由:

  • NginxのTLS処理の方が効率的(C vs JavaScript)
  • 証明書の更新でNode.jsの再起動が不要
  • ポート443にはroot権限が必要 — Node.jsをrootで実行すべきではない
  • レート制限、キャッシュ、圧縮をプロキシが処理
  • HTTP/2のサポートがNginxの方が成熟している

Node.jsでの直接HTTPSは、開発環境、内部サービス、または小規模プロジェクトには問題ありません。

主要フレームワーク

Fastify

const fastify = require('fastify')({
  https: {
    key: fs.readFileSync('/etc/ssl/privkey.pem'),
    cert: fs.readFileSync('/etc/ssl/fullchain.pem'),
  },
});

fastify.get('/', async () => ({ hello: 'https' }));
fastify.listen({ port: 443, host: '0.0.0.0' });

Koa

const Koa = require('koa');
const https = require('https');
const fs = require('fs');

const app = new Koa();
app.use(ctx => { ctx.body = 'Hello HTTPS'; });

https.createServer({
  key: fs.readFileSync('/etc/ssl/privkey.pem'),
  cert: fs.readFileSync('/etc/ssl/fullchain.pem'),
}, app.callback()).listen(443);

Next.js / Nuxt / その他のフレームワーク開発サーバー

フレームワークの開発サーバーは通常、ローカル開発用の--httpsフラグを備えています。本番環境では常にリバースプロキシを使用してください。これらのフレームワークはNginx、Caddy、またはクラウドロードバランサーの背後で静的ファイルの配信やSSRを実行します。

環境変数パターン

証明書のパスをハードコードしないでください。環境変数を使用すれば、同じコードが開発環境と本番環境で動作します:

const options = process.env.SSL_KEY ? {
  key: fs.readFileSync(process.env.SSL_KEY),
  cert: fs.readFileSync(process.env.SSL_CERT),
} : null;

if (options) {
  https.createServer(options, app).listen(443);
  console.log('HTTPS server on port 443');
} else {
  app.listen(3000);
  console.log('HTTP server on port 3000 (no SSL_KEY set)');
}

開発環境での自己署名証明書

ローカル開発用に自己署名証明書を生成します(本番用ではありません):

openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
  -keyout dev-key.pem -out dev-cert.pem -days 365 -nodes \
  -subj "/CN=localhost"
const options = {
  key: fs.readFileSync('./dev-key.pem'),
  cert: fs.readFileSync('./dev-cert.pem'),
};

ブラウザが警告を表示します(自己署名証明書は信頼されていません)。開発用にクリックして進んでください。

証明書のホットリロード

再起動なしで証明書をリロードします(Let’s Encryptの更新に便利):

const tls = require('tls');

function loadCerts() {
  return {
    key: fs.readFileSync('/etc/ssl/privkey.pem'),
    cert: fs.readFileSync('/etc/ssl/fullchain.pem'),
  };
}

const server = https.createServer({
  SNICallback: (hostname, cb) => {
    const ctx = tls.createSecureContext(loadCerts());
    cb(null, ctx);
  },
}, app);

これにより、新しい接続ごとにファイルが再読み込みされます。パフォーマンスを向上させるには、ファイルの変更時にのみリロードするファイルウォッチャーを追加してください。

よくある質問

Node.jsでSSLを処理すべきですか、リバースプロキシを使うべきですか?

本番環境:リバースプロキシを使用してください。開発環境、小規模プロジェクト、内部サービス:Node.jsの直接HTTPSで問題ありません。リバースプロキシパターンは関心の分離を実現し、TLSをより効率的に処理するため、標準的な手法です。

GetHTTPSの証明書をNode.jsで使用できますか?

はい。GetHTTPSは標準的なPEMファイル(privkey.pemfullchain.pem)を生成し、Node.jsはfs.readFileSync()で直接読み取れます。

Node.jsで証明書の更新をどう扱いますか?

リバースプロキシを使用している場合は、ファイルを置き換えてプロキシをリロードするだけです。Node.jsの再起動は不要です。TLSを直接処理している場合は、上記のSNICallbackアプローチを使用するか、証明書ファイルを置き換えた後にNode.jsプロセスを再起動してください。

開発用のlocalhost SSLはどうすればいいですか?

自己署名証明書(上記参照)またはmkcertを使用して、ローカルで信頼される開発証明書を作成してください。localhostにLet’s Encryptを使用しないでください。公開アクセスできないドメインは検証できません。

GetHTTPSの証明書をDenoやBunで使用できますか?

はい。DenoとBunはどちらもPEMファイルによるTLSをサポートしています:

Deno:

Deno.serve({
  port: 443,
  cert: Deno.readTextFileSync("/etc/ssl/fullchain.pem"),
  key: Deno.readTextFileSync("/etc/ssl/privkey.pem"),
}, (req) => new Response("Hello HTTPS"));

Bun:

Bun.serve({
  port: 443,
  tls: {
    cert: Bun.file("/etc/ssl/fullchain.pem"),
    key: Bun.file("/etc/ssl/privkey.pem"),
  },
  fetch(req) { return new Response("Hello HTTPS"); },
});

GetHTTPSの同じPEMファイルがすべてのJavaScriptランタイムで動作します。

関連記事

はじめに 2026-05-08
無料SSL証明書の取得方法(ステップバイステップガイド)
Let's Encryptから5分で無料のSSL証明書を取得。ソフトウェアのインストール不要、アカウント作成不要。4つの方法、両方のチャレンジタイプ、6つのプラットフォームへのインストール、トラブルシューティングを網羅した完全ガイドです。
デプロイ 2026-05-08
DockerとリバースプロキシでのSSL証明書
Nginxリバースプロキシ、自動Let's Encrypt対応のTraefik、手動証明書マウントを使用して、DockerコンテナにHTTPSを設定する方法を解説します。
SSL と証明書 2026-05-07
SSL証明書フォーマット:PEM、PFX、DERの違い
PEM、PFX/PKCS#12、DERの証明書フォーマットを解説。サーバーに必要なフォーマットとOpenSSLでの変換方法を紹介します。
ブラウザで無料 SSL 証明書を取得
インストール不要、アカウント不要。秘密鍵は常にデバイスに残ります。
証明書を取得