diff --git a/src/apps/relay-server/Caddyfile b/src/apps/relay-server/Caddyfile index 9c29d230d2..6228e9f246 100644 --- a/src/apps/relay-server/Caddyfile +++ b/src/apps/relay-server/Caddyfile @@ -12,7 +12,14 @@ # response. Keep reverse-proxy read/response timeouts above that, or the # proxy returns HTTP 504 before Axum can. # -# Option A: With a domain (Let's Encrypt auto-HTTPS) +# IMPORTANT: URL structure when using a /relay path prefix +# / → static homepage (from static/homepage/) +# /relay/* → relay service (prefix stripped before proxying) +# /relay/health → health check +# /relay/ws → WebSocket endpoint +# /relay/api/* → all API endpoints +# +# Option A: With a domain (Let's Encrypt auto-HTTPS), root path # relay.yourdomain.com { # reverse_proxy relay-server:9700 { # transport http { @@ -23,8 +30,10 @@ # } # } # -# Option A2: With a /relay path prefix +# Option A2: With a /relay path prefix (homepage at /, service at /relay/) # relay.yourdomain.com { +# root * /app/homepage +# try_files {path} {path}/ /index.html # handle_path /relay/* { # reverse_proxy relay-server:9700 { # transport http { @@ -57,3 +66,46 @@ } } } + +# ───────────────────────────────────────────────────────────────────────── +# Nginx equivalent (Option A2: /relay prefix, homepage at /) +# ───────────────────────────────────────────────────────────────────────── +# +# server { +# listen 80; +# server_name remote.yourdomain.com; +# +# # Homepage (static files from relay-server/static/homepage/) +# location / { +# root /path/to/relay-server/static/homepage; +# index index.html; +# try_files $uri $uri/ =404; +# } +# +# # Redirect /relay → /relay/ +# location = /relay { +# return 301 /relay/; +# } +# +# # Relay service (strip /relay prefix, proxy to port 9700) +# location /relay/ { +# proxy_pass http://127.0.0.1:9700/; +# proxy_set_header Host $host; +# 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; +# +# # WebSocket support (/relay/ws endpoint) +# proxy_http_version 1.1; +# proxy_set_header Upgrade $http_upgrade; +# proxy_set_header Connection "upgrade"; +# +# # Long timeouts for device RPC (up to 120s) and sync +# proxy_buffering off; +# proxy_read_timeout 130s; +# proxy_send_timeout 130s; +# +# # Sync POSTs can carry large encrypted session bundles +# client_max_body_size 100m; +# } +# } diff --git a/src/apps/relay-server/Dockerfile b/src/apps/relay-server/Dockerfile index b0dfcbb5dc..1c8491ace1 100644 --- a/src/apps/relay-server/Dockerfile +++ b/src/apps/relay-server/Dockerfile @@ -6,8 +6,9 @@ FROM rust:1-slim AS builder WORKDIR /build/src/apps/relay-server # Optional: limit rustc parallelism on small or low-memory VPS hosts. +# docker compose build --build-arg CARGO_BUILD_JOBS=1 +# Note: empty value must NOT be set as ENV — cargo chokes on empty string. ARG CARGO_BUILD_JOBS= -ENV CARGO_BUILD_JOBS=${CARGO_BUILD_JOBS} ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ @@ -39,7 +40,8 @@ RUN rm -rf src ../../crates/services/relay-service/src \ COPY src/apps/relay-server/src/ ./src/ COPY src/crates/services/relay-service/src/ ../../crates/services/relay-service/src/ -RUN cargo build --release \ +RUN if [ -n "${CARGO_BUILD_JOBS}" ]; then export CARGO_BUILD_JOBS; fi \ + && cargo build --release \ && (strip target/release/bitfun-relay-server target/release/relay-admin || true) FROM debian:bookworm-slim diff --git a/src/apps/relay-server/README.md b/src/apps/relay-server/README.md index f3f5e238ba..21cda9fc6d 100644 --- a/src/apps/relay-server/README.md +++ b/src/apps/relay-server/README.md @@ -154,8 +154,11 @@ Relay URL examples: - Direct: `http://:9700` - Localhost: `http://127.0.0.1:9700` -- Behind a reverse proxy: `https://relay.example.com` (only add a path prefix - such as `/relay` if your proxy is configured that way) +- Behind a reverse proxy: `https://relay.example.com/relay` + +The client appends paths (`/ws`, `/api/*`, `/r/*`) to the URL you enter. Use +the `/relay` suffix to match the official server format +(`https://remote.openbitfun.com/relay`). See **Reverse Proxy** for nginx config. **Desktop** @@ -256,13 +259,69 @@ RELAY_PORT=9700 ./target/release/bitfun-relay-server ## Deployment Checklist -1. Open ports: `9700` (direct), and `80/443` if using Caddy / another proxy. -2. Hit `http://:9700/health`. +1. Open ports: `9700` (direct), and `80/443` if using a reverse proxy. +2. Hit `http://:9700/health` (or `https://relay.example.com/relay/health` behind a proxy). 3. Confirm `RELAY_DB_PATH` if you need accounts (Compose does this for you). 4. Create at least one user with `relay-admin`. 5. Fill the same relay URL into Desktop / CLI and log in. 6. If you terminate TLS on a reverse proxy, raise body size and read timeouts (see sync + device RPC notes below). +7. Use the `/relay` suffix in the relay URL (e.g. `https://relay.example.com/relay`) + to match the official server format. See **Reverse Proxy** for nginx config. + +## Reverse Proxy + +When deploying behind a reverse proxy (Caddy, nginx, etc.), configure: + +- **Body size limit**: at least 100 MB (sync POSTs carry large encrypted bundles) +- **Read/response timeout**: at least 130s (device RPC waits up to 120s) +- **WebSocket upgrade**: the /ws endpoint requires Connection upgrade headers +- **Path prefix**: serve the relay at `/relay/*` (strip prefix before proxying + to port 9700); serve static homepage files at `/` via exact-match locations + +### Nginx example (/relay prefix + homepage at /) + +```nginx +server { + listen 80; + server_name relay.example.com; + + # Homepage static files (exact match) + location = / { + root /path/to/relay-server/static/homepage; + try_files /index.html =404; + } + location = /i18n.json { + root /path/to/relay-server/static/homepage; + } + location = /i18n.shared.json { + root /path/to/relay-server/static/homepage; + } + + # With /relay prefix: strip prefix, proxy to relay server + # For clients configured with https://relay.example.com/relay + location = /relay { + return 301 /relay/; + } + location /relay/ { + proxy_pass http://127.0.0.1:9700/; + proxy_set_header Host $host; + 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; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_buffering off; + proxy_read_timeout 130s; + proxy_send_timeout 130s; + client_max_body_size 100m; + } + +} +``` + +See `Caddyfile` for the Caddy equivalent. ## Environment Variables diff --git a/src/apps/relay-server/deploy.sh b/src/apps/relay-server/deploy.sh index 6ce674e3ba..3214ccc1a3 100755 --- a/src/apps/relay-server/deploy.sh +++ b/src/apps/relay-server/deploy.sh @@ -108,8 +108,9 @@ echo "" check_relay_accounts_or_remind echo "" echo "Point BitFun Desktop / CLI Auth Server URL to:" -echo " http://:9700" -echo "See README.md for sync, Peer Device Mode, and proxy timeouts." +echo " Direct: http://:9700" +echo " Proxy: https:///relay (recommended, matches official server)" +echo "See README.md for reverse proxy setup, sync, and Peer Device Mode." echo "" echo "Check status: bash -c 'cd \"${SCRIPT_DIR}\" && ${COMPOSE[*]} ps'" echo "Start: bash start.sh" diff --git a/src/crates/assembly/core/src/agentic/tools/product_runtime/catalog.rs b/src/crates/assembly/core/src/agentic/tools/product_runtime/catalog.rs index 042f320e07..bc2fbb0cf6 100644 --- a/src/crates/assembly/core/src/agentic/tools/product_runtime/catalog.rs +++ b/src/crates/assembly/core/src/agentic/tools/product_runtime/catalog.rs @@ -782,7 +782,7 @@ mod tests { .allowed_tool_names .contains(&"ReviewPlatform".to_string())); assert!(manifest - .collapsed_tool_names + .deferred_tool_names .contains(&"ReviewPlatform".to_string())); assert!(manifest .tool_definitions