nextjs + nginxでのマイグレーション

힘센캥거루
2025년 5월 23일(수정됨)
52
nextjs

サブドメインを利用しようと検索していたところ、ホスティングサーバーだけでなくサーバー側でも設定が必要であることに気づきました。

まず、ホスティングサービスではAやCNAMEレコードを登録します。

そして、該当するリクエストがコンピュータに届くと、ヘッダーのhostに基づいてリバースプロキシ設定に従いポートを転送します。

まずプロキシとは何か、リバースプロキシとは何かを学んだところから記載します。

nextjs + nginxでのマイグレーション-1

1. プロキシとリバースプロキシ

1. プロキシとは?

プロキシ(proxy)は「代理」あるいは「代理人」という意味です。

プロキシはユーザーの立場から中継をするサーバーです。

ユーザーがプロキシにリクエストを送ると、プロキシはユーザーが望む実際の目的地に該当する内容を受け取り、伝達した後、そのリクエストを受けてユーザーに送り返します。

例えるならコンビニの宅配サービスのようなものです。

私たちが宅配便を届けたいのはコンビニではなく配送業者です。

コンビニに郵便物を預けると、そのコンビニが代わりに配送業者へ届け、応答を返してくれます。

nextjs + nginxでのマイグレーション-2

2. リバースプロキシ

プロキシはクライアントから外部サーバーへのリクエストを代行して伝達するものですが、リバースプロキシは内部サーバーでの分配プロセスです。

上で説明した郵便物が配送業者に届くプロセスがプロキシだとすれば、配送物を各家庭に分けるプロセスです。

流れが真逆なのでリバース(reverse)がつきました。

やりたいことはサブドメインを作成し、リクエストヘッダーに含まれるhost名に従い内部サーバのポートを分配するプロセスなのでリバースプロキシです。

2. nginx マイグレーションのプロセス

プロセスは思ったより簡単でした。

nginx インストール -> server.js 削除および nextjs の package.json の復元 
    -> nginx.conf 変更 -> nextjs, nginx 開始

chatgptに不明な点を質問しながら進めたところ、だいたい15〜20分くらいで終わったようです。

やはりコーディングは分からなくてもとりあえず始めるのが正解のようです。

3. 具体的なプロセス

1. nginx インストール

常々思うのが、これがあるからMacBookを使うということです。

Homebrewさえインストールしていれば、煩雑な設定なしにインストールは一発です。

しかもすぐにサービスを登録できます。

brew install nginx
brew services start nginx

2. server.js 削除および package.json の復元

元々使っていたサーバーの関数は以下の通りです。

これはただ削除しても問題ないですが、念のためバックアップしておきました。

const https = require("https");
const http = require("http");
const { parse } = require("url");
const next = require("next");
const fs = require("fs");

const dev = process.env.NODE_ENV !== "production";
const PORT_HTTPS = 8000;
const PORT_HTTP = 3000;
const hostname = "localhost"; // or カスタムドメイン
const app = next({ dev, hostname, PORT: PORT_HTTPS });
const handle = app.getRequestHandler();

const httpsOptions = {
  key: fs.readFileSync(
    "privkey パス",
    "utf8"
  ), // 発行した ssl認証キーを "readFileSync"で読み込み
  cert: fs.readFileSync(
    "fullchain パス",
    "utf8"
  ),
};

async function startServer() {
  try {
    await app.prepare();

    const httpsServer = https.createServer(httpsOptions, (req, res) => {
      const parsedUrl = parse(req.url, true);
      handle(req, res, parsedUrl);
    });

    httpsServer.listen(PORT_HTTPS, () => {
      console.log(`> Ready on https://${hostname}:${PORT_HTTPS}`);
    });


    const httpServer = http.createServer((req, res) => {
      res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });
      res.end();
    })
    httpServer.listen(PORT_HTTP, () => {
      console.log(`> Ready on http://${hostname}:${PORT_HTTP}`);
    })
  } catch (err) {
    console.error("Error starting the server:", err);
  }
}

startServer();

そして package.json で script 部分を以下のように変更しました。

"scripts": {
    "dev": "nodemon server.js",
    "build": "next build",
    "start": "NODE_ENV=production nodemon server.js",
    "lint": "next lint",
  },
"scripts": {
    "dev": "next dev",            
    "build": "next build",        
    "start": "next start",         
    "lint": "next lint",            
},

これをした後 sudo yarn dev を実行するとhttp://localhost:3000で自動的にサーバーが起動されます。

これで基本的な準備は終了ですので、nginx を触ってみましょう。

3. nginx.conf 変更

chatgptは conf ファイルを次のように nano で編集すると言いましたが、我慢できずに...

nano /opt/homebrew/etc/nginx/nginx.conf

そのパスで突撃し、vscode でファイルを開きました。

そして中にある内容をすべて削除し、GPT兄貴がくれた内容をコピペしました。

詳細な内容はコメントを参考にしてください。

# プロセッサ数は自動。低負荷なら1でもOK。
# eventsでconnectionsの数は処理する接続数。
# プロセッサ数 * コネクション数 = 同時に処理可能な接続数。
worker_processes auto;
events {
    worker_connections 1024;
}

# httpリクエストに対する処理。他にもmail{}, stream{}などいろいろなタイプを処理可能。
http {
    # コンテンツ拡張子に応じてMIMEタイプを自動的に設定する。
    include       mime.types;
    # 仮想ホスト設定を指定するserver設定
    include /opt/homebrew/etc/nginx/sites-enabled/*;
    # MIME設定が不明な場合にデフォルトで使うMIMEタイプ
    default_type  application/octet-stream;
    # OSのカーネル機能でファイル転送機能を向上させる。静的ファイルをサービスする際に使用。
    sendfile        on;
    # クライアントと接続を維持する時間。不必要なTCP接続を減らしサーバー性能を向上させる。
    keepalive_timeout 65;

    # この中にserverブロックを入れます。
    # 最初はhttpリクエストをhttpsにリダイレクト
    server {
        listen 80;
        server_name www.earthscience.kr earthscience.kr;
        return 301 https://$host$request_uri;
    }
    # 次はhttpsリクエストとSSL証明書、キーの位置を含む。
    server {
        listen 443 ssl;
        server_name www.earthscience.kr earthscience.kr;

        ssl_certificate /etc/letsencrypt/live/www.earthscience.kr/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/www.earthscience.kr/privkey.pem;

        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

4. nextjs, nginx 起動

これで nextjs でのファイルビルド -> サーバー起動後 nginx を実行すれば完了です。

sudo yarn build
sudo yarn start
sudo nginx # nginxをまだ開始していなければ

4. 感想

初めて nginx について聞いたときは、また新しい言語を学ばなければならないかもしれないというプレッシャーで動けませんでした。

実際にやってみると、server.js を設定するよりはるかに簡単です。

やはりプログラミングは何はともあれ始めてみるのが正しいようです。

しかし...

ミームを探していたら nginx よりも良いという caddy を見つけてしまいました?

また新たな旅が始まりそうです。

nextjs + nginxでのマイグレーション-3

댓글을 불러오는 중...