我有 Nginx 作为几个应用程序的反向代理运行。一个 location 指令运行正常,将请求发送到 unix 套接字文件,然后发送到其上游 wsgi 应用程序。我遇到问题的指令是location ~ ^/sub/alarm(.*)$
。我有几个重写似乎有效,但万一它们与我的其他意图相冲突,我将用每个指令解释我的意图:
- 第一个服务器指令应将所有 http 重定向到 https。这似乎工作正常。
- 第二个服务器指令有一个 location 指令,用于将流量导向我的 wsgi 应用程序。这很好用。另一个 location 指令我打算用来在
/home/myuser/alarm.example.com/
收到 GET 请求时提供静态内容example.net/sub/alarm
. (例如 example.net/sub/alarm/pretty.css 应该移交 /home/myuser/alarm.example.com/pretty.css)而是加载 wsgi 应用程序。 - 最后一个服务器指令应将 alarm.example.net 重定向到 example.net/sub/alarm,因为我没有通配符证书,但想要一个简单的快捷方式和加密。这似乎工作正常。
配置:
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name example.com www.example.com;
rewrite ^/(.*) https://example.com/$1 permanent;
}
server {
listen 443 ssl;
listen [::]:443 ipv6only=on ssl;
charset utf-8;
client_max_body_size 75M;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/example.com.sock;
}
location ~ ^/sub/alarm(.*)$ {
alias /home/appusername/alarm.example.com;
index index.html;
try_files $1 $1/;
}
}
server {
listen 80;
server_name alarm.example.com;
rewrite ^ $scheme://example.com/sub/alarm$request_uri permanent;
}
我在看如何从 nginx 配置中的 $uri 中删除位置块?尝试获取 uri 之后的位置文件部分。我想我遗漏了一些有关优先级的信息。
另一次尝试没有正则表达式:
location /sub/alarm/ {
alias /home/appusername/alarm.example.com;
index index.html;
try_files $uri $uri/index.html =404;
}
在上述情况下,我能够在访问 alarm.example.com 时加载 index.html(正确重定向到https://example.com/sub/alarm/),但所有资源都抛出了 404。
最后,我尝试将这两种尝试结合起来,但似乎无法将波浪号放在位置块内(重新加载 Nginx 时出现“未知指令”):
location /sub/alarm/ {
~ ^/sub/alarm(.)$
try_files /home/appusername/alarm.example.com$1 /home/appusername/alarm.example.com$1/;
}
补充笔记
- example.com 上的动态应用与静态的“闹钟”应用完全无关。之所以包含它,只是因为当我尝试正则表达式时,它代替闹钟应用获得服务。
- 我一直避免学习有关正则表达式的任何知识(可能不明智,但在过去 7 年里直到今天我都从未真正需要它),现在我正在配置 Nginx,为此付出了代价。我曾经正则表达式 101来获取我的正则表达式字符串
^\/sub\/alarm(.*)$
。它似乎表明我需要使用转义斜杠,但 Nginx 似乎没有在示例中显示这一点。如果我需要研究其他概念,请告诉我。从今天开始,我正式结束了我的正则表达式避免立场。 - 如果语法足够有效,可以让 Nginx 重新加载,那么我的错误就出
2015/10/12 20:25:57 [notice] 30500#0: signal process started
在所有尝试中。
答案1
因此用户(呃......我)错过了一些本应明显的线索:
在上述情况下,我能够在访问 alarm.example.com 时加载 index.html(正确重定向到 https://example.com/sub/alarm/),但所有资源都抛出了 404。
尽管这个例子仍然不正确,但我应该检查资源文件的文件权限。Nginx 以 www-data 身份运行,并且位于 index.html 文件的组中,但需要位于所有文件的组中。文件所有者是 appusername 用户。
此后,我添加了另一个应用程序(称为“啤酒”),其路由方式与警报类似。我现在已经学习了正则表达式的基础知识,并能够在一个位置块中做到这一点:
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name example.com www.example.com;
rewrite ^/(.*) https://example.com/$1 permanent;
}
server {
listen 443 ssl;
listen [::]:443 ipv6only=on ssl;
charset utf-8;
client_max_body_size 75M;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
error_log /var/log/nginx/error.log warn;
location ~ ^/sub/(alarm|beer)(.*)$ {
alias /home/appusername/$1.example.com/;
#index index.html index.htm;
try_files $2 $2/ =404;
}
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/example.com.sock;
}
}
server {
listen 80;
server_name alarm.example.com;
rewrite ^ $scheme://example.com/sub/alarm$request_uri permanent;
}
不要介意位置块的顺序切换。那只是打字和重新打字的巧合。