Nginx 部署 单页面应用 + nodejs api 应用 最佳实践

假定你的域名是 xxx.com 如果没有域名 则使用你的服务器 ip


现代前端框架打包后基本会将文件放在 /dist 目录下,通常肯定会有一个index.html的文件 /dist/index.html

然后你需要把打包文件上传到服务器,假如你上传到了 "/var/www/xxx.com/web/"

配置 nginx 添加一个 server块 代理静态文件

	server {
		listen 80;
		server_name xxx.com www.xxx.com;
		root	/var/www/xxx.com/web/;
		index index.html;

		location ~* .(?:manifest|appcache|html?|xml|json)$ {
			expires -1;
		}

		location ~* .(?:css|js)$ {
			try_files $uri =404;
			expires 1y;
			access_log off;
			add_header Cache-Control "public";
		}

		location ~ ^.+..+$ {
			try_files $uri =404;
		}

		location / {
			try_files $uri $uri/ /index.html;
		}
	}

测试nginx配置 nginx -t 没有问题就热重启nginx nginx -s reload

然后在浏览器访问 xxx.com 没有意外就能看到前端页面

node api 服务器

我这里使用 nestjs 示范

假如你的应用程序中要调用一个http接口 "/api/test"

那么在 nestjs 中实现可能是这样

@Controller()
export class AppController {
  @Get('/api/test')
  test() {
    return { a: 1 };
  }
}

现在将你本地的nestjs程序 打包上传到服务器,并使用 pm2 启动,假如你的node启动的是 3000 端口,那么访问 http://xxx.com:3000/api/test 应该会看到 "{ a: 1 }"

部署 Nestjs 最佳实践 在这里

这个时候 需要使用nginx反向代理 http://xxx.com/api/testhttp://xxx.com:3000/api/test

在 server 中添加一个location即可

		location /api/ {
			proxy_pass http://127.0.0.1:3000;
		}

现在你的 server 看起来应该是这样

	server {
		listen 80;
		server_name xxx.com www.xxx.com;
		root	/var/www/xxx.com/web/;
		index index.html;

		location /api/ {
			proxy_pass http://127.0.0.1:3000;
		}

		location ~* .(?:manifest|appcache|html?|xml|json)$ {
			expires -1;
		}

		location ~* .(?:css|js)$ {
			try_files $uri =404;
			expires 1y;
			access_log off;
			add_header Cache-Control "public";
		}

		location ~ ^.+..+$ {
			try_files $uri =404;
		}

		location / {
			try_files $uri $uri/ /index.html;
		}
	}

重启 nginx nginx -t && nginx -s reload

现在在网页访问你的web程序,http服务应该能正常工作

现在有了 web客户端和node api,你可能还需要一个 admin 后台 假如的你的后台也是用单页面写的,并且将 base 设置为 "/admin/"

打包你的 admin 项目, 上传到服务器 "/var/www/xxx.com/web/admin/"

配置 nginx "/admin/"

		location /admin/ {
			try_files $uri $uri/ /admin/index.html;
		}

现在你的 server 看起来应该是这样

	server {
		listen 80;
		server_name xxx.com www.xxx.com;
		root	/var/www/xxx.com/web/;
		index index.html;

		location /api/ {
			proxy_pass http://127.0.0.1:3000;
		}


		location ~* .(?:manifest|appcache|html?|xml|json)$ {
			expires -1;
		}

		location ~* .(?:css|js)$ {
			try_files $uri =404;
			expires 1y;
			access_log off;
			add_header Cache-Control "public";
		}

		location ~ ^.+..+$ {
			try_files $uri =404;
		}

		location /admin/ {
			try_files $uri $uri/ /admin/index.html;
		}

		location / {
			try_files $uri $uri/ /index.html;
		}
	}

现在热重启 nginx nginx -t && nginx -s reload

访问 http://xxx.com/ 显示客户端程序

访问 http://xxx.com/admin/ 显示后台程序

提取 server 块

在 "nginx.conf" 同目录下创建 "xxx.com.conf" 然后将server块复制进去,然后在 "nginx.conf" 的http块 中导入 "xxx.com.conf"

现在你的配置可能是这样

[root@96 conf]# cat xxx.com.conf 
server {
	listen 80;
	server_name xxx.com www.xxx.com;
	root	/var/www/xxx.com/web/;
	index index.html;

	location /api/ {
		proxy_pass http://127.0.0.1:3000;
	}

	location ~* .(?:manifest|appcache|html?|xml|json)$ {
		expires -1;
	}

	location ~* .(?:css|js)$ {
		try_files $uri =404;
		expires 1y;
		access_log off;
		add_header Cache-Control "public";
	}

	location ~ ^.+..+$ {
		try_files $uri =404;
	}

	location /admin/ {
		try_files $uri $uri/ /admin/index.html;
	}

	location / {
		try_files $uri $uri/ /index.html;
	}
}
[root@96 conf]# cat nginx.conf
worker_processes  1;

events {
	worker_connections  1024;
}

http {
	include       mime.types;
	default_type  application/octet-stream;
	proxy_cache_path proxycache keys_zone=one:10m;

	sendfile        on;
	keepalive_timeout  65;

	include a.com.conf;
        include b.com.conf;
	include xxx.com.conf; 
}

配置 https

必须要有域名

使用 certbot 配置 https (具体看certbot文档)

你现在的 "xxx.com.conf"

server {
	listen 80;
	listen 443 ssl;
	server_name xxx.com www.xxx.com;
	root	/var/www/xxx.com/web/;
	index index.html;

	ssl_certificate      /etc/letsencrypt/live/xxx.com/cert.pem;
	ssl_certificate_key  /etc/letsencrypt/live/xxx.com/privkey.pem;

	ssl_session_cache    shared:SSL:1m;
	ssl_session_timeout  5m;

	ssl_ciphers  HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers  on;


	location /api/ {
		proxy_pass http://127.0.0.1:3000;
	}


	location ~* .(?:manifest|appcache|html?|xml|json)$ {
		expires -1;
	}

	location ~* .(?:css|js)$ {
		try_files $uri =404;
		expires 1y;
		access_log off;
		add_header Cache-Control "public";
	}

	location ~ ^.+..+$ {
		try_files $uri =404;
	}

	location /admin/ {
		try_files $uri $uri/ /admin/index.html;
	}

	location / {
		try_files $uri $uri/ /index.html;
	}
}

如果你想使用 docker 配置 nginx + 单页面应用 + nodejs api + 数据库 可以看这里

原文地址:https://www.cnblogs.com/ajanuw/p/15082607.html