diff --git a/docker/Dockerfile b/docker/Dockerfile index 7645d0c8..10862cce 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -5,8 +5,10 @@ RUN docker-php-source extract \ && docker-php-source delete # Java is necessary for the direct calls to the evaluation engine (in Api_splits.php) +# cron is needed for garbage collection RUN apt update \ - && apt install -y --no-install-recommends openjdk-11-jre + && apt install -y --no-install-recommends openjdk-11-jre \ + && apt install -y cron COPY . /var/www/openml RUN mv /var/www/openml/openml_OS/config/BASE_CONFIG-BLANK.php /var/www/openml/openml_OS/config/BASE_CONFIG.php @@ -21,6 +23,12 @@ COPY docker/config/api.conf /etc/apache2/sites-enabled/000-default.conf COPY docker/config/php.ini /usr/local/etc/php/ COPY docker/config/.htaccess /var/www/openml/.htaccess +COPY docker/garbage-collection/cron /etc/cron.d/garbage-collection +RUN chmod +x /etc/cron.d/garbage-collection +RUN crontab /etc/cron.d/garbage-collection +RUN touch /var/log/garbage-collection.log +RUN chmod +x /var/www/openml/docker/garbage-collection/sessionclean.sh + COPY docker/set_configuration.sh /scripts/ diff --git a/docker/config/php.ini b/docker/config/php.ini index 6f97900d..fa0d0227 100644 --- a/docker/config/php.ini +++ b/docker/config/php.ini @@ -330,7 +330,8 @@ serialize_precision = -1 ; This directive allows you to disable certain functions. ; It receives a comma-delimited list of function names. ; https://php.net/disable-functions -disable_functions = +; 2025-06-20 (Jos) - changed to reflect list on current production +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals, ; This directive allows you to disable certain classes. ; It receives a comma-delimited list of class names. @@ -407,7 +408,8 @@ zend.exception_string_param_max_len = 0 ; threat in any way, but it makes it possible to determine whether you use PHP ; on your server or not. ; https://php.net/expose-php -expose_php = On +; 2025-06-20 (Jos) - As in current production, do not expose +expose_php = Off ;;;;;;;;;;;;;;;;;;; ; Resource Limits ; @@ -416,7 +418,8 @@ expose_php = On ; Maximum execution time of each script, in seconds ; https://php.net/max-execution-time ; Note: This directive is hardcoded to 0 for the CLI SAPI -max_execution_time = 30 +; 2025-06-20 (Jos) - changed to reflect current production limit +max_execution_time = 300 ; Maximum amount of time each script may spend parsing request data. It's a good ; idea to limit this time on productions servers in order to eliminate unexpectedly @@ -426,7 +429,8 @@ max_execution_time = 30 ; Development Value: 60 (60 seconds) ; Production Value: 60 (60 seconds) ; https://php.net/max-input-time -max_input_time = 60 +; 2025-06-20 (Jos) - changed to reflect current production limit +max_input_time = 600 ; Maximum input variable nesting level ; https://php.net/max-input-nesting-level @@ -710,7 +714,8 @@ auto_globals_jit = On ; Its value may be 0 to disable the limit. It is ignored if POST data reading ; is disabled through enable_post_data_reading. ; https://php.net/post-max-size -post_max_size = 8M +; 2025-06-20 (Jos) - changed to reflect upload_max_filesize on current production - although post_max_size=0 on PROD, meaning that you can send a large (endless?) amount of 16Gb files +post_max_size = 16G ; Automatically add files before PHP document. ; https://php.net/auto-prepend-file @@ -862,7 +867,8 @@ file_uploads = On ; Maximum allowed size for uploaded files. ; https://php.net/upload-max-filesize -upload_max_filesize = 2M +; 2025-06-20 (Jos) - Same max_filesize as in current production +upload_max_filesize = 16G ; Maximum number of files that can be uploaded via a single request max_file_uploads = 20 @@ -890,7 +896,8 @@ allow_url_include = Off ; Default timeout for socket based streams (seconds) ; https://php.net/default-socket-timeout -default_socket_timeout = 60 +; 2025-06-20 (Jos) - Same default timeout as the current production +default_socket_timeout = 480 ; If your scripts have to deal with files from Macintosh systems, ; or you are running on a Mac and need to deal with files from @@ -1448,7 +1455,8 @@ session.serialize_handler = php ; Development Value: 1 ; Production Value: 1 ; https://php.net/session.gc-probability -session.gc_probability = 1 +; 2025-06-20 (Jos) - As in current production, we will run garbage collection manually, to avoid 1/1000th chance of 2sec delay (TODO, DONT MERGE LIKE THIS!!) +session.gc_probability = 0 ; Defines the probability that the 'garbage collection' process is started on every ; session initialization. The probability is calculated by using gc_probability/gc_divisor, diff --git a/docker/garbage-collection/collect-garbage.php b/docker/garbage-collection/collect-garbage.php new file mode 100644 index 00000000..0075a57a --- /dev/null +++ b/docker/garbage-collection/collect-garbage.php @@ -0,0 +1,3 @@ + diff --git a/docker/garbage-collection/cron b/docker/garbage-collection/cron new file mode 100644 index 00000000..4481ec42 --- /dev/null +++ b/docker/garbage-collection/cron @@ -0,0 +1 @@ +* * * * * /usr/local/bin/php /var/www/openml/docker/garbage-collection/collect-garbage.php && /var/www/openml/docker/garbage-collection/sessionclean.sh >> /var/log/garbage-collection.log 2>&1 diff --git a/docker/garbage-collection/sessionclean.sh b/docker/garbage-collection/sessionclean.sh new file mode 100644 index 00000000..4896f7d4 --- /dev/null +++ b/docker/garbage-collection/sessionclean.sh @@ -0,0 +1,16 @@ +#!/bin/sh -e +# Just simply deleting code igniter's session files if they're older than $GC_MAXLIFETIME_MINUTES +# I've tried just using +# session_start(); +# session_gc(); +# session_destroy(); +# But that does not delete any code igniter sessions, although it should according to the documentation I could find. +# In the end, I just settled for this. If you want to make it more beautiful, note that code igniter config can be partly found in +# openml_OS/config/config.php (e.g., 'sess_expiration' which seems to overwrite the session.gc_maxlifetime in php.ini)... + + +GC_MAXLIFETIME_SECONDS=$(/usr/local/bin/php -r "echo ini_get(\"session.gc_maxlifetime\");") +GC_MAXLIFETIME_MINUTES=$((($GC_MAXLIFETIME_SECONDS + 59) / 60)) # Ceil +GC_SAVEPATH="/tmp" + +find -O3 "$GC_SAVEPATH" -ignore_readdir_race -depth -mindepth 1 -name 'ci_session*' -type f -cmin "+$GC_MAXLIFETIME_MINUTES" -delete diff --git a/docker/set_configuration.sh b/docker/set_configuration.sh index b579dff6..2a012415 100755 --- a/docker/set_configuration.sh +++ b/docker/set_configuration.sh @@ -40,4 +40,5 @@ done cd /var/www/openml php index.php cron build_es_indices +/usr/sbin/cron -l 4 apache2-foreground