From 34a4852905e2087a51d62babadad8f48605b4202 Mon Sep 17 00:00:00 2001 From: Romano Tebest Date: Tue, 4 Aug 2026 13:36:45 +0200 Subject: [PATCH] fix: restore PHP upload limits and OPcache tuning in the production image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FrankenPHP base image loads no php.ini at all — neither php.ini-production nor php.ini-development — so PHP's built-in defaults apply. Verifiable in the base image: docker run --rm dunglas/frankenphp:1-php8.4 \ php -r 'echo ini_get("upload_max_filesize"), " ", php_ini_loaded_file() ?: "none";' -> 2M none The application accepts vehicle documents up to 25 MB and images up to 10 MB, so every upload above 2 MB failed in the published image — and failed before reaching the application's own validation, with a message that does not name the size as the cause. 42f923d intended to fold these limits into the image when it removed docker/uploads-prod.ini and docker/opcache-prod.ini, but no ini settings made it into the Dockerfile. This restores both as a single docker/php-prod.ini copied to /usr/local/etc/php/conf.d/, prefixed zz- so the OPcache values win over docker-php-ext-opcache.ini. Also sets display_errors=Off and expose_php=Off: Laravel switches display_errors off itself, but only once the framework is booted — an error before that would reach the browser with paths and source lines. Verified in the built image: upload_max_filesize=30M, post_max_size=32M, opcache.memory_consumption=256, display_errors and expose_php off. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 4 +++- Dockerfile | 4 ++++ docker/php-prod.ini | 48 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 docker/php-prod.ini diff --git a/CLAUDE.md b/CLAUDE.md index a398a75..ac695cc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,7 +56,9 @@ Feldnamen ab. - **Upload-Grenzen liegen auf drei Ebenen und müssen zusammenpassen.** Greift die äußerste, scheitert der Upload mit einer Meldung, aus der die Ursache nicht hervorgeht („Feld ist erforderlich" statt einer Aussage zur Größe): - 1. PHP — `docker/uploads-prod.ini` (im Image; php.ini-production erlaubt sonst nur 2 MB) + 1. PHP — `docker/php-prod.ini` (wird im `Dockerfile` nach + `/usr/local/etc/php/conf.d/` kopiert; das FrankenPHP-Basisimage lädt keine php.ini, + PHPs eingebauter Standard erlaubt nur 2 MB) 2. Livewire — `config/livewire.php`, `temporary_file_upload.rules` (Standard sind 12 MB) 3. Filament — `maxSize()` am Feld, aus `MAX_FILE_SIZE_KB` bzw. `MAX_IMAGE_SIZE_KB` Aktuell: Dokumente 25 MB, Bilder 10 MB, darüber 30 MB Puffer bei Livewire und PHP. Die diff --git a/Dockerfile b/Dockerfile index b671e10..8320800 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,6 +43,10 @@ RUN apt-get update \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Das Basisimage lädt keine php.ini, es gelten PHPs eingebaute Standardwerte. +# Ohne diese Datei begrenzt PHP Uploads auf 2 MB — die Anwendung erlaubt 25 MB. +COPY docker/php-prod.ini /usr/local/etc/php/conf.d/zz-app-prod.ini + COPY --from=composer:2 /usr/bin/composer /usr/bin/composer COPY composer.json composer.lock ./ diff --git a/docker/php-prod.ini b/docker/php-prod.ini new file mode 100644 index 0000000..fc078b2 --- /dev/null +++ b/docker/php-prod.ini @@ -0,0 +1,48 @@ +; PHP-Einstellungen für den Betrieb im Image. +; +; Das FrankenPHP-Basisimage lädt bewusst *keine* php.ini — weder +; php.ini-production noch php.ini-development. Es gelten also PHPs eingebaute +; Standardwerte, und die sind für diese Anwendung an zwei Stellen zu klein. +; Prüfbar im Basisimage mit: +; +; docker run --rm dunglas/frankenphp:1-php8.4 \ +; php -r 'echo ini_get("upload_max_filesize"), " ", php_ini_loaded_file() ?: "keine";' +; -> 2M keine +; +; Diese Datei landet in /usr/local/etc/php/conf.d/ und wird deshalb geladen. + +; --- Upload-Grenzen ------------------------------------------------------- +; +; Der eingebaute Standard ist upload_max_filesize=2M und post_max_size=8M. Die +; Anwendung lässt Fahrzeugdokumente bis 25 MB und Bilder bis 10 MB zu (siehe +; VehicleDocumentsRelationManager::MAX_FILE_SIZE_KB und +; VehicleForm::MAX_IMAGE_SIZE_KB). Ohne diese Werte scheitert ein größerer +; Upload nicht an der Prüfung der Anwendung, sondern schon vorher an PHP — und +; zwar mit einer Meldung, aus der die Ursache nicht hervorgeht („Feld ist +; erforderlich" statt einer Aussage zur Größe). +; +; Wer die Grenzen in der Anwendung ändert, muss diese Werte mitziehen. +; post_max_size muss über upload_max_filesize liegen: der Wert umfasst den +; gesamten Formularinhalt, nicht nur die Datei. +upload_max_filesize = 30M +post_max_size = 32M + +; --- OPcache -------------------------------------------------------------- +; +; Die Erweiterung ist im Basisimage vorhanden, aber ungetunt. +; validate_timestamps bleibt bewusst auf dem Standard (an): bei dieser +; Nutzerzahl kostet der stat-Aufruf nichts Messbares, und ein neues Deployment +; (neues Image, frischer Container) liefert damit immer aktuellen Code, ohne +; dass zusätzlich ein Cache verworfen werden muss. +opcache.enable = 1 +opcache.memory_consumption = 256 +opcache.max_accelerated_files = 20000 +opcache.interned_strings_buffer = 16 + +; --- Betrieb -------------------------------------------------------------- +; +; Laravel schaltet display_errors selbst ab (HandleExceptions), aber erst wenn +; das Framework läuft. Ein Fehler davor — etwa eine fehlende Erweiterung — +; würde sonst mit Pfaden und Codezeilen im Browser landen. +display_errors = Off +expose_php = Off