迁移到 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 认证密钥
  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 建议用 nano 编辑 conf 文件,但我忍不住。

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

转到指定路径并用 vscode 打开文件。

然后删除内部所有内容,并粘贴 chatgpt 提供的内容。

具体细节请参考注释。

# 处理器数量自动。负载低时 1 也可。
# events 中 connections 的数量是要处理的连接数。
# 处理器数量 * 连接数 = 可同时处理的连接数。
worker_processes auto;
events {
    worker_connections 1024;
}

# 处理 HTTP 请求。mail{}, stream{} 等可处理多种类型。
http {
    # 根据内容扩展名自动指定 MIME 类型。
    include       mime.types;
    # 虚拟主机配置
    include /opt/homebrew/etc/nginx/sites-enabled/*;
    # 不知道 MIME 设置时的默认 MIME 类型。
    default_type  application/octet-stream;
    # 使用操作系统内核功能提高文件传输性能。用于服务静态文件。
    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

댓글을 불러오는 중...