nginx配置多个项目在同一域名,同一台服务器上(node版)

414 阅读2分钟

需求:我这里有4个项目,home项目是个人官网项目,其他三个分别是api, admin, web,分别代表后端服务,前端管理后台,前端展示页面,其中home和web都是nextjs项目,admin是umi生成的静态页面,api是nestjs写的服务端,我想把网站部署到在同一域名,同一台服务器下。

首先是通用配置

server {
        listen 80 default_server;
        listen [::]:80;
        server_name www.domain.com domain.com;
}

然后是home的nginx配置

接在server_name后面

#home
location / {
    root /project/.next/static;
    try_files $uri $uri.html /index.html
    @public
    @nextjs;
    add_header Cache-Control "public, max-age=3600";
    add_header X-my-debug "my-debug:home";
}

location @public {
    add_header Cache-Control "public, max-age=3600";
}

location @nextjs {
    proxy_pass http://127.0.0.1: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;
}

上面的搜索路径是/project/.next/static 代表的是项目project 运行npm run build后的路径。

当访问www.domain.com/ 的时候try_files会一一执行下面的语句,

$uri代表/后面的内容,比如/post,/article

$uri.html 就是/post.html

/index.html就是/post/index.html,/index.html

然后再找不到,就执行@public,@nextjs的内容,@public就加个public的header, @nextjs就是你pm2

start 后面的服务,记住3000是你设置的端口

接着部署api项目

# project1_api
location /project1_api {
    proxy_pass http://127.0.0.1:3100/api;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
}

这个项目是nest项目,部署前先执行pm2 start调用起来

注意由于/project1_api才是代理api项目的路由,所以admin和web项目的api请求都要改成project1_api 由原先的 /api/article => /project1_api/article

如果你前端项目使用axios 你可以通过requestInterceptors下写这条代码,上传的时候换成project1_api

if (REACT_APP_ENV === 'prod') {
    config.url = config.url?.replace('/api/', '/project1_api/');
}

接着部署admin项目

location /project1_admin {
    alias  /home/project1_admin/dist;
    try_files $uri $uri/ /index.html /404.html;
}

这个项目是umi生成的静态文件所以,不需要部署 这里有个巧妙的解决方案是 当访问/project1_admin/article 否则/project1_admin/article/name的时候 try_files的uriuri uri/ /index.html都找不到文件,因为单页面应用就只有根目录有个index.html,这时候让他跳到/404.html页面上,注意这个404的路由会被home项目捕获,所以需要在home项目的404页面上加个逻辑,让它跳到/project1_admin的根目录下

useEffect(() => { if (window.location.href.search('/project1_admin/') > -1) {  
    window.location.replace(`http://${location.host}/project1_admin`) } }, []
)

接着部署web项目

/project1_web/.next/static是project1_web执行npm run buil生成的项目 这项目的部署跟home一模一样,只是端口不同3002 这里需要rewrite /project1_web/(.*) /$1 break; 因为web项目下css,js这些文件也要指向这里

# project1_web
location /project1_web {
    alias /project1_web/.next/static;
    try_files $uri $uri.html /$uri /index.html
    @public
    @project1_nextjs;
    add_header Cache-Control "public, max-age=3600";
}

location @project1_nextjs {
    rewrite /project1_web/(.*) /$1  break;
    proxy_pass http://127.0.0.1:3002;
    proxy_redirect     off;
    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;
}

ok如果你看到这里,你应该能发现了,既然project1能存在,那么project2, project3也行。