From 0e6ec94ae428920b8e866d9eac9efbbcc899fb87 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 26 Oct 2026 11:02:05 +0100 Subject: [PATCH] Run container as unprivileged www-data user and simplify entrypoint - Remove root-only FPM user configuration from entrypoint.sh (moved to Dockerfile build time) - Remove Redis session configuration from entrypoint.sh (handled by Symfony services) - Remove cache directory permission adjustments (unnecessary with proper ownership) - Set file ownership to www-data:www-data at build time using COPY --chown - Create required directories and set ownership in single RUN layer - Switch to www-data USER before CMD - Remove PHP_FPM_USER, PHP_FPM_GROUP, SESSION_LIFETIME environment variables - Add docker/ directory to .dockerignore --- .gitignore | 2 +- Dockerfile | 45 ++++++++++++++++++++++++++------------------- entrypoint.sh | 19 ------------------- 3 files changed, 27 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 7a0b615..e8df7f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +docker/ ###> symfony/framework-bundle ### /.env.local /.env.local.php diff --git a/Dockerfile b/Dockerfile index be4df2d..3ce24f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,38 @@ FROM chill/base-image:8.4-edge -# copy directories +# copy directories with ownership for the unprivileged runtime user +COPY --chown=www-data:www-data ./bin /var/www/app/bin/. +COPY --chown=www-data:www-data ./composer.* /var/www/app/ +COPY --chown=www-data:www-data ./config /var/www/app/config/. +COPY --chown=www-data:www-data ./migrations /var/www/app/migrations/. +COPY --chown=www-data:www-data ./public /var/www/app/public/. +COPY --chown=www-data:www-data ./src /var/www/app/src/. +COPY --chown=www-data:www-data ./templates /var/www/app/templates/. +COPY --chown=www-data:www-data ./translations /var/www/app/translations/. +COPY --chown=www-data:www-data ./vendor /var/www/app/vendor/. -COPY ./bin /var/www/app/bin/. -COPY ./composer.* /var/www/app/ -COPY ./config /var/www/app/config/. -COPY ./migrations /var/www/app/migrations/. -COPY ./public /var/www/app/public/. -COPY ./src /var/www/app/src/. -COPY ./templates /var/www/app/templates/. -COPY ./translations /var/www/app/translations/. -COPY ./vendor /var/www/app/vendor/. - -COPY ./.env /var/www/app/.env +COPY --chown=www-data:www-data ./.env /var/www/app/.env # import the manifest.json file -COPY ./public/build/manifest.json /var/www/app/public/build/manifest.json +COPY --chown=www-data:www-data ./public/build/manifest.json /var/www/app/public/build/manifest.json -ADD ./entrypoint.sh /. +COPY ./entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh +# - mark entrypoint executable +# - declare the FPM pool user/group at build time (was previously written by entrypoint.sh as root) +# - prepare writable Symfony var/ and COMPOSER_HOME directories for the unprivileged runtime user +RUN chmod +x /entrypoint.sh \ + && printf '[www]\nuser=www-data\ngroup=www-data\n' > /usr/local/etc/php-fpm.d/zz-user.conf \ + && mkdir -p /var/www/app/var/cache /var/www/app/var/log /var/www/app/.composer \ + && chown -R www-data:www-data /var/www/app/var /var/www/app/.composer \ + && chown www-data:www-data /var/www/app +# php-fpm listens on 9000 by default (unprivileged port) +EXPOSE 9000 + +USER www-data ENTRYPOINT ["/entrypoint.sh"] -ENV PHP_FPM_USER=www-data \ - PHP_FPM_GROUP=www-data \ - COMPOSER_HOME=/var/www/app/.composer \ - SESSION_LIFETIME=10800 +ENV COMPOSER_HOME=/var/www/app/.composer CMD [ "php-fpm" ] \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 0bebfb8..fd280e4 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -16,23 +16,6 @@ else echo "we assume the database is ready"; fi - -if [ $(id -u) = "0" ]; then - { \ - echo "[www]"; \ - echo ""; \ - echo "user=${PHP_FPM_USER}"; \ - echo "group=${PHP_FPM_GROUP}"; \ - } > /usr/local/etc/php-fpm.d/zz-user.conf -fi - -{ \ - echo ""; \ - echo "session.save_handler = redis" ; \ - echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_PORT}?db=10\"" ; \ - echo "session.gc_maxlifetime = ${SESSION_LIFETIME}" ; \ -} >> /usr/local/etc/php/conf.d/custom.ini - if [ "${APP_ENV}" = "prod" ]; then composer dump-env "${APP_ENV}" chmod +r /var/www/app/.env.local.php @@ -48,8 +31,6 @@ fi if [ "${CLEAR_CACHE}" != "false" ]; then #prepare cache php /var/www/app/bin/console cache:clear --no-warmup - chgrp ${PHP_FPM_GROUP} /var/www/app/var/cache -R && chmod g+rw /var/www/app/var/cache -R - chgrp ${PHP_FPM_GROUP} /var/www/app/var/log -R && chmod g+rw /var/www/app/var/log -R fi exec "${@}"