Comment to Warning: Undefined array key in 14.0.0-B1
-
my setup files:
#!/bin/bash # set_permissions.sh sudo chown -R www-data:www-data . sudo find ./ -type d -exec chmod 775 {} \; sudo find ./ -type f -exec chmod 644 {} \; # Set execute permissions for ffmpeg.exe sudo chmod +x ./plugins/ffmpeg/ffmpeg.exe sudo chmod +x ./periodic/cron.php sudo chmod +x ./image_transcoder.php # Set permissions for the specified directories # sudo chmod 777 ./inc $ only before instalkation sudo chmod 775 ./inc sudo chmod 777 ./cache sudo chmod 777 ./cache_public sudo chmod 777 ./logs sudo chmod 777 ./tmp sudo chmod 777 ./storage sudo chmod 777 ./periodic sudo chmod +x ./docker-compose.yaml sudo chown myuser:myuser ./docker-compose.yaml sudo chown -R myuser:myuser .github sudo chown -R myuser:myuser .gitignore sudo chown -R myuser:myuser .env sudo chown -R myuser:myuser .htaccess sudo chown -R myuser:myuser set_permissions.sh sudo chmod 660 ./logs/mysql_error.log sudo chown mysql:adm ./logs/mysql_error.log sudo chmod +x ./set_permissions.sh
doker-compose.yaml:
version: '3' networks: caddy_public_network: external: true una_private_network: external: false services: web: image: nginx:latest container_name: nginx.exemple.com hostname: localhost env_file: - .env deploy: resources: limits: cpus: '1' # Limit the service to 1.5 CPUs memory: 8G # Limit the service to 8GB of memory ports: - 127.0.0.1:8888:8888 volumes: # - ./scripts/docker-compose/nginx.conf:/etc/nginx/conf.d/nginx.conf - ./scripts/docker-compose/default.conf:/etc/nginx/conf.d/default.conf - ./scripts/docker-compose/rate_limit.conf:/etc/nginx/conf.d/rate_limit.conf - ./scripts/docker-compose/memcached.conf:/etc/nginx/conf.d/memcached.conf - ./logs/access.log:/var/log/nginx/access.log - ./logs/error.log:/var/log/nginx/error.log # - ./logs/auth_error.log:/var/log/nginx/auth_error.log# - ./scripts/docker-compose/phpmyadmin.conf:/etc/nginx/conf.d/phpmyadmin.conf - ./:/opt/una - /etc/localtime:/etc/localtime:ro depends_on: - php networks: - caddy_public_network - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend memcached: image: memcached:latest container_name: memcached.exemple.com hostname: localhost env_file: - .env ports: - 127.0.0.1:11211:11211 networks: - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend php: image: test/test-php:14.0.0-B1 container_name: php.exemple.com.14.0.0-B1 hostname: localhost env_file: - .env build: context: . dockerfile: scripts/docker-compose/PHP.Dockerfile deploy: resources: limits: cpus: '2' memory: 16G restart_policy: condition: on-failure volumes: - ./scripts/docker-compose/php.ini:/usr/local/etc/php/php.ini - ./scripts/docker-compose/www.conf:/usr/local/etc/php-fpm.d/www.conf - ./:/opt/una:Z - /etc/localtime:/etc/localtime:ro depends_on: - mysql networks: - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend cron: image: test/test-cron:14.0.0-B1 container_name: cron.exemple.com.14.0.0-B1 hostname: localhost env_file: - .env build: context: . dockerfile: scripts/docker-compose/Cron.Dockerfile deploy: resources: limits: cpus: '0.5' memory: 4G restart_policy: condition: on-failure volumes: - ./scripts/docker-compose/php.ini:/usr/local/etc/php/php.ini - ./scripts/docker-compose/www.conf:/usr/local/etc/php-fpm.d/www.conf - ./:/opt/una:Z - /etc/localtime:/etc/localtime:ro depends_on: - mysql networks: - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend mysql: image: mariadb:latest container_name: mysql.exemple.com env_file: - .env environment: MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD}' MYSQL_USER: '${MYSQL_USER}' MYSQL_PASSWORD: '${MYSQL_PASSWORD}' MYSQL_DATABASE: '${MYSQL_DATABASE}' volumes: - mysqldata:/var/lib/mysql - ./scripts/docker-compose/db_dump.sql:/docker-entrypoint-initdb.d/db_dump.sql - ./scripts/docker-compose/mysqld.cnf:/etc/mysql/conf.d/mysqld.cnf ports: - 127.0.0.1:3306:3306 networks: - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend jot: image: unaio/jot-server:latest container_name: jot.exemple.com hostname: localhost env_file: - .env restart: always ports: - 127.0.0.1:5000:5000 networks: - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend phpmyadmin: image: phpmyadmin container_name: phpmyadmin.exemple.com hostname: localhost restart: always ports: - 127.0.0.1:8787:80 env_file: - .env environment: - PMA_HOST=mysql - PMA_USER=root - PMA_PASSWORD=${MYSQL_ROOT_PASSWORD} - UPLOAD_LIMIT=1024M volumes: - ./scripts/docker-compose/phpmyadmin.inc.php:/etc/phpmyadmin/config.user.inc.php depends_on: - mysql networks: - una_private_network extra_hosts: - "host.docker.internal:host-gateway" - "127.0.0.1:host-gateway" # IP backend volumes: mysqldata: {}
update php-ini for memcached:
; Memcached extension configuration [memcached] ; Memcached extension configuration ; Specify the serializer for Memcached memcached.serializer = php ; Specify the session prefix for Memcached memcached.sess_prefix = memc.sess.key. ; Enable binary protocol for Memcached sessions memcached.sess_binary = On ; Use SASL authentication for Memcached (0 = disable, 1 = enable) memcached.use_sasl = 0 ; Minimum waiting time for session lock acquisition (in milliseconds) memcached.sess_lock_wait_min = 150 ; Maximum waiting time for session lock acquisition (in milliseconds) memcached.sess_lock_wait_max = 150 ; Maximum size of POST data that PHP will accept. post_max_size = 1024M ; Maximum allowed size for uploaded files. upload_max_filesize = 1024M ; Maximum execution time of each script, in seconds max_execution_time = 3600 ; Maximum amount of time each script may spend parsing request data max_input_time = 3600 ; Maximum amount of memory a script may consume memory_limit = 1024M ; Maximum number of files that can be uploaded via a single request max_file_uploads = 50 ; Enable HTML error handling html_errors = On ; String to output before an error message error_prepend_string = " " ; String to output after an error message error_append_string = " " [opcache] ; Enables the opcode cache for PHP opcache.enable = 1 ; Frequency of checking for updated files (0 = never) opcache.revalidate_freq = 0 ; Validates cached files with timestamp checks opcache.validate_timestamps = 1 ; Maximum number of files that can be cached in memory opcache.max_accelerated_files = 100000 ; Memory consumption by the opcode cache (in MB) opcache.memory_consumption = 72 ; Maximum wasted memory percentage before restart opcache.max_wasted_percentage = 20 ; Size of the interned strings buffer (in MB) opcache.interned_strings_buffer = 16 ; Allows for faster shutting down of the opcode cache opcache.fast_shutdown = 1
Php 8.1 from UNA: https://github.com/unacms/una/blob/master/scripts/docker-compose/PHP.Dockerfile with my update for memcached:
FROM php:8.1-fpm RUN apt-get update && apt-get install -y \ cron \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng-dev \ libonig-dev \ libmagickwand-dev \ libzip-dev \ unzip \ libmemcached-dev \ zlib1g-dev \ libssl-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install -j$(nproc) pdo pdo_mysql mysqli \ && docker-php-ext-install -j$(nproc) zip exif opcache iconv mbstring \ # && pecl install xdebug && docker-php-ext-enable xdebug \ # && pecl install mcrypt-1.0.3 && docker-php-ext-enable mcrypt \ && pecl install imagick-3.7.0 \ && pecl install memcached \ && docker-php-ext-enable imagick memcached
nginx upstream wuth memcached.conf:
upstream memcached_server { server 127.0.0.1:11211; # Other Memcached servers can be added here if needed }
default.conf
server { listen 80 default_server; server_name localhost; root /opt/una; client_max_body_size 1024M; ## Timeouts## request timed out -- default 60# read timeout for the request body from client, its set for testing purpose client_body_timeout 900; # how long to wait for the client to send a request header, its set for testing purpose client_header_timeout 900; # server will close connection after this time keepalive_timeout 900; ## if client stop responding, free up memory -- default 60 send_timeout 900; ## Reset lingering timed out connections. Deflect DDoS.## allow the server to close connection on non responding client, this will free up memory reset_timedout_connection on; proxy_connect_timeout 3600; proxy_send_timeout 3600; proxy_read_timeout 3600; location / { index index.html index.htm index.php; rewrite "^/page/(.*)$" /page.php?i=$1 last; rewrite "^/m/(.*)$" /modules/index.php?r=$1 last; rewrite "^/s/([a-zA-Z0-9_]+)/([a-zA-Z0-9\.]+)" /storage.php?o=$1&f=$2 last; if (!-e $request_filename) { rewrite ^/(.+)$ /r.php?_q=$1 last; break; } # Block requests with suspicious patternsif ($query_string ~* "(\%60|\%7C|\%26|\%24|\%3B|\%28|\%29)") {return 403; } } index index.php index.html index.htm; location ~ \.php$ { fastcgi_pass php:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # Add these timeout settings fastcgi_connect_timeout 3600; fastcgi_send_timeout 3600; fastcgi_read_timeout 3600; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; } ############################################################################# HSTS policy ############################################################################# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; # add_header Content-Security-Policy "default-src 'self'" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; ############################################################################# serve static files directly Tanks to Alex T https://una.io/u/alex-t ############################################################################# location ~* ^(/cache_public/|/plugins_public/|/modules/|/studio/|/template/).+\.(jpg|jpeg|gif|css|png|js|ico|svg|eot|ttf|woff|woff2|)$ { access_log off; expires 1h; # root /opt/una# add_header Cache-Control "public"; try_files $uri =404; } ############################################################################# deny access to hidden files ############################################################################# location ~ /(\.ht|\.git) { deny all; } ############################################################################# deny access to specific folders ############################################################################# location ~ ^/(cache/|storage/|logs/|plugins/|tmp/) { deny all; } ############################################################################# Memcached ############################################################################# location /memcached { set $memcached_key $uri; memcached_pass memcached_server; default_type application/json; error_page 404 = /memcached_not_found; } location = /memcached_not_found { return 404 "{\"error\": \"Not found in Memcached\"}"; } }
and my caddyfile reverse proxy:
{$EXEMPLE_HOSTNAME} { log { output discard } tls {$EXEMPLE_TLS} redir https://www.{host} } {$WWW_EXEMPLE_HOSTNAME} { log { output discard } tls {$EXEMPLE_TLS} @api { path /config path /healthz path /stats/errors path /stats/checker } @static { path /static } @notstatic { not path /static } @imageproxy { path /image_proxy } @notimageproxy { not path /image_proxy } header { # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enable cross-site filter (XSS) and tell browser to block detected attacks X-XSS-Protection "1; mode=block" # Prevent some browsers from MIME-sniffing a response away from the declared Content-Type X-Content-Type-Options "nosniff" # Disable some features Permissions-Policy "accelerometer=(self),ambient-light-sensor=(self),autoplay=(self),camera=(self),encrypted-media=(self),focus-without-user-activation=(),geolocation=(self),gyroscope=(self),magnetometer=(),microphone=(self),midi=(),payment=(),picture-in-picture=(),speaker=(self),sync-xhr=(self),usb=(),vr=()" # Disable some features (legacy)# Feature-Policy "accelerometer 'none';ambient-light-sensor 'none'; autoplay 'none';camera 'none';encrypted-media 'none';focus-without-user-activation 'none'; geolocation 'none';gyroscope 'none';magnetometer 'none';microphone 'none';midi 'none';payment 'none';picture-in-picture 'none'; speaker 'none';sync-xhr 'none';usb 'none';vr 'none'" # Referer Referrer-Policy "no-referrer" # X-Robots-Tag X-Robots-Tag "noindex, noarchive, nofollow" # Remove Server header -Server } header @api { Access-Control-Allow-Methods "GET, POST, OPTIONS" Access-Control-Allow-Origin "https://www.googleapis.com https://maps.googleapis.com https://www.exemple.com https://exemple.com https://onesignal.com"; } # Cache header @static { # Cache Cache-Control "public, max-age=31536000" defer } header @notstatic { # No Cache Cache-Control "no-cache, no-store" Pragma "no-cache" } # CSP (see http://content-security-policy.com/ )
#header @imageproxy {# Content-Security-Policy "default-src 'self' https://www.exemple.com; connect-src 'self' https://overpass-api.de https://maps.googleapis.com; img-src 'self' data: https://www.exemple.com; script-src 'self' https://www.exemple.com https://maps.googleapis.com"#} # header @notimageproxy {# Content-Security-Policy "upgrade-insecure-requests; connect-src 'self' https://overpass-api.de https://maps.googleapis.com;"#} handle { encode zstd gzip reverse_proxy localhost:80 { header_up X-Forwarded-Port {http.request.port} # header_up X-Forwarded-Proto {http.request.scheme} header_up X-Real-IP {remote_host} } } }