fix: Redis client initialization at runtime vs build time

- Add `dynamic = 'force-dynamic'` to /api/build-info route to prevent
  static caching of runtime values (hostname, REDIS_URL, etc.)
- Fix Redis client singleton to retry initialization if REDIS_URL
  wasn't set at build time but is set at runtime
- Update Traefik health check from `/` to `/api/health` for better
  health checking (verifies database connectivity)

The issue was that Next.js was evaluating redis.ts at build time
(when REDIS_URL isn't set in Docker buildkit), caching `null` as the
client, and never re-checking at runtime. Now it retries if the env
var becomes available.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2026-01-15 19:17:46 -06:00
parent c9899eddb7
commit 1483de3acd
2 changed files with 14 additions and 2 deletions

View File

@@ -3,6 +3,10 @@ import { hostname } from 'os'
import buildInfo from '@/generated/build-info.json'
import { getRedisClient, isRedisAvailable } from '@/lib/redis'
// Force dynamic evaluation - this route must not be statically cached
// because it reads runtime environment variables and system state
export const dynamic = 'force-dynamic'
export async function GET() {
const redis = getRedisClient()

View File

@@ -21,13 +21,21 @@ let redisInitialized = false
* Returns null if REDIS_URL is not set in environment.
*/
export function getRedisClient(): Redis | null {
if (redisInitialized) {
const redisUrl = process.env.REDIS_URL
// If we've already initialized with a client, return it
if (redisInitialized && redisClient) {
return redisClient
}
// If we initialized but got null AND REDIS_URL is still not set, return null
// But if REDIS_URL is NOW set (e.g., build-time vs runtime), try again
if (redisInitialized && !redisUrl) {
return null
}
redisInitialized = true
const redisUrl = process.env.REDIS_URL
if (!redisUrl) {
console.log('[Redis] REDIS_URL not set, using in-memory storage')
return null