diff --git a/INSTALL.md b/INSTALL.md index 05ee4db4..7fb94666 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -63,3 +63,43 @@ and Docker Compose (version 1.6.0 or greater) already installed. # To stop user@host:szuru$ docker-compose down ``` + +### Additional Features + +1. **Using a seperate domain to host static files (image content)** + + If you want to host your website on, (`http://example.com/`) but want + to serve the images on a different domain, (`http://static.example.com/`) + then you can run the backend container with an additional environment + variable `DATA_URL=http://static.example.com/`. Make sure that this + additional host has access contents to the `/data` volume mounted in the + backend. + +2. **Setting a specific base URI for proxying** + + Some users may wish to access the service at a different base URI, such + as `http://example.com/szuru/`, commonly when sharing multiple HTTP + services on one domain using a reverse proxy. In this case, simply set + `BASE_URL="/szuru/"` in the frontend container, and + `DATA_URL="/szuru/data/"` in the backend container (unless you are hosting + your data on a different domain). + + You should set your reverse proxy to proxy `http(s)://example.com/szuru` to + `http:///`. For an NGINX + reverse proxy, that will appear as: + + ```nginx + location /szuru { + proxy_http_version 1.1; + proxy_pass http:///; + + proxy_set_header Host $http_host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Script-Name /szuru; + } + ``` diff --git a/client/Dockerfile b/client/Dockerfile index 49e0ab63..69555a4d 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -8,9 +8,10 @@ COPY . ./ ARG BUILD_INFO="docker-latest" ARG CLIENT_BUILD_ARGS="" -RUN node build.js ${CLIENT_BUILD_ARGS} +RUN BASE_URL="__BASEURL__" node build.js ${CLIENT_BUILD_ARGS} -RUN find public/ -type f -size +5k -print0 | xargs -0 -- gzip -6 -k +RUN find public/ -name public/index.html -prune -o -type f -size +5k \ + -print0 | xargs -0 -- gzip -6 -k FROM nginx:alpine @@ -21,6 +22,7 @@ RUN \ echo "#!/bin/sh" >> /init && \ echo 'sed -i "s|__BACKEND__|${BACKEND_HOST}|" /etc/nginx/nginx.conf' \ >> /init && \ + echo 'sed -i "s|__BASEURL__|${BASE_URL:-/}|" /var/www/index.htm' >> /init && \ echo 'exec nginx -g "daemon off;"' >> /init && \ chmod a+x /init diff --git a/client/build.js b/client/build.js index 23d54fa5..fdc5fd09 100644 --- a/client/build.js +++ b/client/build.js @@ -65,7 +65,10 @@ function bundleHtml() { const underscore = require('underscore'); const babelify = require('babelify'); const baseHtml = readTextFile('./html/index.htm', 'utf-8'); - writeFile('./public/index.htm', minifyHtml(baseHtml)); + const baseUrl = process.env.BASE_URL ? process.env.BASE_URL : '/'; + const finalHtml = baseHtml.replace( + '', ``); + writeFile('./public/index.htm', minifyHtml(finalHtml)); glob('./html/**/*.tpl', {}, (er, files) => { let compiledTemplateJs = '\'use strict\'\n'; diff --git a/client/html/index.htm b/client/html/index.htm index 2ebec1c4..00728903 100644 --- a/client/html/index.htm +++ b/client/html/index.htm @@ -9,7 +9,7 @@ Loading... - + diff --git a/client/js/router.js b/client/js/router.js index a8bd4c38..dd9b9e15 100644 --- a/client/js/router.js +++ b/client/js/router.js @@ -14,24 +14,29 @@ const clickEvent = document.ontouchstart ? 'touchstart' : 'click'; const uri = require('./util/uri.js'); let location = window.history.location || window.location; -const base = ''; +function _getOrigin() { + return location.protocol + '//' + location.hostname + + (location.port ? (':' + location.port) : ''); +} function _isSameOrigin(href) { - let origin = location.protocol + '//' + location.hostname; - if (location.port) { - origin += ':' + location.port; - } - return href && href.indexOf(origin) === 0; + return href && href.indexOf(_getOrigin()) === 0; +} + +function _getBaseHref() { + const bases = document.getElementsByTagName('base'); + return bases.length > 0 ? + bases[0].href.replace(_getOrigin(), '').replace(/\/+$/, '') : ''; } class Context { constructor(path, state) { - if (path[0] === '/' && path.indexOf(base) !== 0) { - path = base + path; - } + const base = _getBaseHref(); + path = path.indexOf('/') !== 0 ? '/' + path : path; + path = path.indexOf(base) !== 0 ? base + path : path; this.canonicalPath = path; - this.path = path.replace(base, '') || '/'; + this.path = !path.indexOf(base) ? path.slice(base.length) : path; this.title = document.title; this.state = state || {}; @@ -289,15 +294,14 @@ const _onClick = router => { return; } - let path = el.pathname + el.search + (el.hash || ''); + const base = _getBaseHref(); + const orig = el.pathname + el.search + (el.hash || ''); + const path = !orig.indexOf(base) ? orig.slice(base.length) : orig; - const orig = path; - if (path.indexOf(base) === 0) { - path = path.substr(base.length); - } if (base && orig === path) { return; } + e.preventDefault(); router.show(orig); };