sharevb/it-tools

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

Open

#403 opened on Jun 6, 2026

View on GitHub
 (3 comments) (1 reaction) (0 assignees)Vue (127 forks)user submission
enhancementhelp wanted

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

Contributor guide