接上文
链接: Nginx 简介和入门 - part1
上文 我们简单地在 nginx 创建了3个虚拟主机, 虽然这个3个主机都是用占用80端口
但是我们可以用不同的域名来实现区分访问3台虚拟主机。
但是, 实际项目上, 我们更加多地会使用location 配置而不是用 域名区分。 本文的重点就是location 配置。
先准备1个网站模板
这次我们直接从github 下载
github 地址:
https://github.com/LinkedInLearning/learning-nginx-2492317.git
gateman@tf-vpc0-subnet0-main-server:~/learning-nginx$ pwd
/home/gateman/learning-nginx
gateman@tf-vpc0-subnet0-main-server:~/learning-nginx$ git clone https://github.com/LinkedInLearning/learning-nginx-2492317.git
解压
gateman@tf-vpc0-subnet0-main-server:~/learning-nginx/learning-nginx-2492317$ pwd
/home/gateman/learning-nginx/learning-nginx-2492317
gateman@tf-vpc0-subnet0-main-server:~/learning-nginx/learning-nginx-2492317$ sudo mkdir -p /var/www/binaryville/
gateman@tf-vpc0-subnet0-main-server:~/learning-nginx/learning-nginx-2492317$ sudo tar -xf Binaryville_robot_website_LIL_107684.tgz --directory /var/www/binaryville/
上面的命令直接把文件解压在了/var/www/binaryVille/ 这个文件夹
gateman@tf-vpc0-subnet0-main-server:~/learning-nginx/learning-nginx-2492317$ cd /var/www/binaryville
gateman@tf-vpc0-subnet0-main-server:/var/www/binaryville$ ls -l
total 100
-rw-r--r-- 1 root root 1140 Aug 5 2022 403.html
-rw-r--r-- 1 root root 1193 Jul 29 2022 404.html
-rw-r--r-- 1 root root 1208 Jul 29 2022 50x.html
-rw-r--r-- 1 root root 648 Aug 19 2020 README.rtf
drwxrwxr-x 38 root root 4096 Aug 3 2020 _style-guide
drwxrwxr-x 16 root root 4096 Aug 3 2020 about
drwxrwxr-x 2 root root 4096 Aug 3 2020 account
drwxrwxr-x 2 root root 4096 Aug 3 2020 assets
drwxrwxr-x 8 root root 4096 Aug 3 2020 blog
drwxrwxr-x 2 root root 4096 Aug 3 2020 cart
drwxrwxr-x 4 root root 4096 Aug 3 2020 checkout
drwxrwxr-x 2 root root 4096 Aug 3 2020 contact
-rw-rw-r-- 1 root root 45 Aug 3 2020 humans.txt
drwxrwxr-x 7 root root 4096 Aug 3 2020 images
-rw-rw-r-- 1 root root 29987 Jul 29 2022 index.html
drwxr-xr-x 2 root root 4096 Aug 5 2022 private
-rw-rw-r-- 1 root root 25 Aug 3 2020 robots.txt
drwxrwxr-x 3 root root 4096 Aug 3 2020 shop
然后在/etc/nginx/conf.d 准备1个for这个网站的配置文件
gateman@tf-vpc0-subnet0-main-server:/etc/nginx/conf.d$ cat binaryville.conf
server {
listen 8081;
server_name jp-gcp-vms.xyz www.jp-gcp-vms.xyz;
index index.html index.htm index.php;
root /var/www/binaryville;
}
注意这次用感到是8081 端口, 如果防火墙没打开这个端口的记得打开
重启 nginx 服务
nginx -t
sudo systemctl reload nginx
访问配置好的网站
http://jp-gcp-vms.xyz:8081/
好了接下来我们会尝试更新配置文件, 使用location 配置去更新这个网站的
- Site root
- Images
- Error Pages
配置Site root (网站根目录)
我们先检查下 网站目录 /var/www/binaryVille 的内容
gateman@tf-vpc0-subnet0-main-server:/var/www/binaryville$ ls -l
total 100
-rw-r--r-- 1 root root 1140 Aug 5 2022 403.html
-rw-r--r-- 1 root root 1193 Jul 29 2022 404.html
-rw-r--r-- 1 root root 1208 Jul 29 2022 50x.html
-rw-r--r-- 1 root root 648 Aug 19 2020 README.rtf
drwxrwxr-x 38 root root 4096 Aug 3 2020 _style-guide
drwxrwxr-x 16 root root 4096 Aug 3 2020 about
drwxrwxr-x 2 root root 4096 Aug 3 2020 account
drwxrwxr-x 2 root root 4096 Aug 3 2020 assets
drwxrwxr-x 8 root root 4096 Aug 3 2020 blog
drwxrwxr-x 2 root root 4096 Aug 3 2020 cart
drwxrwxr-x 4 root root 4096 Aug 3 2020 checkout
drwxrwxr-x 2 root root 4096 Aug 3 2020 contact
-rw-rw-r-- 1 root root 45 Aug 3 2020 humans.txt
drwxrwxr-x 7 root root 4096 Aug 3 2020 images
-rw-rw-r-- 1 root root 29987 Jul 29 2022 index.html
drwxr-xr-x 2 root root 4096 Aug 5 2022 private
-rw-rw-r-- 1 root root 25 Aug 3 2020 robots.txt
drwxrwxr-x 3 root root 4096 Aug 3 2020 shop
gateman@tf-vpc0-subnet0-main-server:/var/www/binaryville$ ls images
accepted-cards.svg characters empty-cart.svg home-hero-characters.png logo.svg placeholder-371x217.jpg placeholder-708x590.jpg placeholder-800x800.jpg product-montage.png
blog contact favicon icons.svg placeholder-1184x360.jpg placeholder-535x535.jpg placeholder-720x480.jpg product-montage-cropped.png products
gateman@tf-vpc0-subnet0-main-server:/var/www/binaryville$
我们在 /etc/nginx/conf.d/binaryVille.conf 添加下面代码
location /site {
# First attempt to serve a request as a file,
# then as directory, then fall back to display a 404
try_files $uri $uri/ =404;
}
这时的配置文件内容
root@tf-vpc0-subnet0-main-server:/etc/nginx/conf.d# cat binaryville.conf
server {
listen 8081;
server_name jp-gcp-vms.xyz www.jp-gcp-vms.xyz;
index index.html index.htm index.php;
root /var/www/binaryville;
location / {
# First attempt to serve a request as a file, then as directory, then fall back to display a 404
try_files $uri $uri/ =404 ;
}
}
root@tf-vpc0-subnet0-main-server:/etc/nginx/conf.d#
这段配置代码的意思是,
当访问/ url时, 例如 /abc
nginx 首先会把abc 作为 / 里的1个abc文件处理(通常是浏览器下载)
如果/var/www/binaryVille/ 没有abc这个文件 则尝试处理 /abc/ 当作文件夹
还没有, 返回404
注意 这段代码也是 nginx的默认处理逻辑,不加上也是这样的
这时我们尝试访问 /images
为什么是403 而不是404
首先, /var/www/binaryVille 里面没有images 的文件, 但是有images 文件夹
所以nginx 就当成/images/来处理了
但是images/下虽然有很多 图片文件, 但是默认下是不会显示文件列表的, 而且里面没有index.html 文件, 所以就显示403了
但是我们直接访问images 下某个图片文件, (前提是知道文件名)
是可以访问的
如果这时我们在images 添加1个index.html
root@tf-vpc0-subnet0-main-server:/var/www/binaryville/images# cat index.html
images folder!
root@tf-vpc0-subnet0-main-server:/var/www/binaryville/images#
再刷新下网页!
就能显示网页内容了
配置images 目录
这时我们再增加一段代码
location /images {
# Allow the contents of /images folder to be listed
autoindex on;
}
这时 配置文件内容
root@tf-vpc0-subnet0-main-server:/etc/nginx/conf.d# cat binaryville.conf
server {
listen 8081;
server_name jp-gcp-vms.xyz www.jp-gcp-vms.xyz;
index index.html index.htm index.php;
root /var/www/binaryville;
location / {
# First attempt to serve a request as a file, then as directory, then fall back to display a 404
try_files $uri $uri/ =404 ;
}
location /images {
# Allow the contents of /images folder to be listed
autoindex on;
}
}
当我们为 /images folder 打开 autoindex on时 , 我们刷新下/images/网页, 见到不再是
403 了
而是文件可以被列出
配置覆盖
如果 location / 的配置 和 location /images 的配置有冲突会怎么样
答案是 访问 非 /images 的资源时会依照 / 的配置
而访问 /images 资源时 按照 /images 的配置
例如下面的配置文件
root@tf-vpc0-subnet0-main-server:/etc/nginx/conf.d# cat binaryville.conf
server {
listen 8081;
server_name jp-gcp-vms.xyz www.jp-gcp-vms.xyz;
index index.html index.htm index.php;
root /var/www/binaryville;
location / {
# First attempt to serve a request as a file, then as directory, then fall back to display a 404
try_files $uri $uri/ =404;
}
location /images {
# Allow the contents of /images folder to be listed
autoindex on;
try_files $uri $uri/ =504;
}
}
location / 找不到资源时返回404
location /images 找不到资源时返回504
测试
当访问 /abcxx 时 页面是404
访问/images/abcxx 页面是504了
配置404 错误页面
上面的404 页面是 nginx 默认的
而网站目录下有自定义的404.html, 如何让404 出错的页面指向它呢, 还是location 配置
我们增加下面1段配置代码
# specify the page to server for 404 errors
error_page 404 /404.html;
很容易理解
我们再访问 http://jp-gcp-vms.xyz:8081/abcxx
的确能显示自定义的404.html 页面了
这时我们直接访问
http://jp-gcp-vms.xyz:8081/404.html
也会一样显示上面的页面的
如何禁止用户直接在浏览器访问 http://jp-gcp-vms.xyz:8081/404.html?
加上下面这段代码
# an exact map location for the 404 page
location = /404.html {
# only for intenal requests
internal;
}
也不难理解。。
但是for 这个case, 再访问 http://jp-gcp-vms.xyz:8081/404.html 还是会显示自定义的404 页面,
因为
访问 404.html -> 简直访问 -> return 404 error -> 还是调回404.html…
配置500 错误页面
我们再加上下面3段配置
# specify the page to server for 50x errors
error_page 500 502 503 504 /50x.html;
# an exact map location for the 404 page
location = /50x.html {
# only for intenal requests
internal;
}
# a location to demostrated 500 errors
location /500 {
fastcgi_pass unix:/this/will/fail;
}
其实与404的配置差不多, 小小区别:
- 用error_page 覆盖了多个error 到同1个页面50x.html
- 最后构造了1个 /500 的location 用于测试, fastcgi_pass unix:/this/will/fail 这个命令肯定会出错的
我们尝试访问 http://jp-gcp-vms.xyz:8081/500
就是我们想要的!
出错日志: /var/log/nginx/error.log
gateman@tf-vpc0-subnet0-main-server:/var/log/nginx$ tail -n 10 error.log
2024/01/07 16:26:16 [error] 195693#195693: *1771 open() "/var/www/binaryville1/.env" failed (2: No such file or directory), client: 140.82.15.131, server: 34.39.2.90, request: "GET /.env HTTP/1.1", host: "34.39.2.90"
2024/01/07 16:29:27 [warn] 213106#213106: conflicting server name "jp-gcp-vms.xyz" on 0.0.0.0:80, ignored
2024/01/07 16:29:27 [warn] 213106#213106: conflicting server name "www.jp-gcp-vms.xyz" on 0.0.0.0:80, ignored
2024/01/07 16:29:46 [warn] 213449#213449: conflicting server name "jp-gcp-vms.xyz" on 0.0.0.0:80, ignored
2024/01/07 16:29:46 [warn] 213449#213449: conflicting server name "www.jp-gcp-vms.xyz" on 0.0.0.0:80, ignored
2024/01/07 16:29:46 [notice] 213449#213449: signal process started
2024/01/07 16:32:53 [crit] 213450#213450: *1772 connect() to unix:/this/will/fail failed (2: No such file or directory) while connecting to upstream, client: 103.151.172.31, server: jp-gcp-vms.xyz, request: "GET /500 HTTP/1.1", upstream: "fastcgi://unix:/this/will/fail:", host: "jp-gcp-vms.xyz:8081"
2024/01/07 16:33:21 [error] 213450#213450: *1774 open() "/var/www/binaryville1/.env" failed (2: No such file or directory), client: 154.47.20.17, server: 34.39.2.90, request: "GET /.env HTTP/1.1", host: "34.39.2.90"
2024/01/07 16:34:15 [crit] 213450#213450: *1775 connect() to unix:/this/will/fail failed (2: No such file or directory) while connecting to upstream, client: 103.151.172.31, server: jp-gcp-vms.xyz, request: "GET /500 HTTP/1.1", upstream: "fastcgi://unix:/this/will/fail:", host: "jp-gcp-vms.xyz:8081"
2024/01/07 16:34:20 [crit] 213450#213450: *1775 connect() to unix:/this/will/fail failed (2: No such file or directory) while connecting to upstream, client: 103.151.172.31, server: jp-gcp-vms.xyz, request: "GET /500 HTTP/1.1", upstream: "fastcgi://unix:/this/will/fail:", host: "jp-gcp-vms.xyz:8081"
gateman@tf-vpc0-subnet0-main-server:/var/log/nginx$
这时我们直接访问
http://jp-gcp-vms.xyz:8081/50x.html
这时第2段的internal 生效了, 显示的是404页面而不是50x的页面
访问 50x.html -> 不允许外部访问 -> return 404 -> return 404.html
location 配置中一些通配符规则
这时, 配置文件的内容如下:
root@tf-vpc0-subnet0-main-server:/etc/nginx/conf.d# cat binaryville.conf
server {
listen 8081;
server_name jp-gcp-vms.xyz www.jp-gcp-vms.xyz;
index index.html index.htm index.php;
root /var/www/binaryville;
location / {
# First attempt to serve a request as a file, then as directory, then fall back to display a 404
try_files $uri $uri/ =404;
}
location /images {
# Allow the contents of /images folder to be listed
autoindex on;
try_files $uri $uri/ =504;
}
# specify the page to server for 404 errors
error_page 404 /404.html;
# an exact map location for the 404 page
location = /404.html {
# only for intenal requests
internal;
}
# specify the page to server for 50x errors
error_page 500 502 503 504 /50x.html;
# an exact map location for the 404 page
location = /50x.html {
# only for intenal requests
internal;
}
# a location to demostrated 500 errors
location /500 {
fastcgi_pass unix:/this/will/fail;
}
}
可以简单 location 的配置中有些有 = 号 有些没有
区别是什么呢
其实
location /500 这种写法代表perfix 匹配
下面的location 都是符合规则的
/500 /5001 /500/abc … 总之 500开头的都可以
location = /500 代表精确匹配
只有 /500 才能匹配
还是其他的匹配规则, 参考如下
modifier | Aplication to Location Definitions |
---|---|
None | prefix |
= | exact match |
~ | a case-senitive regular expression |
~* | a case-insensitive regular expression |
^~ | if the longest prefix maches then no regular expression is checked |
1 ~ 4 规则都很简单, 值得注意是最后1个
^~是Nginx配置中用于指定前缀匹配的特殊符号,可以与location块一起使用。
当^~前缀与location块一起使用时,它表示如果请求的URL以指定的前缀匹配,那么该location块将被选择用于处理请求,而不再继续寻找其他更具体的匹配。
下面是对^~符号的使用示例:
location ^~ /images/ {
# 处理以 /images/ 开头的请求
# ...
}
在上述示例中,当请求的URL以 /images/ 开头时,它将被匹配到该location块,并使用该块中的配置来处理请求。这个前缀匹配具有比通用的正则表达式匹配更高的优先级。