From 4f52747eddb3a834ae3b56d81889f0a8c59ecc27 Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Thu, 18 Dec 2025 10:33:16 +0100 Subject: [PATCH 1/2] feat: update Dockerfile to not require beeing root --- glpi/Dockerfile | 24 ++++++++++++------- glpi/files/etc/cron.d/glpi | 1 - glpi/files/etc/supervisor/supervisord.conf | 19 +++++++++++++++ glpi/files/opt/glpi/cron-worker.sh | 8 +++++++ glpi/files/opt/glpi/entrypoint.sh | 1 + .../files/opt/glpi/entrypoint/forward-logs.sh | 8 +------ .../entrypoint/init-volumes-directories.sh | 17 +++++++------ glpi/files/opt/glpi/startup.sh | 6 ----- glpi/files/opt/glpi/startup/install.sh | 8 +++---- glpi/files/opt/glpi/startup/start.sh | 8 ------- 10 files changed, 58 insertions(+), 42 deletions(-) delete mode 100644 glpi/files/etc/cron.d/glpi create mode 100644 glpi/files/etc/supervisor/supervisord.conf create mode 100755 glpi/files/opt/glpi/cron-worker.sh delete mode 100644 glpi/files/opt/glpi/startup.sh delete mode 100644 glpi/files/opt/glpi/startup/start.sh diff --git a/glpi/Dockerfile b/glpi/Dockerfile index 99e117d1..f1be0d40 100644 --- a/glpi/Dockerfile +++ b/glpi/Dockerfile @@ -121,8 +121,11 @@ RUN apt-get update \ # Enable apache mods. && a2enmod rewrite \ \ - # Install cron service. - && apt-get install --assume-yes --no-install-recommends --quiet cron \ + # Install supervisor service. + && apt-get install --assume-yes --no-install-recommends --quiet supervisor \ + \ + # Install libcap2-bin for setcap + && apt-get install --assume-yes --no-install-recommends --quiet libcap2-bin \ \ # Install acl to manage acl of writable directories. && apt-get install --assume-yes --no-install-recommends --quiet acl \ @@ -137,20 +140,20 @@ RUN apt-get update \ # ref: https://github.com/docker-library/docs/tree/master/php#configuration RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini +# Allow apache process to bind to port 80 as non-root user +RUN setcap cap_net_bind_service=+ep /usr/sbin/apache2 + # Copy services configuration files and startup script to container. COPY ./files/etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf COPY ./files/etc/apache2/conf-available/zzz-glpi.conf /etc/apache2/conf-available/zzz-glpi.conf -COPY ./files/etc/cron.d/glpi /etc/cron.d/glpi +COPY ./files/etc/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY ./files/etc/php/conf.d/glpi.ini $PHP_INI_DIR/conf.d/glpi.ini -COPY ./files/opt/glpi/ /opt/glpi/ -RUN find /opt/glpi -type f -iname "*.sh" -exec chmod u+x {} \; +COPY --chown=www-data:www-data ./files/opt/glpi/ /opt/glpi/ +RUN find /opt/glpi -type f -iname "*.sh" -exec chmod +x {} \; # Enable custom Apache configuration RUN a2enconf zzz-glpi.conf -# Install GLPI crontab. -RUN crontab -u root /etc/cron.d/glpi - # Copy GLPI application. COPY --from=builder --chown=www-data:www-data /usr/src/glpi /var/www/glpi @@ -168,9 +171,12 @@ ENV \ GLPI_SKIP_AUTOINSTALL=false \ GLPI_SKIP_AUTOUPDATE=false +# Pass the execution to the www-data user +USER www-data + # Define entrypoint and default command. ENTRYPOINT ["/opt/glpi/entrypoint.sh"] -CMD ["/opt/glpi/startup.sh"] +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] # Define application path as base working dir. WORKDIR /var/www/glpi diff --git a/glpi/files/etc/cron.d/glpi b/glpi/files/etc/cron.d/glpi deleted file mode 100644 index 84a7215b..00000000 --- a/glpi/files/etc/cron.d/glpi +++ /dev/null @@ -1 +0,0 @@ -* * * * * su www-data -s /usr/local/bin/php /var/www/glpi/front/cron.php 2>> /var/log/cron-errors.log 1>> /var/log/cron-output.log diff --git a/glpi/files/etc/supervisor/supervisord.conf b/glpi/files/etc/supervisor/supervisord.conf new file mode 100644 index 00000000..d14c5e64 --- /dev/null +++ b/glpi/files/etc/supervisor/supervisord.conf @@ -0,0 +1,19 @@ +[supervisord] +nodaemon=true +user=www-data + +[program:apache2] +command=apache2-foreground +autorestart=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:glpi-cron] +command=/opt/glpi/cron-worker.sh +autorestart=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/glpi/files/opt/glpi/cron-worker.sh b/glpi/files/opt/glpi/cron-worker.sh new file mode 100755 index 00000000..d4a87be6 --- /dev/null +++ b/glpi/files/opt/glpi/cron-worker.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e -u -o pipefail + +# Infinite loop to run GLPI cron tasks every minute +while true; do + php /var/www/glpi/front/cron.php || echo "Cron task failed" + sleep 60 +done diff --git a/glpi/files/opt/glpi/entrypoint.sh b/glpi/files/opt/glpi/entrypoint.sh index c206519d..d74c02d7 100644 --- a/glpi/files/opt/glpi/entrypoint.sh +++ b/glpi/files/opt/glpi/entrypoint.sh @@ -3,5 +3,6 @@ set -e -u -o pipefail /opt/glpi/entrypoint/init-volumes-directories.sh /opt/glpi/entrypoint/forward-logs.sh +/opt/glpi/startup/install.sh exec "$@" diff --git a/glpi/files/opt/glpi/entrypoint/forward-logs.sh b/glpi/files/opt/glpi/entrypoint/forward-logs.sh index a34f8faa..4a190343 100644 --- a/glpi/files/opt/glpi/entrypoint/forward-logs.sh +++ b/glpi/files/opt/glpi/entrypoint/forward-logs.sh @@ -23,8 +23,6 @@ do if [ ! -f "$log" ]; then touch "$log" - chown www-data:www-data "$log" - chmod u+rw "$log" fi done @@ -41,8 +39,4 @@ do done -# Forward GLPI cron logs to stdout/stderr (see https://stackoverflow.com/a/63713129). -touch /var/log/cron-output.log -touch /var/log/cron-errors.log -tail -F /var/log/cron-output.log > /proc/1/fd/1 & -tail -F /var/log/cron-errors.log > /proc/1/fd/2 & + diff --git a/glpi/files/opt/glpi/entrypoint/init-volumes-directories.sh b/glpi/files/opt/glpi/entrypoint/init-volumes-directories.sh index 36042d03..a59d3296 100644 --- a/glpi/files/opt/glpi/entrypoint/init-volumes-directories.sh +++ b/glpi/files/opt/glpi/entrypoint/init-volumes-directories.sh @@ -2,7 +2,6 @@ set -e -u -o pipefail # Create `config`, `marketplace` and `files` volume (sub)directories that are missing -# and set ACL for www-data user roots=( "${GLPI_CONFIG_DIR}" "${GLPI_VAR_DIR}" @@ -27,14 +26,18 @@ vars=( all_dirs=("${roots[@]}" "${vars[@]}") for dir in "${all_dirs[@]}" do - echo "Creating $dir if does not exists..." - mkdir -p -- "$dir" + if [ ! -d "$dir" ]; then + echo "Creating $dir..." + mkdir -p -- "$dir" + fi done +# Check permissions for dir in "${roots[@]}" do - echo "Setting $dir ACLs..." - chown -R -- www-data:www-data "$dir" - find "$dir" -type d -exec chmod u+rwx {} + - find "$dir" -type f -exec chmod u+rw {} + + if [ ! -w "$dir" ]; then + echo "ERROR: Directory $dir is not writable by current user (UID $(id -u))." + echo "Please ensure that the mounted volume is writable by UID $(id -u) (usually www-data)." + exit 1 + fi done diff --git a/glpi/files/opt/glpi/startup.sh b/glpi/files/opt/glpi/startup.sh deleted file mode 100644 index 4ee618c8..00000000 --- a/glpi/files/opt/glpi/startup.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -e -u -o pipefail - -/opt/glpi/startup/init-env.sh -/opt/glpi/startup/install.sh -/opt/glpi/startup/start.sh diff --git a/glpi/files/opt/glpi/startup/install.sh b/glpi/files/opt/glpi/startup/install.sh index c0236964..45c60cd2 100644 --- a/glpi/files/opt/glpi/startup/install.sh +++ b/glpi/files/opt/glpi/startup/install.sh @@ -2,13 +2,13 @@ set -e -u -o pipefail Install_GLPI() { - su www-data -s /bin/bash -c 'bin/console database:install \ + bin/console database:install \ --db-host="$GLPI_DB_HOST" \ --db-port="$GLPI_DB_PORT" \ --db-name="$GLPI_DB_NAME" \ --db-user="$GLPI_DB_USER" \ --db-password="$GLPI_DB_PASSWORD" \ - --no-interaction --quiet' + --no-interaction --quiet } greetings() { @@ -37,12 +37,12 @@ greetings() { } Update_GLPI() { - su www-data -s /bin/bash -c 'bin/console database:update --no-interaction --quiet' + bin/console database:update --no-interaction --quiet } GLPI_Installed() { if [ -f "${GLPI_CONFIG_DIR}/config_db.php" ]; then - su www-data -s /bin/bash -c 'bin/console db:check --quiet' + bin/console db:check --quiet # GLPI error code for db:check command: # 0: Everything is ok # 1-4: Warnings related to sql diffs (not critical) diff --git a/glpi/files/opt/glpi/startup/start.sh b/glpi/files/opt/glpi/startup/start.sh deleted file mode 100644 index 1261bc05..00000000 --- a/glpi/files/opt/glpi/startup/start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -e -u -o pipefail - -# Run cron service. -cron - -# Run command previously defined in base php-apache Dockerfile. -apache2-foreground From c381cfe69a1da9e4c736daafbc36b3bdd5631ca6 Mon Sep 17 00:00:00 2001 From: Benoit VIGNAL Date: Thu, 18 Dec 2025 11:49:11 +0100 Subject: [PATCH 2/2] feat: enable PHP session garbage collection --- glpi/files/etc/php/conf.d/glpi.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/glpi/files/etc/php/conf.d/glpi.ini b/glpi/files/etc/php/conf.d/glpi.ini index 119f713b..09dd6f0b 100644 --- a/glpi/files/etc/php/conf.d/glpi.ini +++ b/glpi/files/etc/php/conf.d/glpi.ini @@ -5,3 +5,7 @@ session.cookie_samesite = "Strict" ; Do not expose PHP version expose_php = off + +; Enable PHP session garbage collection (required since system cron is removed) +session.gc_probability = 1 +session.gc_divisor = 100