From e1621a3ec29d9e097f5615819cbc23c69fa8fdcd Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 31 Mar 2026 18:26:32 +0500 Subject: [PATCH] fix(infra): move Redis to prod, fix LibreTranslate config loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Redis sidecar to prod docker-compose; backend connects locally (redis:6379) - Caddy layer4 now proxies redis.libnovel.cc:6380 → local redis:6379 (not homelab LAN) - Remove HOMELAB_REDIS_ADDR; homelab runner connects out to prod Redis via rediss:// - Remove local Redis from homelab runner compose; drop redis_data volume - Fix config.Load() missing LibreTranslate section — LIBRETRANSLATE_URL was never read --- Caddyfile | 6 +++--- backend/internal/config/config.go | 5 +++++ docker-compose.yml | 34 ++++++++++++++++++++++++------- homelab/runner/docker-compose.yml | 27 +++++------------------- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/Caddyfile b/Caddyfile index d80e2a7..8fdc7b5 100644 --- a/Caddyfile +++ b/Caddyfile @@ -58,9 +58,9 @@ } # ── Redis TCP proxy via layer4 ──────────────────────────────────────────── - # Exposes homelab Redis over TLS for Asynq job enqueueing from the backend. + # Exposes prod Redis over TLS for Asynq job enqueueing from the homelab runner. # Listens on :6380 (all interfaces). TLS is terminated here using the cert - # for redis.libnovel.cc; traffic is proxied to the homelab Redis instance. + # for redis.libnovel.cc; traffic is proxied to the local Redis sidecar. # Requires the caddy-l4 module in the custom Caddy build. layer4 { :6380 { @@ -73,7 +73,7 @@ } } proxy { - upstream {$HOMELAB_REDIS_ADDR:192.168.0.109:6379} + upstream redis:6379 } } } diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 2232901..8da987c 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -203,6 +203,11 @@ func Load() Config { URL: envOr("POCKET_TTS_URL", ""), }, + LibreTranslate: LibreTranslate{ + URL: envOr("LIBRETRANSLATE_URL", ""), + APIKey: envOr("LIBRETRANSLATE_API_KEY", ""), + }, + HTTP: HTTP{ Addr: envOr("BACKEND_HTTP_ADDR", ":8080"), }, diff --git a/docker-compose.yml b/docker-compose.yml index 0797c36..dd81221 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -126,6 +126,26 @@ services: timeout: 5s retries: 5 + # ─── Redis (Asynq task queue — accessed locally by backend, remotely by homelab runner) ── + redis: + image: redis:7-alpine + restart: unless-stopped + command: > + redis-server + --appendonly yes + --requirepass "${REDIS_PASSWORD}" + # No public port — backend reaches it via internal network. + # Homelab runner reaches it via Caddy TLS proxy on :6380 → redis:6379. + expose: + - "6379" + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] + interval: 10s + timeout: 5s + retries: 5 + # ─── Backend API ────────────────────────────────────────────────────────────── backend: image: kalekber/libnovel-backend:${GIT_TAG:-latest} @@ -151,6 +171,8 @@ services: condition: service_healthy valkey: condition: service_healthy + redis: + condition: service_healthy # No public port — all traffic is routed via Caddy. expose: - "8080" @@ -164,10 +186,9 @@ services: GLITCHTIP_DSN: "${GLITCHTIP_DSN}" OTEL_EXPORTER_OTLP_ENDPOINT: "${OTEL_EXPORTER_OTLP_ENDPOINT}" OTEL_SERVICE_NAME: "backend" - # Asynq task queue — backend enqueues jobs to homelab Redis via Caddy TLS proxy. - # Set to "rediss://:password@redis.libnovel.cc:6380" in Doppler prd config. - # Leave empty to fall back to PocketBase polling. - REDIS_ADDR: "${REDIS_ADDR}" + # Asynq task queue — backend enqueues jobs to local Redis sidecar. + # Homelab runner connects to the same Redis via Caddy TLS proxy on :6380. + REDIS_ADDR: "redis:6379" REDIS_PASSWORD: "${REDIS_PASSWORD}" healthcheck: test: ["CMD", "/healthcheck", "http://localhost:8080/health"] @@ -382,12 +403,10 @@ services: - "80:80" - "443:443" - "443:443/udp" # HTTP/3 (QUIC) - - "6380:6380" # Redis TCP proxy (TLS) for homelab → Asynq + - "6380:6380" # Redis TCP proxy (TLS) for homelab runner → Asynq environment: DOMAIN: "${DOMAIN}" CADDY_ACME_EMAIL: "${CADDY_ACME_EMAIL}" - # Homelab Redis address — Caddy TCP-proxies inbound :6380 to this. - HOMELAB_REDIS_ADDR: "${HOMELAB_REDIS_ADDR:?HOMELAB_REDIS_ADDR required for Redis TCP proxy}" env_file: - path: ./crowdsec/.crowdsec.env required: false @@ -421,6 +440,7 @@ volumes: pb_data: meili_data: valkey_data: + redis_data: caddy_data: caddy_config: caddy_logs: diff --git a/homelab/runner/docker-compose.yml b/homelab/runner/docker-compose.yml index b02c167..655218e 100644 --- a/homelab/runner/docker-compose.yml +++ b/homelab/runner/docker-compose.yml @@ -11,25 +11,10 @@ # - MEILI_URL → https://search.libnovel.cc (Caddy-proxied) # - VALKEY_ADDR → unset (not exposed publicly) # - RUNNER_SKIP_INITIAL_CATALOGUE_REFRESH=true -# - Redis service for Asynq task queue (local to homelab, exposed to prod via Caddy TCP proxy) +# - REDIS_ADDR → rediss://redis.libnovel.cc:6380 (prod Redis via Caddy TLS proxy) # - LibreTranslate service for machine translation (internal network only) services: - redis: - image: redis:7-alpine - restart: unless-stopped - volumes: - - redis_data:/data - command: > - redis-server - --appendonly yes - --requirepass "${REDIS_PASSWORD}" - healthcheck: - test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] - interval: 10s - timeout: 5s - retries: 5 - libretranslate: image: libretranslate/libretranslate:latest restart: unless-stopped @@ -55,8 +40,6 @@ services: restart: unless-stopped stop_grace_period: 135s depends_on: - redis: - condition: service_healthy libretranslate: condition: service_healthy environment: @@ -91,9 +74,10 @@ services: LIBRETRANSLATE_URL: "http://libretranslate:5000" LIBRETRANSLATE_API_KEY: "${LIBRETRANSLATE_API_KEY}" - # ── Asynq / Redis (local service) ─────────────────────────────────────── - # The runner connects to the local Redis sidecar. - REDIS_ADDR: "redis:6379" + # ── Asynq / Redis (prod Redis via Caddy TLS proxy) ────────────────────── + # The runner connects to prod Redis over TLS: rediss://redis.libnovel.cc:6380. + # Caddy on prod terminates TLS and proxies to the local redis:6379 sidecar. + REDIS_ADDR: "${REDIS_ADDR}" REDIS_PASSWORD: "${REDIS_PASSWORD}" # ── Runner tuning ─────────────────────────────────────────────────────── @@ -117,6 +101,5 @@ services: retries: 3 volumes: - redis_data: libretranslate_models: libretranslate_db: