Repository navigation
Introduced redis session handler does not work with non-root images #763
Copy link
Copy link
Open
Labels
integration: memcacheIntegration with any Nextcloud supported Memcached (Redis, Memcached, etc)Integration with any Nextcloud supported Memcached (Redis, Memcached, etc)rootlessRunning in Docker w/o rootRunning in Docker w/o rootuserRunning containers under a different userRunning containers under a different userwontfix
Description
In commit 83ea69d, a redis session handler was intrododuced. But the file /usr/local/etc/php/conf.d/redis-session.ini can not be written when using a non-root image, because the folder is owned by root and the default www-data user does not have write permission.
/var/www/html # ls -lha /usr/local/etc/php/conf.d
total 72
drwxr-xr-x 1 root root 4.0K Feb 26 08:50 .
drwxr-xr-x 1 root root 4.0K Feb 26 07:34 ..
-rw-r--r-- 1 root root 35 Feb 26 08:50 docker-php-ext-apcu.ini
-rw-r--r-- 1 root root 18 Feb 26 08:47 docker-php-ext-exif.ini
-rw-r--r-- 1 root root 16 Feb 26 08:47 docker-php-ext-gd.ini
-rw-r--r-- 1 root root 21 Feb 26 08:50 docker-php-ext-imagick.ini
-rw-r--r-- 1 root root 18 Feb 26 08:48 docker-php-ext-intl.ini
-rw-r--r-- 1 root root 18 Feb 26 08:48 docker-php-ext-ldap.ini
-rw-r--r-- 1 root root 23 Feb 26 08:50 docker-php-ext-memcached.ini
-rw-r--r-- 1 root root 82 Feb 26 08:48 docker-php-ext-opcache.ini
-rw-r--r-- 1 root root 19 Feb 26 08:48 docker-php-ext-pcntl.ini
-rw-r--r-- 1 root root 23 Feb 26 08:49 docker-php-ext-pdo_mysql.ini
-rw-r--r-- 1 root root 23 Feb 26 08:49 docker-php-ext-pdo_pgsql.ini
-rw-r--r-- 1 root root 19 Feb 26 08:50 docker-php-ext-redis.ini
-rw-r--r-- 1 root root 20 Feb 26 07:34 docker-php-ext-sodium.ini
-rw-r--r-- 1 root root 17 Feb 26 08:49 docker-php-ext-zip.ini
-rw-r--r-- 1 root root 18 Feb 26 08:50 memory-limit.ini
-rw-r--r-- 1 root root 189 Feb 26 08:50 opcache-recommended.ini
For running my nextcloud image, I use the default non-privileged user www-data.
/var/www/html $ id
uid=82(www-data) gid=82(www-data) groups=82(www-data)
Reacted by Felix Meyer-Wolters, Pierre de Lespinay, Tom Vincent, Vyacheslav, Greg G., Simon Kolkmann, Antonin Delpeuch, Dennis Zhang, skaa, suurt8ll and 8 more
Reacted by Adam Monsen
Metadata
Metadata
Assignees
Labels
integration: memcacheIntegration with any Nextcloud supported Memcached (Redis, Memcached, etc)Integration with any Nextcloud supported Memcached (Redis, Memcached, etc)rootlessRunning in Docker w/o rootRunning in Docker w/o rootuserRunning containers under a different userRunning containers under a different userwontfix
Activity
Fixes nextcloud#763, non-root usage with enabled redis session handler
Fixes nextcloud#763, non-root usage with enabled redis session handler
smueller18 commentedon May 30, 2019
Here is a command to reproduce this behavior:
[-]Introduced redis session handler breaks entrypoint of non-root images[/-][+]Introduced redis session handler does not work with non-root images[/+]Unb0rn commentedon Jun 2, 2019
Any workarounds? I have this problem too
J0WI commentedon Jun 4, 2019
Thanks for reporting this. I can reproduce the issue, but I'm not very happy with the proposed permission change in #764.
However, this should not break your NextCloud, you just have no Redis session handler. As a workaround, you can mount a
redis-session.inimanually.smueller18 commentedon Jun 4, 2019
I know changing the permissions is kind of a security issue. But running the image as root is even more.
What definitely does not work:
.user.inifile. According to PHP memory limit to 128 ? #447 (comment), this does not work for CLI mode.Here are some options that I figured out:
/usr/local/etc/php/conf.d/to userwww-data. The entrypoint createsredis-session.ini. Results in security concerns./usr/local/etc/php/conf.d/redis-session.iniin the Dockerfile with no content. Change ownership of only/usr/local/etc/php/conf.d/redis-session.inito userwww-data. Content can be written in the entrypoint. More secure than 1. but if redis is not used, there is an empty file./usr/local/etc/php/conf.d/session.iniin the Dockerfile with defaults from default config/usr/local/etc/php/php.ini-production. Change ownership of only/usr/local/etc/php/conf.d/session.inito userwww-data. Content can be replaced withsedin the entrypoint. Security equal to 2. but duplicate config for session./usr/local/etc/php/conf.d/redis-session.iniwhen running as root, otherwise log a warning that the file must be mounted manually instead of throwing the error like described above. No security concerns.Currently I think version 3 is the best trade-off. @J0WI what do you think?
J0WI commentedon Jun 5, 2019
Why would you prefer 3 over 2?
4 would also be an option for me, this is basically what happens now.
@tilosp what is your opinion?
smueller18 commentedon Jun 7, 2019
@J0WI I prefer 3 over 2 because if redis host is not set, there is a file called
redis-session.iniwhich might irritate users.Best practices of writing Docker images says
All images in this project should run as non-root by default. Having this in mind, 4 is not an option. I will open a new PR that sets non-root users as default for all used images and examples. Not choosing 4 is a precondition for that.
tilosp commentedon Jun 12, 2019
1 and 2 are not really an option because it wouldn't work for users other than root and www-data. Instead we would need to chmod 777 them.
It there any difference between 1, 2 and 3 in terms of security? In each case php can modify it's own config.
The web server already runs as a non-root user (www-data) by default.
And i don't see how adding
USER www-datato the Dockerfile will improve the security. If you don't trust the container to run apache as www-data you also can't trust the default user to be www-data.J0WI commentedon Jun 12, 2019
Not it terms of security, but I'd avoid changing upstream files.
smueller18 commentedon Jun 12, 2019
I can't verify that, have a look at the commands:
The PID 1 process always runs as root by using the defaults.
Have a look at the following blog post. There is a good explanation, why running images as root is not a good practice:
If the
USERdirective is set towww-datathe attack vector is minimized when running with defaults. And if anyone wants to run the image as root this is still possible by manually changing the user.It makes no sense to use another user than
rootorwww-datato run fpm or apache, other users do not have sufficient permissions.How should we go an with this issue?
tilosp commentedon Jun 12, 2019
Yes the entrypoint scipt and apache/fpm master process run as root by default. I meant that the processes that handle the requests and run the php code are run by a different user.
Yes it will reduce the attack surface in case there is a bug in apache/fpm that allows code execution in the master process. But it won't help in the case of a malicious docker image. To protect against a malicious docker image you would need to override to default user for example in the docker-compose file.
Something like this should be done upstream in the php base image, then all php based images get the benefit.
This is valid use case and it is supported by the upstream image. It should work, have you tried it? If there is a permission problem it is a bug.
smueller18 commentedon Jun 22, 2019
I was not aware of that in docker-library/php#787 the permissions of folder
/var/www/htmlwere set to777. So yes, every user can be used to run the php-fpm image.I guess the upstream images will not set the user directive in the mid-term because that will break too many existing child images. So in my opinion, this should be treated proactive from the application side.
After the discussions above, how should we follow?
In the meantime, I am just happy if the entrypoint does not throw an exception anymore. And all following changes of this project should work user independent so that updating the image is always possible without manual testing in a sandbox environment.
23 remaining items
phate7 commentedon Feb 13, 2024
Having the exact same problem. Thank you for the fix. Nextcloud should up their game on how to correctly use docker and providing images. The whole upgrade process with nextcloud is also horrendous. If there would be a viable alternative I would gladly take it.
hypery2k commentedon Apr 19, 2024
LorbusChris commentedon May 5, 2024
OT: You may want to check out https://github.com/LorbusChris/nextcloud-quadlet for an alternative way of running a rootless setup. The stack is a bit different, using Valkey instead of Redis, and Envoy as proxy. I've been running this setup for ~4 months with automatic upgrades and without any issues.
J0WI commentedon May 13, 2024
Unlikely, due the reason mentioned in #763 (comment)
Making the server config world writeable would make the image less secure for everyone. Mounting a custom config is the way to go.
guillaumedsde commentedon Mar 22, 2025
Hello 👋
For people running a docker Nextcloud instance with a read-only root filesystem and a non-root user, I have found a workaround to this issue.
PHP allows you to change the directories in which it is going to look for ini configurations using the environment
PHP_INI_SCAN_DIRvariable.So you can launch the container with
PHP_INI_SCAN_DIR="/tmp/php_conf_d:"assuming you have mounted a tmpfs in/tmp(note that the trailing:tells PHP to append the specified directory to the existing set of PHP ini scan directories).Then you can mount a custom script in
/docker-entrypoint-hooks.d/before-starting/redis_config_generator.shwhich could look something like this:(Note that the redis environment variables are prefixed with
HOOK_to avoid Nextcloud attempting to generate its own configuration on top of yours using theREDIS_environment variables)This should enable you to have a custom Redis configuration readable by your custom
--userand written to a writable location on the filesystem.antoinetran commentedon Mar 25, 2025
Hi, I have the same issue in a Kubernetes environment, using Nextcloud helm chart, in OpenShift with restrictive non root policy.
This is a workaround that works!! I couldn't mount an emptyDir directly to the
/usr/local/etc/php/conf.d, because that would have overriden the existing file. So I created an emptyDir, and initContainer to create en empty file, what a workaround!!!Aetylus commentedon Apr 10, 2025
Thank you, that helped me fix my issue with the Helm chart as well. Just a note for anyone else that finds this issue trying to run as non-root along with the cronjob container, you have to set the
securityContexton theinit-redis-session-iniinitContainer.podSecurityContextwon't work because the cronjob container must run as root to work properly.There is an open pull request (nextcloud/helm#703) to use a k8s CronJob resource instead which would solve this problem, in which case
podSecurityContextshould work if it's accepted.antoinetran commentedon Jun 17, 2025
For information, this is the PullRequest I created that fixed this issue: nextcloud/helm#717 . One day it will be merged!
agravgaard commentedon Jan 15, 2026
If I'm understanding nextcloud/helm#752 correctly, then this could currently be worked around by adding to the values:
This seems to work for me, but my testing has been limited so far.
(But my values file is already about 300 lines long and hard to maintain, so I'd prefer to get the above-mentioned fix merged)
Edit: a writable '/tmp' was also needed.
joshtrichards commentedon Jan 29, 2026
Here's a thought:
nextcloud.ini) reference the environment variable(s) directly. **We already do this forPHP_MEMORY_LIMITthough it doesn't have any entrypoint logic since it's much simpler).Specifically:
redis-session.inifile entirely (no write required in the entrypoint)session.save_pathvalue just before launching apache/fpm and export it into an environment variable (e.g.PHP_REDIS_SESSION_SAVE_PATH). Also include others likePHP_REDIS_SESSION_HANDLER = "redis"and the locking settingsnextcloud.iniwe reference the environment variables just like we do forPHP_MEMORY_LIMIT/etc.This should work.
Refs:
REDIS*config handling:docker/docker-entrypoint.sh
Lines 115 to 148 in 0af85f2
PHP_MEMORY_LIMIT):docker/Dockerfile-debian.template
Lines 99 to 123 in 0af85f2
php.inienvironment variable support: https://www.php.net/manual/en/configuration.file.php#configuration.fileProposed (untested):
nextcloud.inireference the above environment variables (i.e. add these to ourDockerfile-*.templatefiles:In PHP 8.3+. we can even add clear fallbacks per PHP docs (though may be unnecessary since defaults are likely fine -- or we could handle it in our entrypoint logic too). Something like this I believe:
feat(redis): config save_handler w/o modifying ini file in entrypoint
joshtrichards commentedon Mar 23, 2026
Early prototype of approach that eliminates entrypoint needing to modify redis-session.ini file is in draft PR #2550. Needs testing.