【问题标题】:nginx with Etherpad in a subdirectory带有 Etherpad 的 nginx 在子目录中
【发布时间】:2022-01-21 02:21:06
【问题描述】:

我正在 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 问题和 SE 中还有一些关于这个主题的其他问题,但总的来说,它们是通过从 etherpad 迁移到 etherpad-lite 来解决的...

【问题讨论】:

    标签: amazon-web-services nginx etherpad


    【解决方案1】:

    简短回答:如果您在前缀位置添加斜杠,一切都会按预期工作。

    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 也可以工作,如果您无法通过上述配置获得从/etherpad/etherpad/ 的 HTTP 301 重定向,请添加以下位置:

        location = /etherpad {
            return 301 /etherpad/;
        }
    

    对我来说这不是必需的,但它可能取决于您的服务器环境。

    要保留查询字符串(如果有),您可以改用return 301 /etherpad/$is_args$args;rewrite ^ /etherpad/ permanent


    长答案(以及秘密发生的事情)。

    关于 “我如何在 URI 前缀下托管 web 应用程序”有很多问题Here 是我的答案之一,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 前缀,并在其前面加上该斜杠(或在 proxy_pass 中使用的任何其他 URI上游名称后的指令)导致//<path>。您可以阅读A little confused about trailing slash behavior in nginxnginx and trailing slash with proxy pass SO 线程了解更多详细信息。无论如何,etherpad 不会为您提供 Cannot GET //<path> 错误的 URI。

    location /etherpad { ... } 更改为location /etherpad/ { ... } 您将解决上述两个问题。


    简单介绍一下 etherpad wiki 示例,尤其是 this one

    两者

    location /etherpad/ {
        proxy_pass http://127.0.0.1/;
        ...
    }
    

    location /etherpad/ {
        rewrite ^/etherpad(/.*) $1 break;
        proxy_pass http://127.0.0.1;
        ...
    }
    

    执行相同的字符串 - 从请求 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(/.*) $1 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,因为在 /path/to/etherpad/src/static/ 目录下将不存在相应的资产。尽管已经定义了对 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(/.*) $1 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(/.*) $1 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;
    

    以及答案开头提到的其他可选标题(X-Real-IPX-Forwarded-ForX-Forwarded-Proto)设置,可以用作单独的文件,例如etherpad-proxy.conf,并使用 include 指令包含在主 nginx 配置中。

    【讨论】:

      【解决方案2】:

      您可以尝试将静态内容导航到正确的文件夹:

      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

      【讨论】:

      • 我认为这是一种明智的方法 - 但我只是迷失在它不太工作的迷宫中......
      • 您的应用程序正在根目录中查找 /static/,而没有 /etherpad/。我只是建议将其重新路由到正确的位置。你迷失了什么?
      猜你喜欢
      • 2016-06-20
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多