Browse Source

bug-fixes

imwald
Silberengel 2 weeks ago
parent
commit
fd70cae4b7
  1. 6
      .env.development
  2. 1
      .gitignore
  3. 2
      PROXY_SETUP.md
  4. 31
      docker-compose.dev.yml
  5. 64
      docker-compose.prod.yml
  6. 26
      docker-compose.yml
  7. 7
      package.json
  8. 13
      scripts/dev-all-local.sh
  9. 10
      scripts/ensure-libretranslate-dirs.sh
  10. 14
      scripts/stack-remote.sh
  11. 6
      scripts/start-local-ancillary.sh

6
.env.development

@ -0,0 +1,6 @@
# Picked up automatically by `vite` / `npm run dev` / `npm run dev:all` (development mode only).
# Paths are same-origin; vite.config.ts proxies them to Docker (see npm run dev:all).
VITE_PROXY_SERVER=/sites
VITE_READ_ALOUD_TTS_URL=/api/piper-tts
VITE_LANGUAGE_TOOL_URL=/api/languagetool
VITE_TRANSLATE_URL=/api/translate

1
.gitignore vendored

@ -34,4 +34,5 @@ public/.og-image.raster.svg
.venv-i18n .venv-i18n
.local-piper-data .local-piper-data
.local-libretranslate
scripts/i18n-overrides/.gaps scripts/i18n-overrides/.gaps

2
PROXY_SETUP.md

@ -187,7 +187,7 @@ VITE_TRANSLATE_URL=/api/translate
**Production:** `docker compose -f docker-compose.prod.yml --profile editor-tools up -d languagetool libretranslate` publishes **127.0.0.1:8010** and **127.0.0.1:5000** (loopback-only). Proxy those paths from Apache/nginx to the SPA origin, and bake the client with `LANGUAGE_TOOL_URL=/api/languagetool` and `TRANSLATE_URL=/api/translate` when running `./scripts/build-and-push-prod.sh`. **Production:** `docker compose -f docker-compose.prod.yml --profile editor-tools up -d languagetool libretranslate` publishes **127.0.0.1:8010** and **127.0.0.1:5000** (loopback-only). Proxy those paths from Apache/nginx to the SPA origin, and bake the client with `LANGUAGE_TOOL_URL=/api/languagetool` and `TRANSLATE_URL=/api/translate` when running `./scripts/build-and-push-prod.sh`.
**Notes:** LanguageTool’s JVM image often needs **~1–2GiB** RAM. LibreTranslate may **download models** on first start (can take several minutes). **Notes:** LanguageTool’s JVM image often needs **~1–2GiB** RAM. LibreTranslate **does not listen on port 5000 until models are ready**; without **`LT_LOAD_ONLY`** it may pull **many gigabytes** first, so the Vite proxy can show **`ECONNRESET` on `/translate`** while booting. Compose sets **`LT_LOAD_ONLY=en,de`** by default (override with **`LT_LOAD_ONLY`**). Models are stored under **`.local-libretranslate/share`** and **`.local-libretranslate/cache`** (gitignored) with **bind mounts** so they survive **`docker compose down`**, image updates, and container recreate. **`scripts/ensure-libretranslate-dirs.sh`** (run automatically by **`npm run dev:all`**, **`npm run stack:remote`**, **`npm run docker:editor-tools`**, etc.) creates those dirs and **`chown`s them to UID 1032** via a short **Alpine** container so the LibreTranslate user can write. If you start **`libretranslate` by hand**, run **`npm run docker:prep-libretranslate`** once first. First download can still take **several minutes**; use **`docker logs -f jumble-libretranslate`** until **`curl http://127.0.0.1:5000/languages`** returns JSON.
## LibreTranslate (same-origin `/api/translate`) ## LibreTranslate (same-origin `/api/translate`)

31
docker-compose.dev.yml

@ -12,17 +12,22 @@ services:
networks: networks:
- jumble - jumble
proxy-server: # Link / OG preview — silberengel/wikistr (override: OG_PROXY_IMAGE).
image: ghcr.io/danvergara/jumble-proxy-server:latest og-proxy:
environment: image: ${OG_PROXY_IMAGE:-silberengel/wikistr:latest-og-proxy}
- ALLOW_ORIGIN=${JUMBLE_SOCIAL_URL:-http://localhost:8089} container_name: jumble-og-proxy
- JUMBLE_PROXY_GITHUB_TOKEN=${JUMBLE_PROXY_GITHUB_TOKEN:-}
- ENABLE_PPROF=true
- PORT=8080
ports: ports:
- "8090:8080" - '127.0.0.1:8090:8090'
environment:
PROXY_PORT: '8090'
PROXY_ALLOW_ORIGIN: ${OG_PROXY_ALLOW_ORIGIN:-http://localhost:5173}
PROXY_TIMEOUT_MS: '30000'
PROXY_MAX_BODY_BYTES: '5242880'
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true'
PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium-browser
networks: networks:
- jumble - jumble
restart: unless-stopped
nostr-relay: nostr-relay:
image: scsibug/nostr-rs-relay:latest image: scsibug/nostr-rs-relay:latest
@ -56,6 +61,13 @@ services:
container_name: jumble-libretranslate container_name: jumble-libretranslate
ports: ports:
- '5000:5000' - '5000:5000'
# Without LT_LOAD_ONLY the image downloads many GB of models before binding :5000 — Vite then gets ECONNRESET on /translate.
tty: true
environment:
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,de}
volumes:
- ./.local-libretranslate/share:/home/libretranslate/.local/share
- ./.local-libretranslate/cache:/home/libretranslate/.local/cache
networks: networks:
- jumble - jumble
restart: unless-stopped restart: unless-stopped
@ -63,7 +75,7 @@ services:
# Wyoming Piper + HTTP bridge (read-aloud). Profile local-tts — matches vite /api/piper-tts → :9876, Wyoming :10200. # Wyoming Piper + HTTP bridge (read-aloud). Profile local-tts — matches vite /api/piper-tts → :9876, Wyoming :10200.
# Mount voices under ./.local-piper-data/voices (see PROXY_SETUP.md) or use your existing piper-data path. # Mount voices under ./.local-piper-data/voices (see PROXY_SETUP.md) or use your existing piper-data path.
piper-wyoming: piper-wyoming:
image: silberengel/wyoming-piper:latest image: ${WYOMING_PIPER_IMAGE:-silberengel/wyoming-piper:latest}
profiles: ['local-tts'] profiles: ['local-tts']
container_name: jumble-piper-wyoming container_name: jumble-piper-wyoming
command: command:
@ -81,6 +93,7 @@ services:
- jumble - jumble
restart: unless-stopped restart: unless-stopped
# No Hub image required — built from this repo. (Avoid silberengel/imwald-piper-tts-proxy:latest here until it exists on Docker Hub.)
piper-tts-proxy: piper-tts-proxy:
profiles: ['local-tts'] profiles: ['local-tts']
container_name: jumble-piper-tts-proxy container_name: jumble-piper-tts-proxy

64
docker-compose.prod.yml

@ -1,5 +1,6 @@
# Minimal compose for running the published image (e.g. on remote server). # Minimal compose for running the published image (e.g. on remote server).
# Usage: docker compose -f docker-compose.prod.yml pull && docker compose -f docker-compose.prod.yml up -d # Full stack (jumble + NIP-66 + og-proxy + Piper + LanguageTool + LibreTranslate): npm run stack:remote
# Usage (app only): docker compose -f docker-compose.prod.yml pull && docker compose -f docker-compose.prod.yml up -d
# #
# Apache (unchanged on your host) should keep (order: specific paths before catch-all /): # Apache (unchanged on your host) should keep (order: specific paths before catch-all /):
# ProxyPass /sites/ http://127.0.0.1:8090/sites/ # ProxyPass /sites/ http://127.0.0.1:8090/sites/
@ -83,8 +84,69 @@ services:
container_name: imwald-libretranslate container_name: imwald-libretranslate
ports: ports:
- '127.0.0.1:5000:5000' - '127.0.0.1:5000:5000'
tty: true
environment:
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,de}
volumes:
- ./.local-libretranslate/share:/home/libretranslate/.local/share
- ./.local-libretranslate/cache:/home/libretranslate/.local/cache
restart: unless-stopped restart: unless-stopped
deploy: deploy:
resources: resources:
limits: limits:
memory: 2048M memory: 2048M
# --- profile `stack`: OG proxy + Piper (Apache → 8090 / 9876). One command: npm run stack:remote ---
# First-party images: silberengel/* (override with OG_PROXY_IMAGE / WYOMING_PIPER_IMAGE / PIPER_HTTP_PROXY_IMAGE).
og-proxy:
image: ${OG_PROXY_IMAGE:-silberengel/wikistr:latest-og-proxy}
profiles: ['stack']
container_name: og-proxy
ports:
- '127.0.0.1:8090:8090'
environment:
PROXY_PORT: '8090'
PROXY_ALLOW_ORIGIN: ${OG_PROXY_ALLOW_ORIGIN:-https://jumble.imwald.eu}
PROXY_TIMEOUT_MS: '30000'
PROXY_MAX_BODY_BYTES: '5242880'
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true'
PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium-browser
restart: unless-stopped
piper-wyoming:
image: ${WYOMING_PIPER_IMAGE:-silberengel/wyoming-piper:latest}
profiles: ['stack']
container_name: piper-tts
command:
- --voice
- en_US-lessac-medium
- --uri
- tcp://0.0.0.0:10200
- --data-dir
- /data
volumes:
- piper-stack-data:/data
expose:
- '10200'
restart: unless-stopped
piper-tts-proxy:
profiles: ['stack']
container_name: imwald-piper-tts-proxy
build:
context: .
dockerfile: services/piper-tts-proxy/Dockerfile
image: ${PIPER_HTTP_PROXY_IMAGE:-silberengel/imwald-piper-tts-proxy:latest}
environment:
NODE_ENV: production
PORT: '9876'
PIPER_TTS_HOST: piper-wyoming
PIPER_TTS_PORT: '10200'
ports:
- '127.0.0.1:9876:9876'
depends_on:
- piper-wyoming
restart: unless-stopped
volumes:
piper-stack-data:

26
docker-compose.yml

@ -12,17 +12,21 @@ services:
networks: networks:
- jumble - jumble
proxy-server: og-proxy:
image: ghcr.io/danvergara/jumble-proxy-server:latest image: ${OG_PROXY_IMAGE:-silberengel/wikistr:latest-og-proxy}
environment: container_name: jumble-og-proxy
- ALLOW_ORIGIN=${JUMBLE_SOCIAL_URL:-http://localhost:8089}
- JUMBLE_PROXY_GITHUB_TOKEN=${JUMBLE_PROXY_GITHUB_TOKEN:-}
- ENABLE_PPROF=true
- PORT=8080
ports: ports:
- "8090:8080" - '127.0.0.1:8090:8090'
environment:
PROXY_PORT: '8090'
PROXY_ALLOW_ORIGIN: ${OG_PROXY_ALLOW_ORIGIN:-http://localhost:5173}
PROXY_TIMEOUT_MS: '30000'
PROXY_MAX_BODY_BYTES: '5242880'
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true'
PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium-browser
networks: networks:
- jumble - jumble
restart: unless-stopped
# Optional: same as docker-compose.dev.yml — `docker compose --profile editor-tools up -d languagetool libretranslate` # Optional: same as docker-compose.dev.yml — `docker compose --profile editor-tools up -d languagetool libretranslate`
languagetool: languagetool:
@ -41,6 +45,12 @@ services:
container_name: jumble-libretranslate container_name: jumble-libretranslate
ports: ports:
- '5000:5000' - '5000:5000'
tty: true
environment:
LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,de}
volumes:
- ./.local-libretranslate/share:/home/libretranslate/.local/share
- ./.local-libretranslate/cache:/home/libretranslate/.local/cache
networks: networks:
- jumble - jumble
restart: unless-stopped restart: unless-stopped

7
package.json

@ -14,9 +14,12 @@
"homepage": "https://github.com/Silberengel/jumble", "homepage": "https://github.com/Silberengel/jumble",
"scripts": { "scripts": {
"dev": "vite --host", "dev": "vite --host",
"dev:all": "bash scripts/dev-all-local.sh",
"stack:remote": "bash scripts/stack-remote.sh",
"dev:refresh": "rm -rf node_modules/.vite && vite --host", "dev:refresh": "rm -rf node_modules/.vite && vite --host",
"docker:editor-tools": "docker compose -f docker-compose.dev.yml --profile editor-tools up -d languagetool libretranslate", "docker:prep-libretranslate": "bash scripts/ensure-libretranslate-dirs.sh",
"docker:local-ancillary": "docker compose -f docker-compose.dev.yml --profile editor-tools --profile local-tts up -d languagetool libretranslate piper-wyoming piper-tts-proxy", "docker:editor-tools": "bash scripts/ensure-libretranslate-dirs.sh && docker compose -f docker-compose.dev.yml --profile editor-tools up -d languagetool libretranslate",
"docker:local-ancillary": "bash scripts/ensure-libretranslate-dirs.sh && docker compose -f docker-compose.dev.yml --profile editor-tools --profile local-tts build piper-tts-proxy && docker compose -f docker-compose.dev.yml --profile editor-tools --profile local-tts up -d og-proxy languagetool libretranslate piper-wyoming piper-tts-proxy",
"piper-tts-proxy": "cross-env NODE_ENV=development npx --yes tsx services/piper-tts-proxy/http.ts", "piper-tts-proxy": "cross-env NODE_ENV=development npx --yes tsx services/piper-tts-proxy/http.ts",
"build": "tsc -b && vite build", "build": "tsc -b && vite build",
"lint": "eslint .", "lint": "eslint .",

13
scripts/dev-all-local.sh

@ -0,0 +1,13 @@
#!/usr/bin/env bash
# One local command: Docker backends + Vite (Ctrl+C stops Vite; Docker keeps running).
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
export OG_PROXY_ALLOW_ORIGIN="${OG_PROXY_ALLOW_ORIGIN:-http://localhost:5173}"
mkdir -p .local-piper-data
bash "$ROOT/scripts/ensure-libretranslate-dirs.sh"
docker compose -f docker-compose.dev.yml --profile editor-tools --profile local-tts build piper-tts-proxy
docker compose -f docker-compose.dev.yml --profile editor-tools --profile local-tts up -d \
og-proxy languagetool libretranslate piper-wyoming piper-tts-proxy
echo "[dev:all] Jumble=Vite (.env.development → /sites, /api/piper-tts, lab APIs) | og-proxy :8090 | Piper :9876"
exec npm run dev

10
scripts/ensure-libretranslate-dirs.sh

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Host dirs for LibreTranslate bind mounts must be writable by container UID 1032 (see docker-compose*.yml).
# Uses a one-shot Alpine container so you do not need sudo chown on the host.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
mkdir -p "$ROOT/.local-libretranslate/share" "$ROOT/.local-libretranslate/cache"
docker run --rm \
-v "$ROOT/.local-libretranslate/share:/s" \
-v "$ROOT/.local-libretranslate/cache:/c" \
alpine:3.20 chown -R 1032:1032 /s /c

14
scripts/stack-remote.sh

@ -0,0 +1,14 @@
#!/usr/bin/env bash
# One remote command from repo clone: silberengel/imwald-jumble + nip66 + wikistr og-proxy + wyoming-piper +
# imwald-piper-tts-proxy (built here; push silberengel/imwald-piper-tts-proxy:latest to Hub for pull-only hosts) +
# LanguageTool + LibreTranslate. Apache → 8089 / 8090 / 9876.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
bash "$ROOT/scripts/ensure-libretranslate-dirs.sh"
COMPOSE=(docker compose -f docker-compose.prod.yml --profile stack --profile editor-tools)
# Pull Hub images only; piper-tts-proxy is built from this repo (push silberengel/imwald-piper-tts-proxy:latest when ready).
"${COMPOSE[@]}" pull jumble jumble-nip66-monitor og-proxy piper-wyoming languagetool libretranslate
"${COMPOSE[@]}" build piper-tts-proxy
"${COMPOSE[@]}" up -d
echo "[stack:remote] jumble :8089 | og-proxy :8090 | piper HTTP :9876 | LT :8010 | translate :5000"

6
scripts/start-local-ancillary.sh

@ -1,12 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Start LanguageTool, LibreTranslate, Wyoming Piper, and the Piper HTTP proxy (Docker). # Prefer: npm run dev:all (backends + Vite in one go).
# Run the app separately: npm run dev # This script only starts Docker (no Vite): og-proxy, LanguageTool, LibreTranslate, Wyoming Piper, Piper HTTP proxy.
# Optional .env.local (Vite): VITE_READ_ALOUD_TTS_URL=/api/piper-tts VITE_LANGUAGE_TOOL_URL=/api/languagetool VITE_TRANSLATE_URL=/api/translate # Optional .env.local (Vite): VITE_READ_ALOUD_TTS_URL=/api/piper-tts VITE_LANGUAGE_TOOL_URL=/api/languagetool VITE_TRANSLATE_URL=/api/translate
set -euo pipefail set -euo pipefail
cd "$(dirname "$0")/.." cd "$(dirname "$0")/.."
mkdir -p .local-piper-data mkdir -p .local-piper-data
npm run docker:local-ancillary npm run docker:local-ancillary
echo echo
echo "Ancillary stack is up (LanguageTool :8010, LibreTranslate :5000, Piper proxy :9876)." echo "Ancillary stack is up (og-proxy :8090, LanguageTool :8010, LibreTranslate :5000, Piper HTTP :9876)."
echo "Wyoming Piper listens inside Docker only; the HTTP proxy on 127.0.0.1:9876 forwards to it." echo "Wyoming Piper listens inside Docker only; the HTTP proxy on 127.0.0.1:9876 forwards to it."
echo "Next: npm run dev" echo "Next: npm run dev"

Loading…
Cancel
Save