Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ services:
# from environment variables — no sidecar or init container needed.
#
# Environment variables:
# GQ_BACKEND_HOST - backend API address for Caddy's reverse proxy
# (default: http://127.0.0.1:8145)
# GQ_BACKEND_HOST - global-query API address for Caddy's reverse proxy.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here is still weak in terms of clarity (it should be clear that this the global query endpoint, the phrase is still too weak, even more so if an actual reverse proxy like nginx is involved in a production environment).

# Must match the query service's SERVER_ADDR below
# (default: http://127.0.0.1:8146).
# GQ_API_BASE_URL - URL the *browser* uses to reach the API.
# Leave empty (default) to route via the Caddy proxy.
# HOST_RESOLVER_TYPES - comma-separated resolver types shown in the UI (default: string)
Expand All @@ -67,7 +68,7 @@ services:
- frontend_data:/data
- frontend_config:/config
environment:
GQ_BACKEND_HOST: ${GQ_BACKEND_HOST:-http://127.0.0.1:8145}
GQ_BACKEND_HOST: ${GQ_BACKEND_HOST:-http://127.0.0.1:8146}
GQ_API_BASE_URL: ${GQ_API_BASE_URL:-}
HOST_RESOLVER_TYPES: ${HOST_RESOLVER_TYPES:-string}
SSE_ON_LOAD: ${SSE_ON_LOAD:-true}
Expand Down
7 changes: 5 additions & 2 deletions frontend/goquery-ui/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,14 @@ USER caddy

EXPOSE 5137

# Runtime env vars with defaults (override in K8s Deployment / docker-compose)
# Runtime env vars with defaults (override in K8s Deployment / docker-compose).
# GQ_BACKEND_HOST defaults to the global-query address of the single-host
# docker-compose setup; the Caddyfile applies the same fallback when it is unset
# or empty, so the proxy always has an upstream to dial (see #480).
ENV GQ_API_BASE_URL="" \
HOST_RESOLVER_TYPES="string" \
SSE_ON_LOAD="true" \
GQ_BACKEND_HOST=""
GQ_BACKEND_HOST="http://127.0.0.1:8146"

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
29 changes: 29 additions & 0 deletions frontend/goquery-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,28 @@ make docker-up # run the hardened image (docker compose up --build)
make docker-build # build Caddy image locally
```

### Runtime configuration

The image is configured entirely through environment variables, read at
container startup. The two networking knobs are easy to confuse:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small chart displaying the interaction between the components, in particular frontend + caddy, global query and goprobe nodes (+ e.g. production environment with an nginx / TLS reverse proxy in front) would help.


| Variable | Consumed by | Purpose | Default |
| --- | --- | --- | --- |
| `GQ_BACKEND_HOST` | Caddy (reverse proxy) | Where Caddy forwards `/_query*` and `/-/*` **server-side**. Point it at the global-query backend. | `http://127.0.0.1:8146` |
| `GQ_API_BASE_URL` | Browser (env.js) | URL the **browser** uses to reach the API. Leave empty to route through Caddy's same-origin proxy (recommended — keeps the CSP intact and avoids CORS). | empty |
| `HOST_RESOLVER_TYPES` | Browser (env.js) | Comma-separated resolver types offered in the UI. | `string` |
| `SSE_ON_LOAD` | Browser (env.js) | Enable SSE streaming by default. | `true` |

Browser API calls go to `/_query*` on the same origin as the UI, and Caddy
proxies them on to `GQ_BACKEND_HOST` — so under normal use you only set
`GQ_BACKEND_HOST`, and leave `GQ_API_BASE_URL` empty. The default backend
(`http://127.0.0.1:8146`) matches the global-query address in the single-host
`docker-compose.yaml`; override it for other topologies, e.g. in Kubernetes:

```bash
GQ_BACKEND_HOST=http://global-query.observability.svc.cluster.local:8145
```

## Using the UI

- Time range: quick presets (5m…30d) or set exact From/To.
Expand Down Expand Up @@ -95,6 +117,13 @@ make docker-build # build Caddy image locally

## Troubleshooting

- API requests fail with `503` and Caddy logs `"no upstreams available"`: the
reverse proxy has no backend to dial because `GQ_BACKEND_HOST` resolved to an
empty value. Set it to your global-query address (see
[Runtime configuration](#runtime-configuration)). Note that listing the
variable with an empty value (e.g. `GQ_BACKEND_HOST=` or `${GQ_BACKEND_HOST:-}`)
overrides the built-in default with empty — leave it unset to take the default.

- If the editor reports a spurious import error for a newly added view file, run a fresh typecheck:

```bash
Expand Down
18 changes: 12 additions & 6 deletions frontend/goquery-ui/deploy/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,25 @@
}
}

# Proxy API calls to the backend. The browser sees same-origin requests,
# so no CORS headers are required on the backend for browser traffic.
# GQ_BACKEND_HOST must be set in the container environment, e.g.
# GQ_BACKEND_HOST=http://global-query:8145
# Proxy API calls to the global-query backend. The browser sees same-origin
# requests, so no CORS headers are required on the backend for browser traffic.
#
# GQ_BACKEND_HOST points Caddy at the backend. It falls back to
# http://127.0.0.1:8146 — the global-query address in the single-host
# docker-compose setup — when unset OR empty. Without a fallback, an empty
# value expands to a reverse_proxy with no upstream, and every request fails
# with 503 "no upstreams available" (see #480). Override it for any other
# topology, e.g. GQ_BACKEND_HOST=http://global-query.observability.svc:8145
# in Kubernetes.
#
# header_up Host rewrites the Host header to the backend's hostport instead
# of preserving the browser's external Host. This is required behind service
# meshes like Istio, whose sidecar routes by Host: an unrecognized external
# host falls through to PassthroughCluster and fails with 503 (see #478).
reverse_proxy /_query* {$GQ_BACKEND_HOST} {
reverse_proxy /_query* {$GQ_BACKEND_HOST:http://127.0.0.1:8146} {
header_up Host {http.reverse_proxy.upstream.hostport}
}
reverse_proxy /-/* {$GQ_BACKEND_HOST} {
reverse_proxy /-/* {$GQ_BACKEND_HOST:http://127.0.0.1:8146} {
header_up Host {http.reverse_proxy.upstream.hostport}
}

Expand Down
Loading