Harden the Redis layer for production.
- Locks no longer fail open: an unreachable backend throws LockUnavailableError and withLock skips the run (or opts into running unlocked, as template seeding does). The lnbits payment poller keeps polling through an outage, made safe by only sending confirmation emails when a row actually transitioned. - Rate limiter INCR+PEXPIRE now runs as one Lua script, self-healing counters stranded without a TTL. - Per-email login lockout moves to a Redis-backed store shared across replicas (in-memory fallback preserved), case-insensitive on email. - Graceful shutdown on SIGTERM/SIGINT: stop periodic jobs, close the server, force-close lingering SSE sockets, close Redis. - Active PING probe backs the health flag; /health reports last ping. SSE payment streams also poll the DB as a pub/sub-gap fallback. - Scale compose gains requirepass, maxmemory 256mb with noeviction, and an authenticated healthcheck; .env.example documents passwords, TLS (rediss://), and DB-index selection. - First tests in the repo: vitest + ioredis-mock covering the lock, rate limiter, and login lockout stores (27 tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
71c277045b
commit
e38d14970d
+11
-3
@@ -22,10 +22,18 @@ DATABASE_URL=./data/spanglish.db
|
||||
# Note: running more than one instance requires DB_TYPE=postgres. SQLite is a
|
||||
# single local file and cannot be shared safely across instances.
|
||||
|
||||
# Redis connection URL. When set, the cache, rate limiter, pub/sub (real-time
|
||||
# payment events), distributed locks, and the email hourly cap are shared across
|
||||
# all instances. When unset, each instance uses in-memory equivalents.
|
||||
# Redis connection URL. When set, the cache, rate limiter, login lockout,
|
||||
# pub/sub (real-time payment events), distributed locks, and the email hourly
|
||||
# cap are shared across all instances. When unset, each instance uses in-memory
|
||||
# equivalents.
|
||||
#
|
||||
# In production always set a password (requirepass on the server) and put it in
|
||||
# the URL. Use the rediss:// scheme for TLS (handled natively by the client),
|
||||
# and an optional /N path to select a DB index when sharing a Redis instance
|
||||
# with other applications.
|
||||
# REDIS_URL=redis://localhost:6379
|
||||
# REDIS_URL=redis://:your-redis-password@redis.internal:6379
|
||||
# REDIS_URL=rediss://:your-redis-password@redis.example.com:6380/1
|
||||
|
||||
# Optional S3-compatible object storage for media uploads (e.g. Garage, MinIO,
|
||||
# AWS S3). When S3_ENDPOINT and S3_BUCKET are set, uploads go to the bucket and
|
||||
|
||||
Reference in New Issue
Block a user