子目录中带有 Etherpad 的 nginx
nginx with Etherpad in a subdirectory
我正在 this location.
的子目录中设置 etherpad-lite
很遗憾,'static' 中的文件未加载:
很明显我的 nginx 中发生了一些事情,(部分)看起来像这样:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name _
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name www.whitewaterwriters.com;
ssl_certificate /etc/letsencrypt/live/www.whitewaterwriters.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.whitewaterwriters.com/privkey.pem;
return 301 https://whitewaterwriters.com$request_uri;
}
server {
listen 443 ssl;
server_name whitewaterwriters.com;
ssl_certificate /etc/letsencrypt/live/whitewaterwriters.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/whitewaterwriters.com/privkey.pem;
root /usr/share/nginx/html;
index index.html index.php;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~/watchtower/.*/live/pdfs/ {
autoindex on;
}
location /watchtower {
root /usr/share/nginx/html/;
}
location /etherpad {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_read_timeout 300;
proxy_pass http://localhost:9001/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /{
root /usr/share/nginx/html/whitewaterwriters-site/_site/;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
我的问题是:如何配置 nginx 才能显示丢失的文件?
在 github issues 和 SE 中还有一些关于这个主题的其他问题,但一般来说,它们是通过从 etherpad 转移到 etherpad-lite 来解决的,我已经在使用它,或者两者都是未回答且接近十年...
您可以尝试将静态内容导航到正确的文件夹:
location /static {
root root /usr/share/nginx/html/whitewaterwriters-site/_site/static;
}
# or something like:
location /etherpad/static {
root root /usr/share/nginx/html/whitewaterwriters-site/_site/;
}
因为这是有效的:https://whitewaterwriters.com/etherpad/static/js/vendors/html10n.js?v=869d568c
简短回答:如果您在前缀位置添加尾部斜杠,一切都会按预期进行。
map $http_upgrade $connection_upgrade {
'' close;
default upgrade;
}
server {
...
location /etherpad/ {
proxy_buffering off; # recommended by etherpad nginx hosting examples
proxy_set_header Host $host;
# optional headers
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP
proxy_set_header X-Forwarded-Proto $scheme; # for EP to set secure cookie flag when https is used
# recommended with keepalive connections
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# upstream
proxy_pass http://127.0.0.1:9001/;
}
}
如果您希望 /etherpad
URI 也能正常工作,如果您无法使用上述配置将 HTTP 301 重定向到 /etherpad
到 /etherpad/
,请添加以下位置:
location = /etherpad {
return 301 /etherpad/;
}
对我来说没有必要,但这取决于您的服务器环境。
要保留查询字符串(如果有),您可以使用 return 301 /etherpad/$is_args$args;
或 rewrite ^ /etherpad/ permanent
。
长答案(以及卧底发生的事情)。
SO 上有很多关于 “我如何在 URI 前缀下托管 Web 应用程序”的问题。 Here is one on my answers and here 是关于类似主题的 ServerFault 线程。
唯一正确的方法是让您的代理应用仅通过相对 URI 请求其资产(考虑 assets/script.js
而不是 /assets/script.js
)或使用正确的 URI前缀 (/etherpad/assets/script.js
).
幸运的是,etherpad 使用相对路径(例如 <script src="static/js/index.js"></script>
)请求其资产,使其适合在任何 URI 前缀下托管。问题是,当你的原始 URI 是 /etherpad
时,浏览器将当前远程 Web 服务器目录视为根目录,并从服务器请求上述脚本作为 scheme://domain/static/js/index.js
。该请求甚至不会被您的 location /etherpad { ... }
捕获(因为它不是以 /etherpad
开头)。另一方面,当您的源 URI 是 /etherpad/
时,浏览器将当前远程 Web 服务器目录视为 /etherpad/
并正确地从服务器请求上述脚本 scheme://domain/etherpad/static/js/index.js
.
现在让我们看看使用您的原始配置代理请求 /etherpad/<path>
发生了什么。由于您在上游地址 (http://localhost
+ /
) 后使用尾部斜杠,nginx 从请求 URI 中删除位置 /etherpad
前缀,并在其前面加上该斜杠(或任何其他 URI)在上游名称后的 proxy_pass
指令中使用)导致 //<path>
。您可以阅读 A little confused about trailing slash behavior in nginx or nginx and trailing slash with proxy pass SO 线程以了解更多详细信息。无论如何,Etherpad 不会提供 URI 给你 Cannot GET //<path>
错误。
将 location /etherpad { ... }
更改为 location /etherpad/ { ... }
您将解决上述两个问题。
关于 etherpad 的几句话 wiki examples, especially this one。
两者
location /etherpad/ {
proxy_pass http://127.0.0.1/;
...
}
和
location /etherpad/ {
rewrite ^/etherpad(/.*) break;
proxy_pass http://127.0.0.1;
...
}
执行相同的字符串 - 在将请求 URI 传递给上游之前从请求 URI 中剥离 /etherpad
前缀。然而,第一个以更有效的方式做到这一点。最好尽可能避免使用正则表达式。使用
location = /etherpad {
return 301 /etherpad/;
}
也比
更有效率
rewrite ^/etherpad$ /etherpad/ permanent;
上述 wiki 示例中的第二个和第三个位置块完全重复了第一个的功能。此外,该示例破坏了 WebSocket support(无论是谁编写的,他至少可以将该支持添加到 location /pad/socket.io { ... }
块)。
永远不要做 this 示例中使用的事情:
location ~ ^/$ { ... }
改为使用完全匹配的位置:
location = / { ... }
这是我测试过的另一种配置,目的是检查我是否可以直接通过 nginx 提供 etherpad 静态资产。它似乎是可行的,尽管我没有对其进行大量测试。它使用未压缩的 js/css 资产版本(当您使用 gzip 或其他一些压缩时,这应该不会影响性能)。这也是一个很好的配置示例,您无法避免使用 rewrite
指令从请求 URI 中去除前缀。
location /etherpad/static/ {
# trying to serve assets directly via nginx
# if the asset is not found, pass the request to the nodejs upstream
rewrite ^/etherpad(/.*) break;
root /full/path/to/etherpad-lite/src;
try_files $uri @etherpad;
}
location /etherpad/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/;
}
location @etherpad {
proxy_redirect / /etherpad/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001;
}
更新
作为 GitHub 上的 suggested,以 /etherpad/static/plugins/
前缀开头的 URI 应始终传递给 nodejs 上游,因为 [=51] 下不存在相应的资产=] 目录。尽管已经定义了回退到 nodejs 上游(try_files $uri @etherpad
),为了消除由 try_files
指令产生的额外 stat
系统调用,我们可以将上面的配置修改为:
location ~ ^/etherpad/static/(?!plugins/) {
# trying to serve assets directly via nginx
# if the asset is not found, pass the request to the nodejs upstream
rewrite ^/etherpad(/.*) break;
root /full/path/to/etherpad-lite/src;
try_files $uri @etherpad;
}
location /etherpad/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/;
}
location @etherpad {
proxy_redirect / /etherpad/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001;
}
(使用负前瞻性正则表达式,更好的可读性)或这个:
location /etherpad/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/;
}
location /etherpad/static/ {
rewrite ^/etherpad(/.*) break;
root /full/path/to/etherpad-lite/src;
try_files $uri @etherpad;
}
location /etherpad/static/plugins/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/static/plugins/;
}
location @etherpad {
proxy_redirect / /etherpad/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001;
}
(仅前缀位置,性能更好)。重复部分
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
可能还有其他可选的 headers (X-Real-IP
, X-Forwarded-For
, X-Forwarded-Proto
) 答案开头提到的设置,可以用作单独的文件,例如etherpad-proxy.conf
,并使用 include
指令包含在主 nginx 配置中。
我正在 this location.
的子目录中设置 etherpad-lite很遗憾,'static' 中的文件未加载:
很明显我的 nginx 中发生了一些事情,(部分)看起来像这样:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name _
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name www.whitewaterwriters.com;
ssl_certificate /etc/letsencrypt/live/www.whitewaterwriters.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.whitewaterwriters.com/privkey.pem;
return 301 https://whitewaterwriters.com$request_uri;
}
server {
listen 443 ssl;
server_name whitewaterwriters.com;
ssl_certificate /etc/letsencrypt/live/whitewaterwriters.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/whitewaterwriters.com/privkey.pem;
root /usr/share/nginx/html;
index index.html index.php;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~/watchtower/.*/live/pdfs/ {
autoindex on;
}
location /watchtower {
root /usr/share/nginx/html/;
}
location /etherpad {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_read_timeout 300;
proxy_pass http://localhost:9001/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /{
root /usr/share/nginx/html/whitewaterwriters-site/_site/;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
我的问题是:如何配置 nginx 才能显示丢失的文件?
在 github issues 和 SE 中还有一些关于这个主题的其他问题,但一般来说,它们是通过从 etherpad 转移到 etherpad-lite 来解决的,我已经在使用它,或者两者都是未回答且接近十年...
您可以尝试将静态内容导航到正确的文件夹:
location /static {
root root /usr/share/nginx/html/whitewaterwriters-site/_site/static;
}
# or something like:
location /etherpad/static {
root root /usr/share/nginx/html/whitewaterwriters-site/_site/;
}
因为这是有效的:https://whitewaterwriters.com/etherpad/static/js/vendors/html10n.js?v=869d568c
简短回答:如果您在前缀位置添加尾部斜杠,一切都会按预期进行。
map $http_upgrade $connection_upgrade {
'' close;
default upgrade;
}
server {
...
location /etherpad/ {
proxy_buffering off; # recommended by etherpad nginx hosting examples
proxy_set_header Host $host;
# optional headers
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP
proxy_set_header X-Forwarded-Proto $scheme; # for EP to set secure cookie flag when https is used
# recommended with keepalive connections
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# upstream
proxy_pass http://127.0.0.1:9001/;
}
}
如果您希望 /etherpad
URI 也能正常工作,如果您无法使用上述配置将 HTTP 301 重定向到 /etherpad
到 /etherpad/
,请添加以下位置:
location = /etherpad {
return 301 /etherpad/;
}
对我来说没有必要,但这取决于您的服务器环境。
要保留查询字符串(如果有),您可以使用 return 301 /etherpad/$is_args$args;
或 rewrite ^ /etherpad/ permanent
。
长答案(以及卧底发生的事情)。
SO 上有很多关于 “我如何在 URI 前缀下托管 Web 应用程序”的问题。 Here is one on my answers and here 是关于类似主题的 ServerFault 线程。
唯一正确的方法是让您的代理应用仅通过相对 URI 请求其资产(考虑 assets/script.js
而不是 /assets/script.js
)或使用正确的 URI前缀 (/etherpad/assets/script.js
).
幸运的是,etherpad 使用相对路径(例如 <script src="static/js/index.js"></script>
)请求其资产,使其适合在任何 URI 前缀下托管。问题是,当你的原始 URI 是 /etherpad
时,浏览器将当前远程 Web 服务器目录视为根目录,并从服务器请求上述脚本作为 scheme://domain/static/js/index.js
。该请求甚至不会被您的 location /etherpad { ... }
捕获(因为它不是以 /etherpad
开头)。另一方面,当您的源 URI 是 /etherpad/
时,浏览器将当前远程 Web 服务器目录视为 /etherpad/
并正确地从服务器请求上述脚本 scheme://domain/etherpad/static/js/index.js
.
现在让我们看看使用您的原始配置代理请求 /etherpad/<path>
发生了什么。由于您在上游地址 (http://localhost
+ /
) 后使用尾部斜杠,nginx 从请求 URI 中删除位置 /etherpad
前缀,并在其前面加上该斜杠(或任何其他 URI)在上游名称后的 proxy_pass
指令中使用)导致 //<path>
。您可以阅读 A little confused about trailing slash behavior in nginx or nginx and trailing slash with proxy pass SO 线程以了解更多详细信息。无论如何,Etherpad 不会提供 URI 给你 Cannot GET //<path>
错误。
将 location /etherpad { ... }
更改为 location /etherpad/ { ... }
您将解决上述两个问题。
关于 etherpad 的几句话 wiki examples, especially this one。
两者
location /etherpad/ {
proxy_pass http://127.0.0.1/;
...
}
和
location /etherpad/ {
rewrite ^/etherpad(/.*) break;
proxy_pass http://127.0.0.1;
...
}
执行相同的字符串 - 在将请求 URI 传递给上游之前从请求 URI 中剥离 /etherpad
前缀。然而,第一个以更有效的方式做到这一点。最好尽可能避免使用正则表达式。使用
location = /etherpad {
return 301 /etherpad/;
}
也比
更有效率rewrite ^/etherpad$ /etherpad/ permanent;
上述 wiki 示例中的第二个和第三个位置块完全重复了第一个的功能。此外,该示例破坏了 WebSocket support(无论是谁编写的,他至少可以将该支持添加到 location /pad/socket.io { ... }
块)。
永远不要做 this 示例中使用的事情:
location ~ ^/$ { ... }
改为使用完全匹配的位置:
location = / { ... }
这是我测试过的另一种配置,目的是检查我是否可以直接通过 nginx 提供 etherpad 静态资产。它似乎是可行的,尽管我没有对其进行大量测试。它使用未压缩的 js/css 资产版本(当您使用 gzip 或其他一些压缩时,这应该不会影响性能)。这也是一个很好的配置示例,您无法避免使用 rewrite
指令从请求 URI 中去除前缀。
location /etherpad/static/ {
# trying to serve assets directly via nginx
# if the asset is not found, pass the request to the nodejs upstream
rewrite ^/etherpad(/.*) break;
root /full/path/to/etherpad-lite/src;
try_files $uri @etherpad;
}
location /etherpad/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/;
}
location @etherpad {
proxy_redirect / /etherpad/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001;
}
更新
作为 GitHub 上的 suggested,以 /etherpad/static/plugins/
前缀开头的 URI 应始终传递给 nodejs 上游,因为 [=51] 下不存在相应的资产=] 目录。尽管已经定义了回退到 nodejs 上游(try_files $uri @etherpad
),为了消除由 try_files
指令产生的额外 stat
系统调用,我们可以将上面的配置修改为:
location ~ ^/etherpad/static/(?!plugins/) {
# trying to serve assets directly via nginx
# if the asset is not found, pass the request to the nodejs upstream
rewrite ^/etherpad(/.*) break;
root /full/path/to/etherpad-lite/src;
try_files $uri @etherpad;
}
location /etherpad/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/;
}
location @etherpad {
proxy_redirect / /etherpad/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001;
}
(使用负前瞻性正则表达式,更好的可读性)或这个:
location /etherpad/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/;
}
location /etherpad/static/ {
rewrite ^/etherpad(/.*) break;
root /full/path/to/etherpad-lite/src;
try_files $uri @etherpad;
}
location /etherpad/static/plugins/ {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001/static/plugins/;
}
location @etherpad {
proxy_redirect / /etherpad/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9001;
}
(仅前缀位置,性能更好)。重复部分
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
可能还有其他可选的 headers (X-Real-IP
, X-Forwarded-For
, X-Forwarded-Proto
) 答案开头提到的设置,可以用作单独的文件,例如etherpad-proxy.conf
,并使用 include
指令包含在主 nginx 配置中。