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.