# Minimal compose for running the published image (e.g. on remote server). # 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 /): # 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. # # Optional editor tools (LanguageTool + LibreTranslate): profile `editor-tools` # docker compose -f docker-compose.prod.yml --profile editor-tools up -d languagetool libretranslate # Then 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 image 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 profiles: ['editor-tools'] container_name: imwald-languagetool ports: - '127.0.0.1:8010:8010' restart: unless-stopped deploy: resources: limits: memory: 2048M libretranslate: image: libretranslate/libretranslate:latest profiles: ['editor-tools'] container_name: imwald-libretranslate ports: - '127.0.0.1:5000:5000' tty: true environment: LT_LOAD_ONLY: ${LT_LOAD_ONLY:-en,de,es,fr,it,pt,ru,zh,ja,ar} LT_UPDATE_MODELS: ${LT_UPDATE_MODELS:-true} volumes: - ./.local-libretranslate/share:/home/libretranslate/.local/share - ./.local-libretranslate/cache:/home/libretranslate/.local/cache restart: unless-stopped deploy: resources: limits: 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 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} 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: