Support runtime BASE_URL via environment variable (no image rebuild required)
#403 opened on Jun 6, 2026
Repository metrics
- Stars
- (1,369 stars)
- PR merge metrics
- (Avg merge 10d 22h) (8 merged PRs in 30d)
Description
What type of request is this?
Self-hosting improvement
Clear and concise description of the feature you are proposing
Clear and concise description of the feature you are proposing
Currently, BASE_URL is a build argument (ARG BASE_URL) in the Dockerfile. This means the subpath is baked into the static assets at image build time, users who want to deploy IT-Tools under a subpath (e.g. /it-tools/) must rebuild the Docker image themselves. Pulling the official image from GHCR and setting a runtime environment variable does not work.
The goal is to make BASE_URL a runtime environment variable so that the official image can be deployed under any subpath without rebuilding:
# docker-compose.yml
services:
it-tools:
image: ghcr.io/sharevb/it-tools:latest
environment:
BASE_URL: /it-tools/ # no rebuild needed
There are two blockers preventing this today:
1. BASE_URL is a Vite build arg — assets paths are hardcoded at build time
Vite uses BASE_URL to generate absolute asset paths in the bundle:
<script src="/it-tools/assets/index-abc123.js"></script>
These paths cannot be changed after the build without a rebuild.
The fix is to build Vite with base: "./" (relative paths) so assets resolve correctly regardless of the subpath at runtime:
// vite.config.ts
const baseUrl = process.env.BASE_URL || './';
base: baseUrl,
Since Vue Router already uses createWebHistory(config.app.baseUrl) and config.app.baseUrl reads from import.meta.env.BASE_URL, the router will continue to work correctly with this change.
2. nginx.conf has a hardcoded rewrite for /it-tools/
The current nginx.conf contains:
location / {
rewrite ^/it-tools/(.*) /$1 break;
try_files $uri $uri/ /index.html;
}
This rewrite is hardcoded and only works for /it-tools/. It should be replaced with a dynamic location block using ${BASE_URL} via envsubst (already supported by nginxinc/nginx-unprivileged through the /etc/nginx/templates/ mechanism):
# nginx.conf — default.conf.template
server {
listen ${PORT};
listen [::]:${PORT};
server_name _;
root /usr/share/nginx/html;
index index.html;
include /etc/nginx/mime.types;
types {
application/javascript js mjs;
}
location ${BASE_URL} {
try_files $uri $uri/ /index.html;
}
}
With BASE_URL defaulting to /, behavior is identical to today for existing deployments, no regression.
Is there example of this tool in the wild?
This pattern is used by several self-hosted tools:
- Gitea: ROOT_URL env var controls the subpath at runtime
- Grafana: GF_SERVER_ROOT_URL env var, no rebuild needed
Additional context
Source inspection confirms nginx.conf is already a template processed by envsubst (via default.conf.template), only the hardcoded /it-tools/ rewrite and the Vite base option need updating Default behavior (BASE_URL unset) must remain identical to today, this is a purely additive change
Validations
- Check the feature is not already implemented in the project.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
- Check that the feature can be implemented in a client side only app (IT-Tools is client side only, no server).
- Everything is written in PLAIN ENGLISH