GitNexus/docker-compose.yaml
samuel mbabhazi 0f3bad23b9
feat(web): resolve a root-relative GITNEXUS_BACKEND_URL against the page origin (#3640)
* feat(web): resolve a root-relative GITNEXUS_BACKEND_URL against the page origin

A GITNEXUS_BACKEND_URL of `/` (or `/prefix`) is injected as-is, and the
web client resolves it against the origin that served the page, so one
gitnexus-web deployment reaches its API on every hostname a reverse
proxy gives it. Protocol-relative values are left to the URL check and
rejected. Documents the two ways to route /api/* behind a proxy.

Closes #3593

* fix(web): reject a backslash-prefixed same-origin path

The URL parser reads a backslash as a slash, so `/\host` resolved against
the page origin became `http://host/`, an origin change. Both the server
check and the client resolution now treat it like `//host`.

* fix(web): keep a configured base ending in /api, and drop the unsupported direct route

normalizeServerUrl stripped a trailing /api from every URL, so a deployment
configured with GITNEXUS_BACKEND_URL=/proxy/api passed health and discovery
and then connected to /proxy/repo. The deployment's own base is now kept as
configured; the /api cleanup stays for hand-entered URLs. A regression covers
health, discovery and repository selection under /proxy/api.

The README no longer offers routing /api/* straight to `gitnexus serve` on a
public hostname: serve refuses to start with GITNEXUS_PUBLIC_ORIGIN set until
it has authentication of its own.

* fix(web): keep only a same-origin base as configured

The bypass in normalizeServerUrl matched any injected default, so an
absolute GITNEXUS_BACKEND_URL ending in /api would have produced a
doubled /api segment, and one carrying credentials would have kept them.
Only a root-relative deployment base is kept now; it is resolved from the
page origin, so it has neither. Absolute injected URLs are normalized as
before.
2026-10-24 08:45:24 +01:00

54 lines
2.2 KiB
YAML

services:
gitnexus-server:
image: ${SERVER_IMAGE:-ghcr.io/abhigyanpatwari/gitnexus:latest}
container_name: ${SERVER_CONTAINER_NAME:-gitnexus-server}
# Map the server to the same host port the web UI expects by default
# (http://localhost:4747). The browser runs on the host, so the UI's
# built-in default works without any reconfiguration.
ports:
- '${SERVER_HOST_PORT:-4747}:4747'
volumes:
# Persist the global registry, indexes, and cloned repos across runs.
- gitnexus-data:/data/gitnexus
# Optional: mount a host workspace so `gitnexus index <path>` can see
# repos you already have on disk. The default points at an empty
# `./workspace/` sibling that compose will create on first start —
# it intentionally does NOT bind-mount the repo root, which would
# expose `.git`, `.env`, and CI secrets to the container.
# Override with `WORKSPACE_DIR=/abs/path/to/your/repos`.
- ${WORKSPACE_DIR:-./workspace}:/workspace:ro
restart: unless-stopped
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:4747/api/health']
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
gitnexus-web:
image: ${WEB_IMAGE:-ghcr.io/abhigyanpatwari/gitnexus-web:latest}
container_name: ${WEB_CONTAINER_NAME:-gitnexus-web}
ports:
- '${WEB_HOST_PORT:-4173}:4173'
# Override the backend URL served to the browser. The default
# (http://localhost:4747) works when both containers run locally.
# Set GITNEXUS_BACKEND_URL in your .env or shell for remote/custom setups:
# GITNEXUS_BACKEND_URL=http://<server-ip>:4747
# Behind a reverse proxy that routes /api/* next to the UI, set it to `/`:
# the browser then calls the API on whichever hostname served the page
# (see "Same-origin API behind a reverse proxy" in the README).
environment:
- GITNEXUS_BACKEND_URL=${GITNEXUS_BACKEND_URL:-}
depends_on:
gitnexus-server:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:4173/']
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
volumes:
gitnexus-data: