Score:0

Configuring NGINX with proxy_pass set up on a subdirectory pointing to a docker server, and ensuring relative URLs (.js, .css) resolve

ky flag

I have nginx 1.14.0 running on Ubuntu 18.04 server. On that server, I'm attempting to self-host many different applications. My goal is to have each location exist at a subdirectory of my url, server.calebjay.com.

For example, right now I'd like to set up pigallery2 to be available at server.calebjay.com/photos. To do so, I have a docker instance serving on port 800, and I have nginx proxying to it. This partially works, insomuch as index.html loads.

However, relative urls, such as script src, aren't resolving, I believe because they're formed like main.js instead of /photos/main.js.

To test, I can GET https://server.calebjay.com/photos, and resolve an index.html. I get 404s for a lot of .js and .css files. Confirming, if I grab those relative URLs, and do https://server.calebjay.com/photos/main-asdfasdf.js, I still get a 404, {server-ip-address}/photos/main-asdf.js and https://server.calebjay.com/photos/main-asdf.js both properly return the given JS file.

There are many answers regarding this, however none have worked for me.

My baseline nginx config:

/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/*;
}

For the subdomain and single docker server to which I'm proxying for now:

/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;
  }

Each of the commented out portions are separate experiments I've tried from various places on the stack network:

Neither rewrite based on http-referrer worked, though one image did resolve as a result.

Having an explicit rule for images nor adding a mime-type header worked.

Answers regarding static content and try_files didn't work, nor should they I believe, as I'm proxying to a server.

Replacing links using sub_filter didn't work.

Setting location as /photos instead of /photos/ didn't work.

I don't have access to the docker internals, so can't modify the html directly.

How can I get my hrefs to resolve against the proper domain, with the subdirectory of /photos/?

(I did restart nginx after every config change)

Further details:

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

EDIT: Ah, it appears that the http_referer rewrite solution works in loading js, css, etc, but then the JS application changes the client URL on the client-side, without issuing a request, to server.calebjay.com/, thus causing my browser to show server.calebjay.com/login, thus causing future requests to miss the http_referer. It may be impossible to fix this, as I'm not aware of any way to force javascript to rewrite URLs based on a subdirectory. I may be forced to simply have all my applications on separate subdomains, unless the given application happens to take a subdirectory config.

Score:0
us flag

You need to configure your application's base URL properly, so that it creates proper URLs that match your setup.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.