Skip to content

Commit e4abf91

Browse files
turegjorupclaude
andcommitted
feat: move Symfony sessions to Redis, env-configurable
framework.session.handler_id now reads from SESSION_HANDLER_DSN, which defaults to the existing REDIS_CACHE_DSN so dev (and prod that has Redis available) gets Redis-backed sessions out of the box. Operators can set SESSION_HANDLER_DSN= (empty) to fall back to PHP's native file handler. Why move: - Removes the per-session flock that serialises parallel session-touching requests on the file handler (visible as inconsistent tail latency when the React admin fires concurrent fetches). - Sessions survive container restarts without mounting /tmp as a volume. - Multi-pod deployments share session state without sticky routing — the OIDC handshake works regardless of which pod handles the callback. The new RedisSessionHandler is auto-built by Symfony from the DSN; it prefixes keys with `sf_s` so they don't collide with cache keys on the same Redis DB. when@test forces handler_id back to null, since MockFileSessionStorage doesn't go through a handler and we don't want the test container to compile a Redis handler against an env that may not point at a reachable Redis. Verified locally: HTTP request to /v2/authentication/oidc/urls writes a `sf_s<id>` key into Redis; full PHPUnit suite (143 tests, 607 assertions) passes with redis DBSIZE=0 after, confirming the test override works. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 665d38c commit e4abf91

3 files changed

Lines changed: 22 additions & 1 deletion

File tree

.env

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ JWT_SCREEN_REFRESH_TOKEN_TTL=2592000
7272
REDIS_CACHE_PREFIX=DisplayApiService
7373
# Connection string for Redis cache server.
7474
REDIS_CACHE_DSN=redis://redis:6379/0
75+
# Session storage backend, consumed by framework.session.handler_id.
76+
# A `redis://...` DSN makes Symfony auto-build a RedisSessionHandler (with
77+
# its own `sf_s` key prefix, so cache and session keys don't collide on
78+
# the same DB). Empty value = PHP's native file handler; pick that for
79+
# single-pod deployments that don't care about flock-induced tail latency
80+
# or container-restart session survival.
81+
SESSION_HANDLER_DSN=${REDIS_CACHE_DSN}
7582
###< redis ###
7683

7784
###> Http Client ###

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ All notable changes to this project will be documented in this file.
1010
- Aligned API and Nginx image labels with the OCI image spec: dropped deprecated `LABEL maintainer`,
1111
added `org.opencontainers.image.{authors,vendor,documentation,base.name}`, and fixed the Nginx image's
1212
`title`/`description` so it stops inheriting the source-repo defaults.
13+
- Switched Symfony session storage to Redis (default `SESSION_HANDLER_DSN=${REDIS_CACHE_DSN}`); set
14+
`SESSION_HANDLER_DSN=` empty to fall back to PHP's native file handler. Removes the per-session
15+
`flock` that serialised parallel session-touching requests and lets sessions survive container
16+
restarts; multi-pod deployments now share session state without sticky routing.
1317

1418
## [3.0.0-rc2] - 2026-05-05
1519

config/packages/framework.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ framework:
99
# Enables session support. Note that the session will ONLY be started if you read or write from it.
1010
# Remove or comment this section to explicitly disable session support.
1111
session:
12-
handler_id: null
12+
# Empty falls back to PHP's native file handler; a `redis://...` DSN
13+
# makes Symfony auto-build a RedisSessionHandler. See SESSION_HANDLER_DSN
14+
# in .env. Redis-backed sessions remove the per-session flock that
15+
# serialises parallel requests on the file handler and survive
16+
# container restarts; local dev gets the same behaviour because the
17+
# default DSN points at the compose Redis.
18+
handler_id: '%env(SESSION_HANDLER_DSN)%'
1319
cookie_secure: auto
1420
cookie_samesite: lax
1521
storage_factory_id: session.storage.factory.native
@@ -33,4 +39,8 @@ when@test:
3339
framework:
3440
test: true
3541
session:
42+
# MockFileSessionStorage keeps tests off Redis; force handler_id
43+
# back to native so the Redis handler service isn't compiled
44+
# against an env that may not point at a reachable Redis.
45+
handler_id: null
3646
storage_factory_id: session.storage.factory.mock_file

0 commit comments

Comments
 (0)