Session directory is unwritable by the server user, so sessions silently never persist #23

Closed
opened 2026-08-04 11:25:04 +00:00 by geusebio · 0 comments
Owner

session.save_path points at a directory the server user cannot write, so every request
loses its session and nobody can stay logged in
.

$ docker run --rm --entrypoint sh matthewbaggett/frankenphp:8.5 -c 'php -i | grep session.save_path; ls -ld /var/lib/php-zts/session'
session.save_path => /var/lib/php-zts/session => /var/lib/php-zts/session
drwxrwx---    2 root     frankenphp      4096 Jul 25 17:41 /var/lib/php-zts/session

The directory is root:frankenphp 0770, but /etc/services.d/frankenphp/run starts the
server as app — which is neither the owner nor (effectively) in the group. Every request
logs:

Warning: SessionHandler::read(): open(/var/lib/php-zts/session/sess_…, O_RDWR) failed: Permission denied (13)
Warning: SessionHandler::write(): open(/var/lib/php-zts/session/sess_…, O_RDWR) failed: Permission denied (13)
Warning: session_write_close(): Failed to write session data with "…\StrictSessionHandler" handler

These are warnings, not errors, so the app looks like it is working — it just never keeps
anyone logged in. In our case it failed 10 of 11 Playwright E2E tests, all of which begin
by signing in.

Note on the obvious fix

addgroup app frankenphp does not work, because of #22chpst -u app drops
supplementary groups. Until #22 is fixed the only thing that helps is ownership by uid:

RUN chown -R app /var/lib/php-zts/session

Best fixed here in the base image, since the image is what chooses both the save_path
and the user the server runs as. matthewbaggett/php:8.5 leaves save_path empty, so PHP
falls back to /tmp and the problem does not arise there.

`session.save_path` points at a directory the server user cannot write, so **every request loses its session and nobody can stay logged in**. ``` $ docker run --rm --entrypoint sh matthewbaggett/frankenphp:8.5 -c 'php -i | grep session.save_path; ls -ld /var/lib/php-zts/session' session.save_path => /var/lib/php-zts/session => /var/lib/php-zts/session drwxrwx--- 2 root frankenphp 4096 Jul 25 17:41 /var/lib/php-zts/session ``` The directory is `root:frankenphp 0770`, but `/etc/services.d/frankenphp/run` starts the server as `app` — which is neither the owner nor (effectively) in the group. Every request logs: ``` Warning: SessionHandler::read(): open(/var/lib/php-zts/session/sess_…, O_RDWR) failed: Permission denied (13) Warning: SessionHandler::write(): open(/var/lib/php-zts/session/sess_…, O_RDWR) failed: Permission denied (13) Warning: session_write_close(): Failed to write session data with "…\StrictSessionHandler" handler ``` These are warnings, not errors, so the app looks like it is working — it just never keeps anyone logged in. In our case it failed 10 of 11 Playwright E2E tests, all of which begin by signing in. ### Note on the obvious fix `addgroup app frankenphp` does **not** work, because of #22 — `chpst -u app` drops supplementary groups. Until #22 is fixed the only thing that helps is ownership by uid: ```dockerfile RUN chown -R app /var/lib/php-zts/session ``` Best fixed here in the base image, since the image is what chooses both the `save_path` and the user the server runs as. `matthewbaggett/php:8.5` leaves `save_path` empty, so PHP falls back to `/tmp` and the problem does not arise there.
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/docker#23
No description provided.