DependencyTrack / DependencyTrack/dependency-track
BASE_PATH misconfiguration: outdated docs, nginx doesn't strip prefix, API requires manual path rewrite at gateway level
- Dominant language
- Java
- Stars
- 4.2k
- Forks
- 811
- Avg merge
- 8h 39m
- Merged PRs (30d)
- 237
Description
### Current Behavior
Deploying the frontend behind a reverse proxy (tested with NGINX Gateway Fabric / Kubernetes Gateway API) with `BASE_PATH=/dependency-track` results in a broken application: all CSS/JS assets return the HTML index page instead of static files.
Three issues were identified:
#### 1. Documentation says `BASE_PATH` should not end with `/`
From [the official docs](https://docs.dependencytrack.org/getting-started/configuration/#base-path):
> For example, if the frontend is served from `https://example.com/dependency-track`, you would set `BASE_PATH` to `/dependency-track`.
Setting `BASE_PATH=/dependency-track` (no trailing slash) causes the `` HTML tag to be rendered as:
```html
```
A base URI without a trailing slash means relative URLs **replace the last path segment**, not append to it:
```
/dependency-track + css/app.abc123.css => /css/app.abc123.css (404)
```
The correct value is `BASE_PATH=/dependency-track/` (with trailing slash), which produces:
```html
```
```
/dependency-track/ + css/app.abc123.css => /dependency-track/css/app.abc123.css (200)
```
#### 2. The nginx config inside the frontend container does not strip `BASE_PATH` before `try_files`
The current nginx template in the container is:
```nginx
location / {
root /opt/owasp/dependency-track-frontend;
try_files $uri $uri/ /index.html;
...
}
```
Even when `BASE_PATH` is correctly set with a trailing slash, the reverse proxy forwards requests like `GET /dependency-track/css/app.abc123.css` to the container. Nginx then looks for the file at:
```
/opt/owasp/dependency-track-frontend/dependency-track/css/app.abc123.css
```
This path does not exist. The actual file is at:
```
/opt/owasp/dependency-track-frontend/css/app.abc123.css
```
So `try_files` always falls through to `index.html`, returning HTML with `Content-Type: text/html` for every asset request.
The nginx config could use `alias` and match on `BASE_PATH`:
```nginx
location /dependency-track/ { # Should use BASE_PATH in the template
alias /opt/owasp/dependency-track-frontend/;
try_files $uri $uri/ /dependency-track/index.html;
...
}
```
This forces the operator to perform a `URLRewrite` / `ProxyPass` rewrite at the reverse proxy level. This should be handled internally by the container.
#### 3. Undocumented `CONTEXT` variable for the API server, inconsistent behavior and broken healthcheck
The API server has an undocumented environment variable `CONTEXT` that is supposed to configure the base path (e.g. `CONTEXT=/dependency-track/api`). I haven't found this variable in the [official configuration documentation](https://docs.dependencytrack.org/getting-started/configuration/).
When `CONTEXT` is set, the API server returns `405 Method Not Allowed` on routes that should be valid, even though the URL path is correct. The root cause is unclear, but the server misbehaves with `CONTEXT` set and works normally without it.
Additionally, the Dockerfile healthcheck appears to assume `CONTEXT` ends with a trailing `/`:
```dockerfile
# Implicit assumption: CONTEXT ends with /
HEALTHCHECK ... curl ... ${CONTEXT}health
```
**Workaround applied:** remove `CONTEXT` entirely (not documented anyway) and rewrite the path prefix at the gateway level:
```yaml
# Kubernetes Gateway API
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /api # the gateway/reverse proxy handles /dependecy-track/api but forward /api to the backend container
matches:
- path:
type: PathPrefix
value: /dependency-track/api
```
This should not be the operator's responsibility.
**Expected behavior:**
- `CONTEXT` should be documented, or removed in favor of a properly documented alternative.
- If `CONTEXT` is kept, the server must not return `405` on valid routes when it is set.
- The Dockerfile healthcheck should be robust to both `/dependency-track/api` and `/dependency-track/api/` (guard against missing trailing slash).
- The API server should natively serve its routes under the configured context path/base url without requiring gateway-level URL rewriting.
### Steps to Reproduce
1. Deploy the frontend container image with `BASE_PATH=/dependency-track` (as documented).
2. Place it behind any reverse proxy passing the full path to the container (standard behavior for most proxies and Kubernetes Gateway API).
3. Navigate to the application - the UI fails to load (blank page / console errors showing CSS/JS assets returning HTML).
4. Even after correcting `BASE_PATH` to `/dependency-track/` (with trailing slash), assets still return HTML because nginx looks for the path including the prefix in the filesystem.
### Expected Behavior
1. **Docs should be corrected**: `BASE_PATH` must end with `/`. The example in the documentation should show `BASE_PATH=/dependency-track/`.
2. **The nginx container config should strip `BASE_PATH` internally**: operators should not need to configure a path rewrite in their reverse proxy. The container should work correctly when the full prefixed path is forwarded to it (standard proxy behavior). Using `alias` + a `location` block matching `BASE_PATH` should achieve this.
3. **The API server should accept a configurable base path**: so that `/dependency-track/api/v1/...` is handled natively without requiring gateway-level URL rewriting.
### Dependency-Track Version
4.14.1
### Dependency-Track Distribution
Container Image
### Database Server
PostgreSQL
### Database Server Version
17.8
### Browser
N/A
### Checklist
- [x] I have read and understand the [contributing guidelines](https://github.com/DependencyTrack/dependency-track/blob/master/CONTRIBUTING.md#filing-issues)
- [x] I have checked the [existing issues](https://github.com/DependencyTrack/dependency-track/issues) for whether this defect was already reported
Contributor guide
Assessment
This issue has not been assessed yet.