云服务器使用nginx部署web项目

nginx 是一个很强大的高性能Web反向代理服务。

image-20220828015532132

本文以百度智能云服务器debian为例,root角色进行操作。非 root 角色,需要sudo <命令>,回车,输入当前用户密码即可执行。

安装 nginx

1
2
3
4
5
6
7
8
9
# 列出所有可更新的软件清单命令
$ apt update
# 升级软件包
$ apt upgrade
# 安装nginx
$ apt install nginx
# 查下版本,确认安装成功
$ nginx -v
nginx version: nginx/1.10.3

Tips

nginx 版本不同,目录可能存在一些差异

nginx 目录

1
2
3
4
5
$ whereis nginx
$ cd /etc/nginx
$ ls
conf.d fastcgi_params koi-win modules-available nginx.conf scgi_params sites-enabled uwsgi_params
fastcgi.conf koi-utf mime.types modules-enabled proxy_params sites-available snippets win-utf

其中,/etc/nginx/nginx.conf为主配置文件,sites-avaiable主要用户配置 server 端。

执行文件:/usr/sbin/nginx

web 目录:/var/www

常用命令

1
2
3
4
5
6
7
8
9
10
# 停止nginx
$ /etc/init.d/nginx stop
# 启动nginx
$ /etc/init.d/nginx start
# 服务状态
$ /etc/init.d/nginx status
# 重新载入配置文件
$ /etc/init.d/nginx reload
# 重启
$ /etc/init.d/nginx restart

service 命令管理 nginx 服务

1
2
3
4
5
6
7
8
9
10
# 启动
$ service nginx start
# 停止
$ service nginx stop
# 服务状态
$ service nginx status
# 重载
$ service nginx reload
# 重启
$ service nginx restart

systemctl 命令管理 nginx 服务

1
2
3
4
# 列出所有 service 单元配置
$ systemctl list-units --type=service
# 查看nginx服务状态
$ systemctl status nginx
1
2
# 测试配置文件
$ nginx -t

Tips

systemctl 命令是系统服务管理器指令,它实际上将 service 和 chkconfig 这两个命令组合到一起。

web 目录与 sites-enabled

前面我们提到 web 存放目录是:/var/www,里面默认有一个 html 目录,在我们安装完 nginx 时直接再浏览器输入 ip 或域名,默认会到 80 端口,并展示一个 welcom to nginx 的界面,就是来自于/var/www/html/index.nginx-debian.html 这个文件。为什么会默认到这个文件,是在哪里配置的呢,打开/etc/nginx/nginx.conf 主配置文件会发现在 http 内有这么一句代码:

1
2
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

如果所有 server 配置都写在 nginx.conf 主配置文件中,难免会显得杂乱与臃肿。为了方便配置文件的维护,所以需要进行拆分配置,将低耦合高内聚贯彻到底。

include /etc/nginx/sites-enabled/ 的作用就是引入/etc/nginx/sites-available/下的所有 server 文件(有一个默认的default文件),其实 sites-enabled 下是 server 配置文件的软链接。而实际配置其实是在/etc/nginx/sites-available/下。

sites-available 中自定义文件并部署项目

如果我们要在 web7000 这个目录下部署多个 web 项目,web1,web2。让浏览器访问 localhost:7000/web1 时响应 web1 的项目,访问 localhost:7000/web2 时响应 web2 的项目。

切换到/etc/nginx/sites-available目录下,ls查看当前目录的配置,默认是有一个default 案例。将 default 复制一份,并起名为任意名字以.conf 结尾的文件,注意命名不要使用下划线符号_连接的方式,这可能导致文件执行无效。

1
2
3
4
5
6
$ cd /etc/nginx
$ ls
$ cd sites-available
$ ls
$ cp default web7000.conf
$ vim web7000.conf

web7000.conf 文件配置如下:

http://www.hautree.top指向http://ip:7000

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
listen [::]:80;
server_name www.hautree.top

location / {
proxy_pass http://localhost:7000;
}
}

server {
listen 7000;
listen [::]:7000;
server_name localhost;
# 静态资源路径
root /var/www/web7000;
# 入口文件-首页
index index.html;

location / {
add_header Access-Control-Allow-Origin *;
# root /var/www/web7000;
# index index.html;
try_files $uri/ =404;
}
}

接下来保存退出,在 sites-enabled 目录下创建软连接

1
2
$ cd /etc/nginx/sites-enabled
$ ln -s /etc/nginx/sites-available/web7000.conf

然后再重启 nginx,让配置生效

1
2
3
4
5
6
7
8
# 优雅地重启nginx
# 如果要在更改配置后刷新nginx,最好最好重新加载服务。这将关闭旧进程,并使用新配置重新启动新进程。
$ systemctl reload nginx
# 或
$ /etc/init.d/nginx reload
# 强制重启Nginx
# 对于主要配置更改,可以强制完全重新启动nginx。这将强制关闭整个服务和子流程,然后重新启动整个程序包。
$ systemctl restart nginx

在浏览器中输入www.hautree.top,则会显示我们放在/var/www/web7000 下的 index.html 文件。这样就完成了一个基本的 web 项目部署。

一个端口下部署多个项目

以上操作我们只能在 7000 端口下,/var/www/web7000 目录下部署一个项目,如果要部署多个项目又该如何实现呢?例如浏览器输入 ip:7000/web1 显示项目 web1,输入 ip:7000/web2 显示项目 web2,我们的/var/www/web7000 目录结构是这样

1
2
3
+-- web7000
+-- web2
+-- web1

更改/etc/nginx/sites-available/web7000.conf文件为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
listen 80;
listen [::]:80;
server_name www.hautree.top

location / {
proxy_pass http://localhost:7000;
}
}

server {
listen 7000;
listen [::]:7000;
server_name localhost;
# 静态资源路径
root /var/www/web7000;
# 入口文件-首页
index index.html;

location /web2 {
add_header Access-Control-Allow-Origin *;
try_files $uri/ =404;
}
location /web1 {
add_header Access-Control-Allow-Origin *;
try_files $uri $uri/ =404;
}
}

location = /web1表示浏览器输入www.huatree.top/web1进入此规则,location = web2 同理。

try_files $uri $uri/ =404存在优先级,首先找 u r i 是 否 存 在 , 不 存 在 响 应 404。

uri又代表什么意思呢,浏览器输入www.huatree.top/web2, $uri 代表的就是/web2 文件,注意是web2 文件(不是指目录)。

$uri/代表的是**/web2 目录**,如果存在则会结合 root 去找/var/www/web7000/web2 下的 index.html 并响应。

所以我们做了以上配置会发现浏览器中输入www.huatree.top/web1响应 404,输入www.huatree.top/web2才会响应对应 web2 项目下的 html 文件。

那是不是 try_files $uri 就没啥用了呢?

我们在浏览器端输入 ip:7000/web1/index.html 时, $uri 解析成了 web1/index.html,所以这样时能访问的,利用这个特性,我们还可以访问 web1 下的其他资源,比如有一张 test.png 图片,则可 ip:7000/web1/test.png。

一个端口下部署多个 Vue 项目

场景:需要解决 CORS,接口地址通过 nginx 代理

配置 vue 文件

vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
publicPath: '/web3', // web4 ...
devServer: {
open: true,
proxy: {
'/api': {
target: 'http://api.xxx.top', // 接口地址
changeOrigin: true
}
}
}
}

router/index.ts

1
2
3
4
5
const routerHistory = createWebHistory('/web3')
const router = createRouter({
history: routerHistory,
routes:constantRoutes
}

打包

将打包生成的 dist 中的文件拷贝到/etc/nginx/sites-available/h5.conf 中规定好的目录下

配置 h5.conf

1
2
$ cp /etc/nginx/sites-available/default /etc/nginx/sites-available/h5.conf
$ vim /etc/nginx/sites-available/h5.conf

编辑 h5.conf 关键内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
server {
listen 80;
listen [::]:80;

server_name h5.huatree.top;

location / {
proxy_pass http://localhost:7001;
}
}

server {
listen 7001;
listen [::]:7001;

server_name localhost;

root /home/www/subapp;
index index.html;

location /web3 {
try_files $uri $uri/ =404;
}
# location /web4 {
# try_files $uri $uri/ =404;
# }
location /api {
proxy_pass http://api.xxx.top/api;
}
# location /api2 {
# proxy_pass http://api.xxx.top/api2;
# }
}

nginx 配置并默认跳转到 https

1
2
3
$ cd /etc/nginx/sites-available
$ cp default reverse-proxy.conf
$ vim reverse-proxy.conf

reverse-proxy.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 443 ssl;
listen [::]:443 ssl;
# 日志
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;

# 启用ssl功能(最新版本不需要配置,默认开启)
ssl on;

# 证书
ssl_certificate /home/huatree/certs/huatree.top_bundle.pem;
ssl_certificate_key /home/huatree/certs/huatree.top.key;

# 会话、协议等
ssl_session_cache shared:SSL:1m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

location / {
proxy_pass http://localhost:7000;
}
}

证书:这里的证书,可以去域名提供商那儿,申请免费的安全证书。了解更多,可详见参考 6,7,申请下载配置使用。

这里以一个端口下部署的单个项目为例,更改/etc/nginx/sites-available/web7000.conf文件为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
listen 80;
listen [::]:80;
server_name www.hautree.top
# 重写
rewrite ^(.*) https://www.huatree.top permanent;

location / {
proxy_pass http://localhost:7000;
}
}

server {
listen 7000;
listen [::]:7000;
server_name localhost;
# 静态资源路径
root /var/www/web7000;
# 入口文件-首页
index index.html;

location / {
add_header Access-Control-Allow-Origin *;
# root /var/www/web7000;
# index index.html;
try_files $uri/ =404;
}
}

最后,让配置生效

1
2
3
4
5
6
# 检查配置是否正常
$ nginx -t
# 重载
$ systemctl reload nginx
# 或者重启
$ systemctl restart nginx

相关链接

[1] debian > 系统管理

[2] Linux 下 systemctl 命令和 service、chkconfig 命令的区别

[3] 云服务器使用 nginx 部署 web 项目(ubuntu 操作系统)

[4] nginx 配置选项 try_files 详解

[5] Debian 下用 Nginx 反向代理 http 为 https

[6] DEBIAN8 NGINX 添加阿里云 SSL 证书,配置 HTTPS

[7] Nginx|Tomcat 配置 https

[8] nginx 一个端口部署多个 vue 项目