我有一个在 Ubuntu 16.04.2 LTS
上运行的 nginx 版本:nginx/1.10.3 (Ubuntu)
。
我使用 nginx
来提供静态文件、由 webpack
生成的包,但这无关紧要。
我想要实现的是:
在 example.com
上,我想提供 /home/bundles/main/index.html
。我能做到。
在 projects.example.com/project_1
上,我想提供 /home/bundles/project_1/index.html
。
在 projects.example.com/project_2
上,我想提供 /home/bundles/project_2/index.html
。
最后两个我做不到。当我访问 projects.example.com/project_1
或 projects.example.com/project_2
时,我会看到默认的 nginx 页面。
为了让事情变得更加困惑,/etc/nginx/sites-enabled/default
被完全注释掉了。
此外,如果在 projects.example.com
的 location
block 中,我将 project_1
替换为 /
,我将为该特定项目提供服务,但随后我将无法为其他项目提供服务。
下面,我将向您展示我的 nginx 配置
server {
listen 80;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
server {
listen 80;
server_name projects.example.com;
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
location /project_2 {
root /home/bundles/project_2;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name projects.example.com;
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
location /project_2 {
root /home/bundles/project_2;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
感谢您的帮助!
编辑
我的回答
我找到的解决方案是用alias
更改root
。
server {
listen 80;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
server {
listen 80;
server_name projects.example.com;
location /project_1 {
alias /home/bundles/project_1;
index index.html;
}
location /project_2 {
alias /home/bundles/project_2;
index index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name projects.example.com;
location /project_1 {
alias /home/bundles/project_1;
index index.html;
}
location /project_2 {
alias /home/bundles/project_2;
index index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
解决方案基于这两个答案。第一个answer展示如何解决第二个问题 answer解释为什么 alias
有效而 root
无效。
引用@treecoder
In case of the root directive, full path is appended to the root including the location part, whereas in case of the alias directive, only the portion of the path NOT including the location part is appended to the alias.
在我的具体情况下,这将像这样翻译;
使用 root
时,nginx
尝试访问的路径将为 /home/bundles/project_1/project_1
。
使用alias
可以访问正确的路径,/home/bundles/project_1
。
返回上一级,例如说:
root/home/bundles/
也不是真正的选择。这是因为我的项目实际上并不名为 project_1
和 project_2
。实际结构与此更相似。
在 /bundles
中,我有目录 project_a
和 project_b
。我想将 project_1
路由到 project_a
目录,并将 project_2
路由到 project_b
目录。
这就是我使用别名
的原因。
我希望这会有所帮助。
最佳答案
你有:
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
因此 root
仅为以 /project_1
开头的 URI 定义。对于任何其他 URI,将使用默认的 root
。
如果您提供 URI /project_1/
(带有尾部 /
),假设 default index
directive生效后,nginx
应返回您的 /project_1/index.html
内容。
但是,找不到 URI /project_1
- 因此返回 /index.html
。 URI /index.html
不以 /project_1
开头,因此使用默认根。
如果您希望 URI /project_1
按预期工作,并且默认操作转到项目的 index.html
文件,请更改 try_files
指令。
location /project_1 {
root /home/bundles/project_1;
try_files $uri $uri/ /project_1/index.html;
}
参见this document了解更多。
由于两个项目共享一个共同的根,您可以按如下方式简化:
server {
listen 80;
server_name projects.example.com;
root /home/bundles
index index.html;
location /project_1 {
try_files $uri $uri/ /project_1/index.html;
}
location /project_2 {
try_files $uri $uri/ /project_2/index.html;
}
location / {
deny all;
}
}
我添加了 index
指令以避免依赖默认值(相同),并添加了 location
block 来拒绝访问项目外部的区域。
关于Nginx 正在提供默认内容而不是我的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48688492/