You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

150 lines
5.9 KiB

# Production stack: jumble + NIP-66 monitor + og-proxy + Wyoming Piper + Piper HTTP proxy + LanguageTool + LibreTranslate.
# `docker compose up -d` starts every service here (including piper-tts-proxy) if images exist; it only pulls images that are missing locally. To refresh :latest first: `docker compose pull` or `docker compose up -d --pull always`.
# Remote: docker compose -f docker-compose.prod.yml pull && docker compose -f docker-compose.prod.yml up -d
# First-time LibreTranslate + Piper models: bash scripts/ensure-libretranslate-dirs.sh (see scripts/README-deploy.md).
# Images built/pushed by ./scripts/build-and-push-prod.sh (app, monitor, piper-tts-proxy); others pull from Hub.
#
# Apache (unchanged on your host) should keep (order: specific paths before catch-all /):
# ProxyPass /sites/ http://127.0.0.1:8090/sites/
# ProxyPass /api/piper-tts http://127.0.0.1:9876/api/piper-tts
# ProxyPassReverse /api/piper-tts http://127.0.0.1:9876/api/piper-tts
# ProxyPass / http://127.0.0.1:8089/
# so the browser hits same-origin /api/piper-tts → piper HTTP proxy (see services/piper-tts-proxy + PROXY_SETUP.md); /sites/ → OG proxy; else static SPA on 8089.
# VITE_PROXY_SERVER / VITE_READ_ALOUD_TTS_URL are baked at image build — see scripts/build-and-push-prod.sh
#
# NIP-66 monitor: set NIP66_MONITOR_NSEC (and optionally NIP66_MONITOR_NPUB) in the host env or .env.
# - Cron service `jumble-nip66-monitor` (Imwald NIP-66 monitor image) uses NIP66_MONITOR_NSEC to publish 30166/10166; nsec never goes to the client.
# - Set NIP66_MONITOR_NPUB (npub1... derived from the same key) so the relay info page shows the monitor's avatar and handle in the NIP-66 liveliness section.
#
# Apache (or nginx) must proxy same-origin paths baked into the SPA, e.g. /api/languagetool → http://127.0.0.1:8010
# and /api/translate → http://127.0.0.1:5000. Build the app with:
# LANGUAGE_TOOL_URL=/api/languagetool TRANSLATE_URL=/api/translate ./scripts/build-and-push-prod.sh
services:
jumble:
image: silberengel/imwald-jumble:latest
container_name: imwald-jumble
ports:
- "8089:80"
restart: unless-stopped
# Do NOT pass NIP66_MONITOR_NSEC to the web app; only npub is needed for the relay info page.
environment:
- NIP66_MONITOR_NPUB=${NIP66_MONITOR_NPUB}
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
deploy:
resources:
limits:
memory: 512M
# NIP-66 relay monitor cron: publishes 30166 (relay discovery) and 10166 (announcement).
# Starts and stops with the app. Requires NIP66_MONITOR_NSEC to do anything.
jumble-nip66-monitor:
image: silberengel/imwald-jumble-nip66-monitor:latest
container_name: imwald-jumble-nip66-monitor
restart: unless-stopped
environment:
- NIP66_MONITOR_NSEC=${NIP66_MONITOR_NSEC}
- RELAYS_TO_MONITOR=${RELAYS_TO_MONITOR:-}
- RELAY_LIST_SKIP_KIND10002=${RELAY_LIST_SKIP_KIND10002:-}
- MAX_RELAYS_TO_MONITOR=${MAX_RELAYS_TO_MONITOR:-}
- PUBLISH_RELAYS=${PUBLISH_RELAYS:-}
- INTERVAL_MS=${INTERVAL_MS:-}
# Default: merge built-in relay list + monitor’s kind 10002 (`r` tags). See nip66-cron/index.mjs.
# - RELAYS_TO_MONITOR — optional; replaces merged list entirely
# - RELAY_LIST_SKIP_KIND10002=1 — defaults only (no 10002 fetch)
logging:
driver: json-file
options:
max-size: "5m"
max-file: "2"
deploy:
resources:
limits:
memory: 128M
languagetool:
image: silviof/docker-languagetool:latest
container_name: imwald-languagetool
ports:
- '127.0.0.1:8010:8010'
restart: unless-stopped
deploy:
resources:
limits:
memory: 2048M
libretranslate:
image: libretranslate/libretranslate:latest
container_name: imwald-libretranslate
ports:
- '127.0.0.1:5000:5000'
tty: true
env_file:
- ./scripts/libretranslate-lt.default.env
environment:
LT_UPDATE_MODELS: ${LT_UPDATE_MODELS:-true}
volumes:
# One tree under .local (same as upstream run.sh -v …/lt-local:/home/libretranslate/.local); avoids split-mount permission edge cases.
- ./.local-libretranslate:/home/libretranslate/.local
restart: unless-stopped
deploy:
resources:
limits:
memory: 2048M
# OG proxy + Piper (Apache → 8090 / 9876). Piper HTTP image: silberengel/imwald-piper-tts-proxy (see build-and-push-prod.sh).
og-proxy:
image: ${OG_PROXY_IMAGE:-silberengel/wikistr:latest-og-proxy}
# Distinct name so `docker compose` does not assume an unrelated `og-proxy` container belongs to this project.
container_name: imwald-og-proxy
dns:
- 1.1.1.1
- 8.8.8.8
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}
# Distinct from ad-hoc stacks named `piper-tts`; Piper HTTP proxy reaches this service as `piper-wyoming`.
container_name: imwald-piper-wyoming
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:
container_name: imwald-piper-tts-proxy
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: