sharevb/it-tools

Support runtime BASE_URL via environment variable (no image rebuild required)

Offen

#403 geöffnet am 06.06.2026

 (3 Kommentare) (1 Reaktion) (0 zugewiesene Personen)Vue (127 Forks)user submission
enhancementhelp wanted

Repository-Metriken

Stars
 (1.369 Sterne)
PR-Merge-Metriken
 (Durchschn. Merge 10T 22h) (8 gemergte PRs in 30 T)

Beschreibung

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

Contributor Guide