一台云服务器跑多个小项目:Nginx 反向代理加子路径隔离的实操
一台云服务器跑多个小项目:Nginx 反向代理加子路径隔离的实操
个人手里的小项目一多,很容易变成一台服务器一个项目,机器越买越多,账单越堆越高。其实一台 2 核 2G 的小服务器,跑三五个访问量不大的小项目完全够用,关键是把入口收敛到 Nginx 这一层:Nginx 对外只占 80 和 443 端口,后面每个项目跑在自己的本地端口上,互不干扰;出问题也只影响一个项目,不会整台机器一起倒。
一、先定好端口分配表,别随手起端口
多项目共存最先乱掉的往往是端口。今天起个 3000,明天起个 8080,过两个月自己都忘了哪个端口对应哪个项目。我的做法是建一张固定的端口分配表,写在服务器的备忘文件里,新增项目先查表再分配。
一个简单可行的分段:3000 到 3099 给 Node 类项目,4000 到 4099 给 Python 类项目,5000 到 5099 给静态站点加简单后端,8000 到 8099 留给数据库管理工具这类内部服务。端口号本身没有讲究,分段只是为了以后一眼能看出项目类型。分配表里每行记四样东西:端口、项目名、启动命令、负责人(个人项目就写自己)。改配置、重启服务、排查故障时,先看这张表,省掉大量翻历史命令的时间。
另外一条铁律:业务项目一律只监听 127.0.0.1,不要监听 0.0.0.0。只绑本地回环地址,外部就访问不到这个端口,只能经过 Nginx 转发。这样即使安全组一时配宽了,项目本身也不会直接暴露在公网上,等于多了一层保险。启动命令里显式写清楚监听地址,比如 Node 的应用就写 HOST=127.0.0.1 PORT=3001,不要依赖框架默认。
二、Nginx 按域名或子路径分流
入口收敛之后,分流有两种常见做法,按域名分和按子路径分。手里有域名、每个项目能分一个子域名时,按域名分最干净:a.example.com 和 b.example.com 各自一个 server 块,配置互相独立,改一个不影响另一个。只有一个域名、或者项目只是内部小工具时,按子路径分更省事:example.com/blog/ 走博客,example.com/tool/ 走工具站。
按域名分的配置骨架很固定。每个 server 块只做三件事:监听 80 端口、写清 server_name、把请求 proxy_pass 到本机的项目端口。转发时有三个头一定要带上,否则后端拿不到真实信息:proxy_set_header Host $host 让后端知道原始域名,proxy_set_header X-Real-IP $remote_addr 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for 让后端日志里记录的是访客真实 IP 而不是 127.0.0.1。少了这三行,以后查访问日志全是本地地址,等于白记。
按子路径分要多注意一个坑:很多前端项目打包时写死了根路径 /,放到 /tool/ 下面后静态资源全按根路径请求,直接 404。部署前先确认项目支持子路径部署,前端项目一般在构建配置里改一个 publicPath 或 base 就能解决;改不了的,就别硬塞进子路径,改走子域名。不要在 Nginx 里用 rewrite 去硬拼资源路径,越拼越乱,后期维护的人一定会骂。
三、每个项目独立目录、独立启动方式
目录结构同样要先定规矩再动手。我的习惯是 /srv/ 下面一个项目一个目录,目录名就是项目名,里面放三样东西:代码、启动脚本、日志目录。比如 /srv/blog/ 里面有代码、start.sh 和 logs/。启动脚本只写两行:进入目录、启动命令加日志重定向。以后重启项目不用回忆命令,直接跑脚本就行。
进程管理不要靠 nohup 挂后台,机器一重启就全丢了。小项目用 systemd 管最省心:每个项目一个 service 文件,写清工作目录、启动命令、重启策略 Restart=always,再 systemctl enable 设开机自启。服务挂了自动拉起,机器重启自动恢复,systemctl status 项目名 就能看运行状态。这一步花十分钟配好,后面能省掉无数次半夜爬起来手动重启。
日志也按项目分开。每个项目的标准输出重定向到自己目录的 logs/ 下面,Nginx 的访问日志和错误日志同样按 server 块分文件,不要全挤进默认的 access.log。出了问题先看对应项目的日志,不用在一堆混杂的记录里翻找。日志文件记得配轮转,做法和上一篇定时任务加日志轮转里写的一样,小项目一天几 MB,轮转周期放宽到每周一次也够用。
四、HTTPS 只配一次,后面复用
多项目共存时证书不要每个项目各配一套。Nginx 层面统一处理:用 certbot 给每个子域名签证书,或者只签一个通配符证书,server 块里引用同一份证书文件。证书到期自动续期由 certbot 的定时任务负责,不用每个项目单独操心。项目本身永远只跑 HTTP,加密只在 Nginx 这一层做,后端代码不用改一行。
子路径方案下更简单:整个域名只有一份证书,所有项目共用,新增项目完全不用碰证书配置。
五、上线新项目的固定顺序
最后把新增项目的流程固定下来,照着走就不会漏步骤:第一步,查端口分配表,领一个空闲端口;第二步,代码放到 /srv/项目名/,写好启动脚本;第三步,写 systemd service 文件,启动并设开机自启,确认本地 curl 127.0.0.1:端口 能返回内容;第四步,写 Nginx 的 server 块或 location,nginx -t 检查语法再 reload;第五步,从外网访问域名或子路径确认 200,顺手看一眼日志有没有报错。
这套做法的成本很低:一台小服务器、一个 Nginx、几张固定表格。换来的是项目之间互不干扰、故障定位有章可循、新增项目十分钟上线。等到某天某个项目访问量真的上来了,再单独给它迁一台机器也不迟,迁移时只要把对应目录和配置原样搬走,入口改一行 DNS 就行。
- 点赞
- 收藏
- 关注作者
评论(0)