hyperdx/packages/api/.env.development
Warren Lee dea1b669e6
Fix dev env port resolution and improve multi-worktree support (#2025)
## Summary

- Fix dev environment port isolation so OTel collector, MongoDB, and ClickHouse resolve to the correct worktree-specific ports
- Add slot-specific session cookies so multiple worktrees on localhost don't interfere with each other's login sessions
- Share NX build cache across worktrees for faster builds
- Add worktrunk project config for automated worktree lifecycle management

## Changes

### Port resolution fix

**Root `.env`**: Replace self-referential `HDX_DEV_*` vars (e.g. `HDX_DEV_OTEL_HTTP_PORT=${HDX_DEV_OTEL_HTTP_PORT:-4318}`) with plain default values. The `${VAR:-default}` syntax caused `dotenv-expand` infinite recursion, preventing `dev-env.sh` port overrides from taking effect.

**`packages/api/.env.development`**: Remove redundant self-referential port declarations and `:-default` fallbacks from `${HDX_DEV_*}` references. Ports now come exclusively from `dev-env.sh` exports or root `.env` defaults.

**`packages/app/.env.development`**: Set `HYPERDX_API_KEY` to `super-secure-ingestion-api-key` (matching the API/collector) instead of a placeholder. Remove self-referential port declarations.

**`packages/app/src/config.ts`**: Add `process.env.OTEL_EXPORTER_OTLP_ENDPOINT` as fallback for `HDX_COLLECTOR_URL` so the browser OTel SDK picks up the correct collector endpoint.

### Session cookie isolation

**`packages/api/src/api-app.ts`**: Use `connect.sid.<slot>` as the session cookie name in dev mode so multiple worktrees on `localhost` maintain independent sessions. Guarded behind `config.IS_DEV && process.env.HDX_DEV_SLOT` — production uses the default `connect.sid`.

### Shared NX build cache

**`scripts/dev-env.sh`**: Set `NX_CACHE_DIRECTORY=~/.config/hyperdx/nx-cache` so all worktrees share a single content-hash-based build cache. Unchanged packages get cache hits regardless of worktree; changed packages rebuild correctly.

### Worktrunk project config

**`.config/wt.toml`**: New project config for [worktrunk](https://worktrunk.dev) (`wt`) worktree lifecycle hooks:
- `pre-start`: Symlink `node_modules/` from primary worktree (instant, no copy)
- `post-start`: Copy `.env.local` from primary worktree
- `post-remove`: Tear down Docker stacks (`dev-down`, `dev-int-down`, `dev-e2e-down`) for the removed worktree's slot
2026-04-01 20:53:09 +00:00

24 lines
5.4 KiB
Text

# Ports come from scripts/dev-env.sh (worktree isolation) or root .env (defaults)
HYPERDX_LOG_LEVEL=debug
EXPRESS_SESSION_SECRET="hyperdx is cool 👋"
FRONTEND_URL="http://localhost:${HYPERDX_APP_PORT}"
HDX_NODE_ADVANCED_NETWORK_CAPTURE=1
HDX_NODE_BETA_MODE=1
HDX_NODE_CONSOLE_CAPTURE=1
MINER_API_URL="http://localhost:5123"
MONGO_URI="mongodb://localhost:${HDX_DEV_MONGO_PORT}/hyperdx"
NODE_ENV=development
OTEL_SERVICE_NAME="hdx-oss-dev-api"
OTEL_RESOURCE_ATTRIBUTES="service.version=dev"
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:${HDX_DEV_OTEL_HTTP_PORT}"
PORT=${HYPERDX_API_PORT}
OPAMP_PORT=${HYPERDX_OPAMP_PORT}
REDIS_URL=redis://localhost:6379
USAGE_STATS_ENABLED=false
NODE_OPTIONS="--max-http-header-size=131072"
ENABLE_SWAGGER=true
DEFAULT_CONNECTIONS=[{"name":"Local ClickHouse","host":"http://localhost:${HDX_DEV_CH_HTTP_PORT}","username":"default","password":""}]
DEFAULT_SOURCES=[{"from":{"databaseName":"default","tableName":"otel_logs"},"kind":"log","timestampValueExpression":"TimestampTime","name":"Logs","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"Body","serviceNameExpression":"ServiceName","bodyExpression":"Body","eventAttributesExpression":"LogAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,SeverityText,Body","severityTextExpression":"SeverityText","traceIdExpression":"TraceId","spanIdExpression":"SpanId","connection":"Local ClickHouse","traceSourceId":"Traces","sessionSourceId":"Sessions","metricSourceId":"Metrics"},{"from":{"databaseName":"default","tableName":"otel_traces"},"kind":"trace","timestampValueExpression":"Timestamp","name":"Traces","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"SpanName","serviceNameExpression":"ServiceName","eventAttributesExpression":"SpanAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,StatusCode,round(Duration/1e6),SpanName","traceIdExpression":"TraceId","spanIdExpression":"SpanId","durationExpression":"Duration","durationPrecision":9,"parentSpanIdExpression":"ParentSpanId","spanNameExpression":"SpanName","spanKindExpression":"SpanKind","statusCodeExpression":"StatusCode","statusMessageExpression":"StatusMessage","connection":"Local ClickHouse","logSourceId":"Logs","sessionSourceId":"Sessions","metricSourceId":"Metrics"},{"from":{"databaseName":"default","tableName":""},"kind":"metric","timestampValueExpression":"TimeUnix","name":"Metrics","resourceAttributesExpression":"ResourceAttributes","metricTables":{"gauge":"otel_metrics_gauge","histogram":"otel_metrics_histogram","sum":"otel_metrics_sum","_id":"682586a8b1f81924e628e808","id":"682586a8b1f81924e628e808"},"connection":"Local ClickHouse","logSourceId":"Logs","traceSourceId":"Traces","sessionSourceId":"Sessions"},{"from":{"databaseName":"default","tableName":"hyperdx_sessions"},"kind":"session","timestampValueExpression":"TimestampTime","name":"Sessions","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"Body","serviceNameExpression":"ServiceName","bodyExpression":"Body","eventAttributesExpression":"LogAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,SeverityText,Body","severityTextExpression":"SeverityText","traceIdExpression":"TraceId","spanIdExpression":"SpanId","connection":"Local ClickHouse","logSourceId":"Logs","traceSourceId":"Traces","metricSourceId":"Metrics"},{"from":{"databaseName":"otel_json","tableName":"otel_logs"},"kind":"log","timestampValueExpression":"Timestamp","name":"JSON Logs","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"Body","serviceNameExpression":"ServiceName","bodyExpression":"Body","eventAttributesExpression":"LogAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,SeverityText,Body","severityTextExpression":"SeverityText","traceIdExpression":"TraceId","spanIdExpression":"SpanId","connection":"Local ClickHouse","traceSourceId":"JSON Traces","metricSourceId":"JSON Metrics"},{"from":{"databaseName":"otel_json","tableName":"otel_traces"},"kind":"trace","timestampValueExpression":"Timestamp","name":"JSON Traces","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"SpanName","serviceNameExpression":"ServiceName","eventAttributesExpression":"SpanAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,StatusCode,round(Duration/1e6),SpanName","traceIdExpression":"TraceId","spanIdExpression":"SpanId","durationExpression":"Duration","durationPrecision":9,"parentSpanIdExpression":"ParentSpanId","spanNameExpression":"SpanName","spanKindExpression":"SpanKind","statusCodeExpression":"StatusCode","statusMessageExpression":"StatusMessage","connection":"Local ClickHouse","logSourceId":"JSON Logs","metricSourceId":"JSON Metrics"},{"from":{"databaseName":"otel_json","tableName":""},"kind":"metric","timestampValueExpression":"TimeUnix","name":"JSON Metrics","resourceAttributesExpression":"ResourceAttributes","metricTables":{"gauge":"otel_metrics_gauge","histogram":"otel_metrics_histogram","sum":"otel_metrics_sum"},"connection":"Local ClickHouse","logSourceId":"JSON Logs","traceSourceId":"JSON Traces"}]
INGESTION_API_KEY="super-secure-ingestion-api-key"
HYPERDX_API_KEY=$INGESTION_API_KEY
ANTHROPIC_API_KEY="your-anthropic-api-key-here"