mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat: add subpath config (#1236)
Co-authored-by: Warren <5959690+wrn14897@users.noreply.github.com>
This commit is contained in:
parent
658728318b
commit
b806116d73
9 changed files with 211 additions and 2 deletions
9
.changeset/feat-subpath-config.md
Normal file
9
.changeset/feat-subpath-config.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
'@hyperdx/app': minor
|
||||
---
|
||||
|
||||
feat: Add subpath configuration support
|
||||
|
||||
This change allows the HyperDX frontend to be served from a subpath (e.g.,
|
||||
`/hyperdx`). It includes updated Next.js, NGINX, and Traefik configurations,
|
||||
along with documentation for the new setup.
|
||||
1
.env
1
.env
|
|
@ -20,6 +20,7 @@ HYPERDX_APP_PORT=8080
|
|||
HYPERDX_APP_URL=http://localhost
|
||||
HYPERDX_LOG_LEVEL=debug
|
||||
HYPERDX_OPAMP_PORT=4320
|
||||
HYPERDX_BASE_PATH=
|
||||
|
||||
# Otel/Clickhouse config
|
||||
HYPERDX_OTEL_EXPORTER_CLICKHOUSE_DATABASE=default
|
||||
|
|
|
|||
|
|
@ -83,5 +83,29 @@ services:
|
|||
interval: 1s
|
||||
timeout: 1s
|
||||
retries: 60
|
||||
|
||||
# nginx:
|
||||
# image: nginx:alpine
|
||||
# ports:
|
||||
# - '4040:4040'
|
||||
# volumes:
|
||||
# - ./proxy/nginx/nginx.conf.template:/etc/nginx/templates/default.conf.template:ro
|
||||
# environment:
|
||||
# HYPERDX_BASE_PATH: ${HYPERDX_BASE_PATH:-/}
|
||||
# network_mode: host
|
||||
# restart: always
|
||||
|
||||
# traefik:
|
||||
# image: traefik:latest
|
||||
# ports:
|
||||
# - '4040:4040'
|
||||
# volumes:
|
||||
# - ./proxy/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
# - ./proxy/traefik/config.yml:/etc/traefik/dynamic/config.yml:ro
|
||||
# environment:
|
||||
# HYPERDX_BASE_PATH: ${HYPERDX_BASE_PATH:-/}
|
||||
# network_mode: host
|
||||
# restart: always
|
||||
|
||||
networks:
|
||||
internal:
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
|
|||
OTEL_SERVICE_NAME="hdx-oss-dev-app"
|
||||
PORT=${HYPERDX_APP_PORT}
|
||||
NODE_OPTIONS="--max-http-header-size=131072"
|
||||
NEXT_PUBLIC_HYPERDX_BASE_PATH=
|
||||
|
|
@ -8,7 +8,10 @@ const withNextra = require('nextra')({
|
|||
themeConfig: './src/nextra.config.tsx',
|
||||
});
|
||||
|
||||
const basePath = process.env.NEXT_PUBLIC_HYPERDX_BASE_PATH;
|
||||
|
||||
module.exports = {
|
||||
basePath: basePath,
|
||||
experimental: {
|
||||
instrumentationHook: true,
|
||||
// External packages to prevent bundling issues with Next.js 14
|
||||
|
|
|
|||
74
proxy/README.md
Normal file
74
proxy/README.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Proxy Configuration
|
||||
|
||||
This directory contains configurations for running the HyperDX frontend behind a
|
||||
reverse proxy that serves the application under a specific subpath. This is
|
||||
useful for deployments where HyperDX is not at the root of a domain (e.g.,
|
||||
`http://example.com/hyperdx`).
|
||||
|
||||
We provide configurations for two popular reverse proxies:
|
||||
|
||||
- [Nginx](./nginx/nginx.conf.template)
|
||||
- [Traefik](./traefik/config.yml)
|
||||
|
||||
## Environment Variables
|
||||
|
||||
To configure the subpath, you need to set the following environment variables in
|
||||
your `.env` file.
|
||||
|
||||
### `HYPERDX_BASE_PATH` and `NEXT_PUBLIC_HYPERDX_BASE_PATH`
|
||||
|
||||
To serve the application from a subpath, two environment variables must be set
|
||||
to the **same value**:
|
||||
|
||||
1. `HYPERDX_BASE_PATH`: This is used by the reverse proxy (Nginx or Traefik) to
|
||||
handle path routing and rewriting.
|
||||
2. `NEXT_PUBLIC_HYPERDX_BASE_PATH`: This is used by the Next.js application to
|
||||
generate correct asset links and API routes.
|
||||
|
||||
- The value **must** start with a `/` if it's not an empty string (ex:
|
||||
`/hyperdx`).
|
||||
- If you want to serve from the root, you can omit these variables or set them
|
||||
to `/`.
|
||||
|
||||
### `FRONTEND_URL`
|
||||
|
||||
This variable should be set to the full public URL of the frontend, including
|
||||
the subpath. The API server uses this URL for various purposes such as
|
||||
generating absolute URLs for redirects, links in emails, or alerts.
|
||||
|
||||
- It should be a full URL, including the protocol (`http` or `https`).
|
||||
- It should include the subpath defined in `HYPERDX_BASE_PATH`.
|
||||
|
||||
**Example `.env` Configuration:**
|
||||
|
||||
For local development with the subpath `/hyperdx`, your configuration would look
|
||||
like this:
|
||||
|
||||
```
|
||||
HYPERDX_BASE_PATH=/hyperdx
|
||||
NEXT_PUBLIC_HYPERDX_BASE_PATH=/hyperdx
|
||||
FRONTEND_URL=http://localhost:4040/hyperdx
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
The proxy configurations are designed to handle subpath routing with minimal
|
||||
changes to the application code. Here's a high-level overview of the logic:
|
||||
|
||||
1. **Root Redirect**: If a subpath is configured (e.g., `/hyperdx`), any
|
||||
requests to the root (`/`) are automatically redirected to that subpath.
|
||||
This ensures users always land on the correct URL.
|
||||
|
||||
2. **Path Rewriting**: The application's frontend code sometimes makes requests
|
||||
to root-level paths (e.g., `/api/...` or `/_next/...`). The proxy intercepts
|
||||
these requests, prepends the configured subpath, and forwards them to the
|
||||
Next.js server. For example, a request for `/_next/static/chunk.js` becomes
|
||||
a request for `/hyperdx/_next/static/chunk.js` before being sent to the
|
||||
application.
|
||||
|
||||
3. **Direct Proxy**: Any requests that already include the correct subpath are
|
||||
passed directly to the Next.js application, which is configured via
|
||||
`basePath` to handle them correctly.
|
||||
|
||||
This setup allows the frontend application to be developed as if it were running
|
||||
at the root, while the proxy transparently manages the subpath routing.
|
||||
43
proxy/nginx/nginx.conf.template
Normal file
43
proxy/nginx/nginx.conf.template
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
upstream app {
|
||||
server 127.0.0.1:8080;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 4040;
|
||||
|
||||
set $base_path "${HYPERDX_BASE_PATH}";
|
||||
if ($base_path = "/") {
|
||||
set $base_path "";
|
||||
}
|
||||
|
||||
# Common proxy headers
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Redirect root to base path, if a base path is set
|
||||
location = / {
|
||||
if ($base_path != "") {
|
||||
return 301 $base_path;
|
||||
}
|
||||
# If no base path, just proxy to the app
|
||||
proxy_pass http://app;
|
||||
}
|
||||
|
||||
# This handles assets and api calls made to the root and rewrites them to include the base path
|
||||
location ~ ^(/api/|/_next/|/__ENV\.js$|/Icon32\.png$) {
|
||||
# Note: $request_uri includes the original full path including query string
|
||||
proxy_pass http://app$base_path$request_uri;
|
||||
}
|
||||
|
||||
# Proxy requests that are already prefixed with the base path to the app
|
||||
location ${HYPERDX_BASE_PATH} {
|
||||
# The full request URI (e.g., /hyperdx/settings) is passed to the upstream
|
||||
proxy_pass http://app;
|
||||
}
|
||||
}
|
||||
46
proxy/traefik/config.yml
Normal file
46
proxy/traefik/config.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
http:
|
||||
routers:
|
||||
# This handles the main app at the basepath
|
||||
app-router:
|
||||
entryPoints:
|
||||
- web
|
||||
rule: 'PathPrefix(`{{ env "HYPERDX_BASE_PATH" }}`)'
|
||||
service: app-service
|
||||
|
||||
# This handles assets and api calls at the root and rewrites them
|
||||
assets-api-router:
|
||||
entryPoints:
|
||||
- web
|
||||
rule:
|
||||
'PathPrefix(`/api`) || PathPrefix(`/_next`) || Path(`/__ENV.js`) ||
|
||||
Path(`/Icon32.png`)'
|
||||
service: app-service
|
||||
middlewares:
|
||||
- add-basepath
|
||||
|
||||
# This redirects from / to the basepath
|
||||
root-redirect:
|
||||
entryPoints:
|
||||
- web
|
||||
rule: 'Path(`/`)'
|
||||
service: app-service # service is required, but redirect will happen first
|
||||
middlewares:
|
||||
- redirect-to-basepath
|
||||
|
||||
middlewares:
|
||||
add-basepath:
|
||||
addPrefix:
|
||||
prefix: '{{ env "HYPERDX_BASE_PATH" }}'
|
||||
|
||||
redirect-to-basepath:
|
||||
redirectRegex:
|
||||
regex: '^/$'
|
||||
replacement: '{{ env "HYPERDX_BASE_PATH" }}'
|
||||
permanent: true
|
||||
|
||||
services:
|
||||
app-service:
|
||||
loadBalancer:
|
||||
passHostHeader: true
|
||||
servers:
|
||||
- url: 'http://127.0.0.1:8080'
|
||||
8
proxy/traefik/traefik.yml
Normal file
8
proxy/traefik/traefik.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
entryPoints:
|
||||
web:
|
||||
address: ':4040'
|
||||
|
||||
providers:
|
||||
file:
|
||||
filename: /etc/traefik/dynamic/config.yml
|
||||
watch: true
|
||||
Loading…
Reference in a new issue