在搜索使用子域时,我意识到不仅需要在托管服务器上设置,还需要在服务器端配置。
首先,在托管服务中注册 A 或 CNAME 记录。
当请求进入计算机时,将根据头部的 host,将端口传递给反向代理配置。
首先描述一下我学到的关于代理和反向代理的知识。

1. 代理与反向代理
1. 什么是代理?
代理(proxy)意为“代理人”或“代表”。
代理是用户端用于中继的服务器。
当用户向代理发送请求时,代理会将用户所需的内容发送到实际目的地,然后接收请求并传递给用户。
可以比作便利店快递。
我们想要送达快递的地方不是便利店,而是物流公司。
如果把快递放在便利店,便利店会代为转交给物流公司并返回应答。

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 nginx2. 删除 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 # 如果还没有启动 nginx4. 感想
刚听说 nginx 的时候,因为担心要学习一种新语言而退缩。
结果发现比设置 server.js 简单多了。
果然编程就是要先尝试。
不过...
在找网络迷因时发现了据说比 nginx 更好的 caddy?
看起来又要开启新的旅程了。

댓글을 불러오는 중...