cluster

Infrastructure files for Nordgedanken and Midnightthoughts.
git clone git://archive.git.mtrnord.blog/MTRNord/cluster.git
Log | Files | Refs | README

commit 8ae1cc4426e00c3779eed993f03ae518104511ec
parent e5a64bf7fb061ac1c22201305666bebbe632250f
Author: MTRNord <MTRNord@users.noreply.github.com>
Date:   Wed, 15 Oct 2025 22:25:13 +0200

fixes

Signed-off-by: MTRNord <MTRNord@users.noreply.github.com>

Diffstat:
Mapps/talos_cluster/blog/docker/10-opcache.ini | 11++++++-----
Aapps/talos_cluster/blog/docker/20-apcu.ini | 9+++++++++
Mapps/talos_cluster/blog/docker/Dockerfile | 122++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mapps/talos_cluster/blog/docker/php.ini | 179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mapps/talos_cluster/blog/docker/wordpress.conf | 44++++++++++++++++++++++++++++++++++----------
Mapps/talos_cluster/blog/docker/www.conf | 24++++++++++++++----------
Mapps/talos_cluster/blog/wordpress.yaml | 2+-
7 files changed, 306 insertions(+), 85 deletions(-)

diff --git a/apps/talos_cluster/blog/docker/10-opcache.ini b/apps/talos_cluster/blog/docker/10-opcache.ini @@ -5,8 +5,9 @@ opcache.jit_buffer_size=64M opcache.jit=tracing opcache.enable=1 -opcache.enable_cli=0 -opcache.memory_consumption=128 -opcache.interned_strings_buffer=8 -opcache.max_accelerated_files=4000 -opcache.revalidate_freq=2 +opcache.enable_cli=1 +opcache.memory_consumption=256 +opcache.interned_strings_buffer=12 +;opcache.max_accelerated_files=4000 +;opcache.revalidate_freq=2 +opcache.max_wasted_percentage=5 diff --git a/apps/talos_cluster/blog/docker/20-apcu.ini b/apps/talos_cluster/blog/docker/20-apcu.ini @@ -0,0 +1,9 @@ +; APCu configuration for PHP +extension=apcu.so +apc.enabled=1 +apc.shm_size=64M +apc.ttl=7200 +apc.enable_cli=0 +apc.entries_hint=4096 +apc.slam_defense=1 +apc.serializer=php diff --git a/apps/talos_cluster/blog/docker/Dockerfile b/apps/talos_cluster/blog/docker/Dockerfile @@ -1,75 +1,103 @@ # Use Ubuntu as the base image FROM ubuntu:25.10 -# Set the Timezone to UTC +# Non-interactive frontend for apt and set timezone +ARG DEBIAN_FRONTEND=noninteractive ENV TZ=UTC -# Install Nginx, and other necessary Packages -RUN apt-get update && apt-get install -y \ - software-properties-common \ - nginx \ - curl \ - wget \ - sudo \ - unzip \ +# Install common packages, nginx, php and tools in a single layer for smaller image +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + gnupg \ + lsb-release \ + nginx \ + curl \ + wget \ + unzip \ + sudo \ + imagemagick \ + php8.4 \ + php8.4-fpm \ + #php8.4-mysql \ + php8.4-mysqlnd \ + php8.4-cli \ + php8.4-opcache \ + php8.4-exif \ + php8.4-gd \ + php8.4-curl \ + php8.4-dom \ + php8.4-imagick \ + php8.4-mbstring \ + php8.4-igbinary \ + php8.4-zip \ + php8.4-intl \ + php8.4-bz2 \ + php8.4-redis \ + php8.4-apcu \ + php8.4-bcmath \ + redis-server cron less nano \ && rm -rf /var/lib/apt/lists/* -# Add PHP repository -# RUN sudo add-apt-repository ppa:ondrej/php +# Enable PHP extensions +RUN phpenmod -v 8.4 -s fpm \ + redis apcu exif gettext \ + iconv opcache bz2 igbinary curl dom \ + intl gd imagick mbstring zip mysqlnd curl \ + bcmath calendar ctype posix xmlreader xmlwriter -RUN apt-get update && apt-get install -y \ - php8.4 php8.4-fpm php8.4-mysql php8.4-cli php8.4-gd \ - php8.4-curl php8.4-dom php8.4-imagick php8.4-mbstring php8.4-zip php8.4-intl \ - php8.4-redis redis-server cron \ - && rm -rf /var/lib/apt/lists/* -RUN phpenmod redis -ADD php.ini /etc/php/8.4/nginx/ -COPY 10-opcache.ini /etc/php/8.4/mods-available/opcache.ini +# Copy PHP ini and extension INI files before enabling them (cache layer friendly) +COPY 20-apcu.ini /etc/php/8.4/mods-available/20-apcu.ini +COPY 10-opcache.ini /etc/php/8.4/mods-available/10-opcache.ini COPY www.conf /etc/php/8.4/fpm/pool.d/www.conf +COPY php.ini /etc/php/8.4/fpm/php.ini -# Install Wordpress -RUN wget https://wordpress.org/latest.zip \ - && unzip latest.zip -d /var/www/html/ \ +# Install WordPress into the webroot +RUN wget -q https://wordpress.org/latest.zip \ + && unzip -q latest.zip -d /var/www/html/ \ && rm latest.zip +# Configure nginx: replace default site and enable wordpress config +RUN rm -f /etc/nginx/sites-enabled/default +COPY wordpress.conf /etc/nginx/sites-available/wordpress.conf +RUN ln -s /etc/nginx/sites-available/wordpress.conf /etc/nginx/sites-enabled/wordpress.conf -# Add Nginx config file -RUN rm /etc/nginx/sites-enabled/default -ADD wordpress.conf /etc/nginx/sites-available/ -RUN ln -s /etc/nginx/sites-available/wordpress.conf /etc/nginx/sites-enabled/ - -# Copy redis.conf for redis-server +# Copy redis config and well-known files COPY redis.conf /redis.conf COPY wellknown/client.json /var/www/html/well-known/client COPY wellknown/server.json /var/www/html/well-known/server COPY wellknown/support.json /var/www/html/well-known/support.json -# Add WordPress config file -RUN rm /var/www/html/wordpress/wp-config-sample.php -ADD wp-config.php /var/www/html/wordpress/wp-config.php -ADD advanced-cache.php /var/www/html/wordpress/wp-content/advanced-cache.php -ADD wp-cache-config.php /var/www/html/wordpress/wp-content/wp-cache-config.php -ADD object-cache.php /var/www/html/wordpress/wp-content/object-cache.php -# Change the user and Permission of WordPress root directory -RUN chown -R www-data:www-data /var/www/html/wordpress \ - && chmod -R 755 /var/www/html/wordpress -RUN chown -R www-data:www-data /var/www/html/well-known \ - && chmod -R 755 /var/www/html/well-known - -# Exposing container to port 8080 +# Add WordPress configuration and cache files +RUN rm -f /var/www/html/wordpress/wp-config-sample.php +COPY wp-config.php /var/www/html/wordpress/wp-config.php +COPY advanced-cache.php /var/www/html/wordpress/wp-content/advanced-cache.php +COPY wp-cache-config.php /var/www/html/wordpress/wp-content/wp-cache-config.php +COPY object-cache.php /var/www/html/wordpress/wp-content/object-cache.php + +# Fix permissions for the webroot +RUN chown -R www-data:www-data /var/www/ \ + && chmod -R 755 /var/www/ + +# Install WP-CLI +RUN curl -fsSL -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \ + && chmod +x /usr/local/bin/wp + +# Expose HTTP port EXPOSE 8080 -# Copy the startup script and give excuitable permission +# Copy startup script and make it executable COPY startup.sh /usr/local/bin/startup.sh RUN chmod +x /usr/local/bin/startup.sh -# Add cronjob: every 10 minutes, run wp-cron.php via curl -RUN echo '*/10 * * * * curl https://mtrnord.blog/wp-cron.php > /dev/null 2>&1' > /etc/cron.d/wp-cron -RUN chmod 0644 /etc/cron.d/wp-cron && crontab /etc/cron.d/wp-cron +# Add cronjob: every 10 minutes, run wp-cron.php via curl as www-data +# Note: cron files in /etc/cron.d must have the user field +RUN printf '*/10 * * * * www-data curl -fsS --retry 3 https://mtrnord.blog/wp-cron.php > /dev/null 2>&1\n' > /etc/cron.d/wp-cron \ + && chmod 0644 /etc/cron.d/wp-cron -# Ensure cron runs in the background with the app (use printf for cross-arch compatibility) +# Ensure cron runs alongside the startup script RUN printf '#!/bin/sh\ncron && exec "$@"\n' > /usr/local/bin/with-cron.sh && chmod +x /usr/local/bin/with-cron.sh -# Command to run the startup script with cron +# Default command: run cron helper then startup CMD ["/usr/local/bin/with-cron.sh", "/usr/local/bin/startup.sh"] diff --git a/apps/talos_cluster/blog/docker/php.ini b/apps/talos_cluster/blog/docker/php.ini @@ -1,10 +1,31 @@ -file_uploads = On -allow_url_fopen = Off -memory_limit = 256M -upload_max_filesize = 150M +[PHP] +engine = On +short_open_tag = Off +asp_tags = Off + +precision = 14 + +output_buffering = 0 + +zlib.output_compression = Off + +implicit_flush = Off + +unserialize_callback_func = +serialize_precision = 17 + + +disable_functions = +disable_classes = + +zend.enable_gc = On + +expose_php = On + max_execution_time = 350 -date.timezone = Europe/Berlin -error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR +memory_limit = 256M + +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = Off display_startup_errors = Off log_errors = On @@ -12,13 +33,147 @@ error_log = /dev/stderr log_errors_max_len = 1024 ignore_repeated_errors = On ignore_repeated_source = Off +report_memleaks = On +track_errors = Off html_errors = Off + +variables_order = "GPCS" +request_order = "GP" + +register_argc_argv = Off +auto_globals_jit = On post_max_size = 150M -zlib.output_compression = On -zlib.output_compression_level = 5 -realpath_cache_size = 16M -realpath_cache_ttl = 120 + +auto_prepend_file = +auto_append_file = + +default_mimetype = "text/html" +default_charset = "UTF-8" + +always_populate_raw_post_data = -1 + +cgi.discard_path = 1 +cgi.fix_pathinfo = 0 + +file_uploads = On +upload_max_filesize = 150M +max_file_uploads = 20 + +allow_url_fopen = Off +allow_url_include = Off + +default_socket_timeout = 60 + +[CLI Server] +cli_server.color = On + +[Date] +date.timezone = Europe/Berlin + +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket = + + +[ODBC] +;odbc.default_db = Not yet implemented +;odbc.default_user = Not yet implemented +;odbc.default_pw = Not yet implemented +;odbc.default_cursortype +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 +;birdstep.max_links = -1 + +[Interbase] +ibase.allow_persistent = 1 +ibase.max_persistent = -1 +ibase.max_links = -1 +;ibase.default_db = +;ibase.default_user = +;ibase.default_password = +;ibase.default_charset = +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" +ibase.dateformat = "%Y-%m-%d" +ibase.timeformat = "%H:%M:%S" + +[MySQL] +mysql.allow_local_infile = On +mysql.allow_persistent = On +mysql.cache_size = 2000 +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 60 +mysql.trace_mode = Off + +[MySQLi] +;mysqli.allow_local_infile = On +mysqli.max_persistent = -1 +mysqli.allow_persistent = On +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off + +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off +;mysqlnd.net_cmd_buffer_size = 2048 +;mysqlnd.net_read_buffer_size = 32768 + + +[bcmath] +bcmath.scale = 0 + +[Session] +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" + session.save_handler = files -session.save_path = /var/lib/php/sessions -session.cache_limiter = public +;session.save_path = "/tmp" +session.use_strict_mode = 0 +session.use_cookies = 1 +;session.cookie_secure = +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 +session.cookie_lifetime = 0 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = +session.serialize_handler = php +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.referer_check = +;session.entropy_length = 32 +;session.entropy_file = /dev/urandom +session.cache_limiter = nocache session.cache_expire = 180 +session.use_trans_sid = 0 +session.hash_function = 0 +session.hash_bits_per_character = 5 +;session.upload_progress.enabled = On +;session.upload_progress.cleanup = On +;session.upload_progress.prefix = "upload_progress_" +;session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" +;session.upload_progress.freq = "1%" +;session.upload_progress.min_freq = "1" + + +[soap] +soap.wsdl_cache_enabled=1 +soap.wsdl_cache_dir="/tmp" +soap.wsdl_cache_ttl=86400 +soap.wsdl_cache_limit = 5 diff --git a/apps/talos_cluster/blog/docker/wordpress.conf b/apps/talos_cluster/blog/docker/wordpress.conf @@ -1,5 +1,15 @@ limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; +# Use an upstream for php-fpm so php backend can be referenced consistently +upstream phpfpm { + # unix socket for the php8.4-fpm pool + server unix:/var/run/php/php8.4-fpm.sock; + # keepalive connections to improve latency when talking to php-fpm + keepalive 32; + # fallback to TCP socket if needed (uncomment and configure host:port) + # server 127.0.0.1:9000; +} + server { listen 8080; root /var/www/html/wordpress; @@ -9,8 +19,16 @@ server { error_log stderr; set $cache_uri $request_uri; - server_name _; + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; + + server_name _; # Allow access to /.well-known/matrix before dotfile deny rule location /.well-known/matrix { @@ -45,12 +63,13 @@ server { # Deny access to wp-login.php location = /wp-login.php { limit_req zone=one burst=1 nodelay; - include snippets/fastcgi-php.conf; - fastcgi_pass unix:/var/run/php/php8.4-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - include fastcgi_params; + try_files $uri =404; + + include fastcgi.conf; + fastcgi_intercept_errors on; fastcgi_read_timeout 300s; proxy_read_timeout 300s; + fastcgi_pass phpfpm; } location ~* /.well-known/webfinger { @@ -96,17 +115,22 @@ server { } location ~ \.php$ { - include snippets/fastcgi-php.conf; - fastcgi_pass unix:/var/run/php/php8.4-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - include fastcgi_params; + try_files $uri =404; + + include fastcgi.conf; + fastcgi_intercept_errors on; fastcgi_read_timeout 300s; proxy_read_timeout 300s; + fastcgi_pass phpfpm; } - location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { + location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { expires max; log_not_found off; access_log off; } + + location = /wp-admin/install.php { + deny all; + } } diff --git a/apps/talos_cluster/blog/docker/www.conf b/apps/talos_cluster/blog/docker/www.conf @@ -113,7 +113,7 @@ listen.group = www-data ; pm.process_idle_timeout - The number of seconds after which ; an idle process will be killed. ; Note: This value is mandatory. -pm = dynamic +pm = ondemand ; The number of child processes to be created when pm is set to 'static' and the ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. @@ -124,22 +124,22 @@ pm = dynamic ; forget to tweak pm.* to fit your needs. ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' ; Note: This value is mandatory. -pm.max_children = 100 +pm.max_children = 50 ; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: (min_spare_servers + max_spare_servers) / 2 -pm.start_servers = 30 +pm.start_servers = 5 ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' -pm.min_spare_servers = 30 +pm.min_spare_servers = 2 ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' -pm.max_spare_servers = 60 +pm.max_spare_servers = 10 ; The number of rate to spawn child processes at once. ; Note: Used only when pm is set to 'dynamic' @@ -156,7 +156,7 @@ pm.max_spare_servers = 60 ; This can be useful to work around memory leaks in 3rd party libraries. For ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. ; Default Value: 0 -;pm.max_requests = 500 +pm.max_requests = 500 ; The URI to view the FPM status page. If this value is not set, no URI will be ; recognized as a status page. It shows the following information: @@ -372,13 +372,13 @@ pm.max_spare_servers = 60 ; The log file for slow requests ; Default Value: not set ; Note: slowlog is mandatory if request_slowlog_timeout is set -;slowlog = log/$pool.log.slow +slowlog = /proc/self/fd/2 ; The timeout for serving a single request after which a PHP backtrace will be ; dumped to the 'slowlog' file. A value of '0s' means 'off'. ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) ; Default Value: 0 -;request_slowlog_timeout = 0 +request_slowlog_timeout = 2s ; Depth of slow log stack trace. ; Default Value: 20 @@ -389,7 +389,7 @@ pm.max_spare_servers = 60 ; does not stop script execution for some reason. A value of '0' means 'off'. ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) ; Default Value: 0 -;request_terminate_timeout = 0 +request_terminate_timeout = 300s ; The timeout set by 'request_terminate_timeout' ini option is not engaged after ; application calls 'fastcgi_finish_request' or when application has finished and @@ -429,7 +429,7 @@ pm.max_spare_servers = 60 ; Note: on highloaded environment, this can cause some delay in the page ; process time (several ms). ; Default Value: no -;catch_workers_output = yes +catch_workers_output = yes ; Decorate worker output with prefix and suffix containing information about ; the child that writes to the log and if stdout or stderr is used as well as @@ -489,3 +489,7 @@ php_flag[display_errors] = off php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 256M php_admin_value[error_log] = /proc/self/fd/2 +php_admin_value[output_buffering] = 0 +php_admin_value[max_input_time] = 3600 +php_admin_value[max_input_nesting_level] = 256 +php_admin_value[max_input_vars] = 10000 diff --git a/apps/talos_cluster/blog/wordpress.yaml b/apps/talos_cluster/blog/wordpress.yaml @@ -121,7 +121,7 @@ spec: failureThreshold: 3 livenessProbe: httpGet: - path: /wp-admin/install.php + path: /wp-login.php port: 8080 scheme: "HTTP" initialDelaySeconds: 60