Redis in Ubersmith - Advanced Guide Estimated Reading Time: 10 Minutes Overview Ubersmith uses Redis as a fast, in-memory data store that backs several core parts of the application: user sessions, general-purpose caching, the internal background job queue, distributed locking, data export jobs, and per-plugin storage. Because so much depends on it, Redis should be treated as a required infrastructure component in production, not an optional performance boost. In a standard Ubersmith deployment, Redis runs as two separate container groups, managed for you by the installer: redis-data — a single Redis instance holding all of the durable, persisted data described below (sessions, caching, the queue, plugin logs). redis — a group of three independent, non-clustered Redis instances used exclusively for distributed locking. These do not replicate to each other; they're used together only to reach quorum for the locking algorithm (see Distributed locking below). Ubersmith also supports Redis Sentinel as an optional add-on for redis-data, giving it automatic failover to a replica if the primary node goes down. You will not normally interact with Redis configuration directly — the installer wires up connection details for you, and the application's internal config file is generated automatically at container startup from environment variables. This document explains what Redis is used for, how it's deployed, what you can configure, and the pitfalls to plan around. What Redis is used for Ubersmith doesn't use a single Redis connection for everything — different subsystems connect to different logical databases (by index) on redis-data, and each subsystem behaves differently if Redis becomes unavailable. This matters because not every subsystem degrades gracefully. Subsystem Purpose Redis database If Redis is unreachable Sessions Stores PHP session data and session locks redis-data, database 0 Sessions cannot be read or written — the site becomes inaccessible to logged-in users until Redis recovers Application storage / cache Caches computed values and general key/value storage used throughout the app, including the plugin SDK key/value store and the client-brand lookup cache redis-data, database 2 Mostly degrades gracefully — general cache operations fail silently and are treated as cache misses, and the client-brand lookup falls back to a direct database query. Plugin data access (e.g. exporter plugins for Intacct, QuickBooks Online) may fail without a fallback. Background job queue Powers Ubersmith's internal queuing system, and doubles as the backing store for data export job state/progress redis-data, database 4 Queue jobs cannot be published or consumed, and export jobs cannot run or track progress — background processing stops Plugin debug/execution logging Stores plugin execution and debug log entries redis-data, database 3 Logging is skipped; does not affect core functionality Distributed locking (Redlock) Coordinates locks across app instances so certain operations run one at a time dedicated redis service (3 independent instances), database 1 on each Tolerates one of the three lock instances being down (quorum-based); fails only if too few instances are reachable The takeaway: sessions, the queue, and export processing are hard dependencies with no fallback. General caching and the client-brand lookup are soft dependencies that degrade gracefully to the database. Keep this distinction in mind when planning Redis maintenance windows. How Redis is deployed A standard Ubersmith installation is deployed via Docker Compose, generated and managed by the Ubersmith installer. You don't hand-write Redis connection strings or edit Ubersmith's internal config file — the web container's startup script generates that file automatically from environment variables the installer sets for you, and the rest of the application containers (php, cron, mail) read the result from a shared volume. In practice, this means: The redis-data container is provisioned automatically and used for sessions, application storage/cache, plugin logs, and the queue (databases 0, 2, 3, and 4, respectively — see the table above). The redis container is provisioned as three instances (docker compose up --scale redis=3 -d redis) dedicated to distributed locking, independent of redis-data. Redis data is persisted to a named Docker volume (redis) mounted into redis-data, and a redis-backup utility container periodically archives that volume — see Backups & persistence. An optional redis-commander container provides a web UI (on port 8081) for inspecting Redis data directly. It's not started automatically (restart: no) — start it manually if you need to look inside Redis, and be aware it points at database 3 (plugin logs) by default rather than the databases used for sessions or caching. The handful of Redis-related settings you can control live in your deployment's Compose override file, as environment variables on the web service — most commonly to enable Redis Sentinel (below) or to configure authentication. High availability with Redis Sentinel By default, redis-data is a single instance. If it goes down, every subsystem that depends on it is affected until it comes back. Redis Sentinel adds automatic failover: a set of Sentinel processes monitor a Redis primary and its replicas (run and managed outside of the standard Ubersmith Compose stack), and promote a replica to primary if the current one becomes unreachable. Sentinel support applies only to redis-data — the three-instance locking redis service has its own, separate resilience model (quorum across independent nodes; see Distributed locking) and is not managed by Sentinel. How it works in Ubersmith When Sentinel is enabled, Ubersmith no longer connects to a fixed Redis host for redis-data. Instead, on each connection it asks one of the configured Sentinel instances "who is the current primary for <master name>?", gets back an address and port, and connects to that address for the duration of the request. Ubersmith also verifies the node it connects to reports itself as a primary before using it, as an extra safety check against talking to a stale replica. Enabling it Redis Sentinel is off by default. To turn it on, set the following environment variables on the web service in your deployment's Compose override file (these are present but commented out in the default template): web: environment: REDIS_SENTINEL_ENABLE: 1 REDIS_SENTINEL_MASTER: mymaster REDIS_USER: your_redis_user REDIS_AUTH: your_redis_password REDIS_SENTINEL_HOSTS: 10.0.0.1,10.0.0.2,10.0.0.3 REDIS_SENTINEL_MASTER must match the name your Sentinels are configured to monitor (the name used in sentinel monitor <name> <host> <port> <quorum> on the Sentinel side). REDIS_SENTINEL_HOSTS is a comma-separated list of Sentinel hosts/IPs; Ubersmith assumes the standard Sentinel port (26379) on each and tries them in order, moving on to the next if one is unreachable. It only fails if all configured Sentinels are unreachable. REDIS_USER and REDIS_AUTH are only required if your Redis/Sentinel deployment uses authentication — see Authentication & security. You still need a real, reachable primary/replica set behind the scenes — Sentinel here is an operational layer you stand up and manage (a primary plus replicas, monitored by an odd number of Sentinel processes, ideally three or more so a majority quorum can be reached even if one Sentinel is unreachable) rather than something the standard Ubersmith Compose stack provisions for you. What to expect operationally Switching between Sentinel and non-Sentinel mode does not migrate data. The Sentinel-managed primary/replica set is a separate dataset from the standalone redis-data container. Toggling REDIS_SENTINEL_ENABLE between 0 and 1 points Ubersmith at a different dataset — sessions, cached data, and queued jobs from one will not be visible under the other. Plan any migration between modes accordingly (e.g. during a maintenance window, accepting that active sessions will be invalidated). Network access: every service that talks to Redis (web, php, cron, mail) needs network access to both the Sentinel ports (default 26379) and to all Redis primary/replica nodes, since the primary address can change at any time. Authentication & security If your Redis deployment requires authentication, set REDIS_USER and REDIS_AUTH as environment variables on the web service in your Compose override file. The startup script applies these credentials automatically to every relevant connection (sessions, application storage, plugin logs, and the queue) — you don't need to edit connection strings by hand. Note that REDIS_USER/REDIS_AUTH apply to redis-data only. The dedicated locking redis service does not currently support authentication through these variables. Distributed locking Separate from redis-data, Ubersmith runs a group of three independent, non-clustered redis instances used only to coordinate distributed locks — for example, to make sure certain operations run one at a time across multiple application containers. These three instances don't replicate to each other or share any other data; each one just needs to be reachable so the locking algorithm can reach a majority (2 of 3) to grant or release a lock. Because it's quorum-based, this design tolerates one of the three instances being down — locking keeps working, just with less margin. If two or more are unreachable, lock acquisition fails outright rather than allowing operations to proceed unsafely. This is a deliberate trade-off (favoring safety over availability) and is not configurable. This locking service is independent of Redis Sentinel — it isn't a primary/replica pair, so there's no "failover" concept here; resilience comes purely from running three separate instances and requiring only a majority. Backups & persistence Only redis-data holds data worth persisting long-term (sessions, application cache, plugin logs, and the queue); the three-instance locking redis service holds only short-lived lock state and isn't backed up. redis-data's data lives on a named Docker volume (redis), so it survives container restarts and recreation as long as the volume itself isn't removed. A redis-backup utility container can be used to back up that volume to a compressed file on the host, giving you a point-in-time snapshot to restore from if needed. Keep in mind that a Redis backup is a snapshot of a fast-moving, in-memory dataset — session and queue state can be seconds old by the time it's restored. Treat Redis backups as a safety net for disaster recovery, not as a substitute for keeping Redis itself healthy and available. Pitfalls & limitations Sessions, the queue, and export processing are hard dependencies with no fallback. Unlike general caching, there is no code path that lets Ubersmith keep working without redis-data for these subsystems — plan maintenance windows accordingly. Sentinel failover has a real, user-visible outage window (tens of seconds), primarily affecting sessions. This is expected behavior, not a bug. Switching between Sentinel-managed and standalone redis-data does not carry data over. Treat it as a distinct dataset, not a live migration. Redis Sentinel only protects redis-data. The distributed-locking redis service is resilient in a different way (three independent instances, majority quorum) and isn't part of your Sentinel setup. Losing two of the three locking redis instances stops lock acquisition outright, even though the third instance is healthy — this is intentional (favors correctness over uptime), but it means the locking service needs its own attention during infrastructure maintenance, separate from redis-data. Plugin debug/execution logs are stored as a capped Redis list, not a searchable log store — there's no filtering by log level or timestamp. Don't rely on it as a substitute for a proper log aggregation system if you need to search or retain logs long-term. redis-commander defaults to database 3 (plugin logs). If you use it to inspect Redis and don't see the data you expect, check you're looking at the right logical database — sessions, cache, and the queue live on different ones. Redis backups only cover redis-data. The locking redis instances hold only transient state and are intentionally excluded — don't expect a backup/restore cycle to preserve in-flight locks (nor would you want it to). Troubleshooting checklist "Could not connect to Redis Database" errors: check basic network reachability to redis-data (or the locking redis instances, depending on which subsystem is affected). Check application logs for the underlying error — connection failures are logged with more detail than is shown to end users. Authentication failures: verify REDIS_USER/REDIS_AUTH are set correctly on the web service — remember these apply to redis-data only, not the locking redis instances. All Sentinels unreachable: Ubersmith only raises this once every configured Sentinel host in REDIS_SENTINEL_HOSTS fails to respond — check that those addresses and the Sentinel port (default 26379) are correct and reachable from the application containers. Lock acquisition failures with the other Redis-backed subsystems otherwise healthy: check the three locking redis instances specifically — this points to two or more of them being unreachable, which breaks quorum even if redis-data is fine. Site-wide inaccessibility with no other errors: check redis-data health first, since sessions are a hard dependency — this is the most common symptom of a Redis outage or a Sentinel failover in progress.