配置 NGINX 并在指向 Docker 服务器的子目录中设置 proxy_pass,并确保相对 URL(.js、.css)能够解析

配置 NGINX 并在指向 Docker 服务器的子目录中设置 proxy_pass,并确保相对 URL(.js、.css)能够解析

我在 Ubuntu 18.04 服务器上运行 nginx 1.14.0。在该服务器上,我尝试自行托管许多不同的应用程序。我的目标是让每个位置都存在于我的 URL server.calebjay.com 的子目录中。

例如,现在我想设置pigallery2可在 上使用server.calebjay.com/photos。为此,我有一个在端口 800 上服务的 docker 实例,并且我已nginx代理到它。这部分有效,因为index.html负载很大。

但是,相对 URL(例如script src)无法解析,我相信这是因为它们的格式是main.js而不是/photos/main.js

为了测试,我可以GET https://server.calebjay.com/photos,并解析index.html。很多 .js 和 .css 文件都会出现 404 错误。确认一下,如果我抓取这些相对 URL,并执行https://server.calebjay.com/photos/main-asdfasdf.js,我仍然会得到 404 错误,{server-ip-address}/photos/main-asdf.js并且https://server.calebjay.com/photos/main-asdf.js两者都正确返回了给定的 JS 文件。

关于这个问题有很多答案,但没有一个对我有用。

我的基本 nginx 配置:

/etc/nginx/nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
}

http {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        gzip on;

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

对于我现在代理的子域和单个docker服务器:

/etc/nginx/sites-available/server.calebjay.com.conf

   server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name server.calebjay.com www.server.calebjay.com;
        return 301 https://$server_name$request_uri;
  }

  server {
    server_name server.calebjay.com; 

    gzip on;


#location ~ \.css {
#    add_header  Content-Type    text/css;
#}
#location ~ \.js {
#    add_header  Content-Type    application/x-javascript;
#}

#location / {
 # if ($http_referer ~ "^https?://[^/]+/photos/") {
 #     rewrite ^/(.*) https://$http_host/photos/$1 redirect;
 # }
#    if ($http_referer = "https://server.calebjay.com/photos/") {
#        rewrite ^/(.*) https://server.calebjay.com/photos/$1 redirect;
#    }
#}

   location /photos/ {
    # rewrite ^/photos(/.*)$ $1 break;
      proxy_pass http://localhost:800/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
     # sub_filter "<head>" "<head><base href=\"${scheme}://${host}/photos\">";
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;
    }


    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    ssl_certificate /etc/letsencrypt/live/server.calebjay.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/server.calebjay.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
  }

每个注释掉的部分都是我在堆栈网络的各个位置尝试过的单独实验:

两者都不 rewrite基于http-referrer工作,尽管结果确实解决了一个图像。

对图像有明确的规则也不添加 mime 类型标头工作了。

关于静态内容的解答并且 try_files 不起作用,我相信它们也不应该起作用,因为我正在代理到服务器。

使用 sub_filter 替换链接没有用。

环境 location/photos不是/photos/不起作用。

我无法访问 docker 内部,因此无法直接修改 html。

我怎样才能让我的hrefs域名和子目录解析/photos/

(每次配置更改后我都会重新启动 nginx)

更多细节:

nginx -V

nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.1  11 Sep 2018
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-H4cN7P/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

编辑:啊,看来该http_referer rewrite解决方案在加载 js、css 等时有效,但随后 JS 应用程序在客户端将客户端 URL 更改为 ,而无需发出请求,从而server.calebjay.com/导致我的浏览器显示server.calebjay.com/login,从而导致将来的请求错过http_referer。可能无法修复此问题,因为我不知道有任何方法可以强制 javascript 根据子目录重写 URL。我可能被迫将所有应用程序放在单独的子域中,除非给定的应用程序恰好采用子目录配置。

答案1

您需要正确配置应用程序的基本 URL,以便它创建与您的设置相匹配的正确 URL。

相关内容