Skip to content

So konfigurieren Sie PHP-Datei-Uploads in Docker | php.ini · Nginx · docker-compose

Kategorie:Docker・PHP
Dieser Artikel ist derzeit nur auf Japanisch verfügbar. Übersetzte Versionen werden schrittweise veröffentlicht.

In mit Docker erstellten Umgebungen treten häufig Probleme auf wie 「lokal konfigurierte Einstellungen werden nicht im Container widerspiegelt」 und 「Nginx-Container wurden korrigiert, aber PHP-FPM-Container-Einstellungen bleiben bestehen」. Dies liegt daran, dass Docker-Container unabhängige Umgebungen haben, daher werden Konfigurationsdateien zwischen Host und Container getrennt. Dieser Artikel erläutert systematisch, wie Sie Datei-Upload-Einstellungen in der Kombination von Nginx- und PHP-FPM-Containern korrekt konfigurieren.

Benutzerdefinierte PHP-Konfiguration in Docker

Es gibt hauptsächlich zwei Methoden, um benutzerdefinierte php.ini-Einstellungen auf einen PHP-Container anzuwenden. Eine ist das Kopieren der Datei während des Image-Builds in der Dockerfile, die andere ist die Verwendung von Volume-Mounting in docker-compose.

Methode 1: <code>php.ini</code> in <code>Dockerfile</code> kopieren

# Dockerfile(PHP-FPM コンテナ)
FROM php:8.3-fpm-alpine

# 必要な拡張をインストール
RUN docker-php-ext-install pdo_mysql opcache

# カスタム php.ini をコンテナにコピー
# php.ini-development または php.ini-production をベースにする
COPY ./docker/php/php.ini /usr/local/etc/php/php.ini

# または conf.d ディレクトリに追加設定ファイルとして置く(推奨)
# 既存設定を上書きせず、変更したい値だけ記述できる
COPY ./docker/php/custom.ini /usr/local/etc/php/conf.d/99-custom.ini

WORKDIR /var/www/html

Methode 2: Volume-Mounting mit <code>docker-compose</code>

# docker-compose.yml
services:
  php:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    volumes:
      # アプリのソースコード
      - ./src:/var/www/html
      # php.ini をマウント(ファイル変更が即反映される)
      - ./docker/php/custom.ini:/usr/local/etc/php/conf.d/99-custom.ini:ro

Die Volume-Mount-Methode eignet sich für die Entwicklungsumgebung, da Änderungen an der Konfigurationsdatei durch einfachen Neustart des Containers widergespiegelt werden. Für die Produktionsumgebung wird die Dockerfile-Methode empfohlen, die in das Image kopiert (um die Reproduzierbarkeit des Images zu bewahren).

Erforderliche Konfigurationswerte und php.ini Schreibweise

Es gibt 4 Konfigurationswerte im Zusammenhang mit Datei-Uploads. Bereiten Sie eine <code>custom.ini</code>-Datei mit allen diesen Konfigurationen vor.

; docker/php/custom.ini
; ============================================
; ファイルアップロード関連の設定
; ============================================

; ファイルアップロードを有効化(デフォルトOnだが明示する)
file_uploads = On

; 1ファイルあたりのアップロード上限
; Nginx の client_max_body_size と合わせること
upload_max_filesize = 100M

; POSTリクエスト全体の上限
; upload_max_filesize より大きくすること(フォームフィールドのオーバーヘッド分)
post_max_size = 110M

; ============================================
; メモリ・実行時間の設定
; ============================================

; PHPスクリプトが使用できる最大メモリ
; post_max_size より大きくすること
memory_limit = 256M

; スクリプトの最大実行時間(秒)
; 大きなファイルのアップロードや処理に対応
max_execution_time = 300

; リクエストデータ(POSTやファイル)の読み込み最大時間(秒)
; -1 で max_execution_time に従う
max_input_time = 300

Wie man den Speicherort der php.ini-Konfigurationsdatei überprüft

Um zu überprüfen, welche <code>php.ini</code> im Container geladen wird, verwenden Sie den folgenden Befehl.

# コンテナ内で実行(docker exec 経由)
docker exec -it <コンテナ名> php -i | grep "php.ini"

# 出力例:
# Configuration File (php.ini) Path => /usr/local/etc/php
# Loaded Configuration File         => /usr/local/etc/php/php.ini

# Additional .ini files parsed(conf.d の追加設定)
docker exec -it <コンテナ名> php -i | grep "additional"
# Additional .ini files parsed => /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini,
#   /usr/local/etc/php/conf.d/99-custom.ini

# 特定の設定値を確認
docker exec -it <コンテナ名> php -i | grep -E "upload_max|post_max|memory_limit"
# upload_max_filesize => 100M
# post_max_size       => 110M
# memory_limit        => 256M

Um es über das Web zu überprüfen, verwenden Sie <code>phpinfo()</code>.

<?php
// /var/www/html/public/info.php (一時的なデバッグ用)
phpinfo();
// ※ 本番環境では削除すること(サーバー情報が丸見えになる)
Upload-Fluss mit Docker 2-Container-Konfiguration (Nginx + PHP-FPM) Client Browser Nginx-Container Nginx client_max_body_size PHP-FPM-Container PHP-FPM upload_max_filesize post_max_size App /var/www HTTP POST FastCGI :9000 Upload schlägt fehl, wenn beide Grenzwerte nicht übereinstimmen Upload-Pfad mit Docker 2-Container-Konfiguration
Abbildung 1: Upload-Ablauf mit 2-Container-Konfiguration Nginx + PHP-FPM

Konfigurationsbeziehung zwischen Nginx-Container und PHP-FPM-Container

Die typische PHP-Konfiguration in Docker ist eine 2-Container-Konfiguration, die den Nginx-Container und den PHP-FPM-Container trennt. Da jeder unabhängige Beschränkungen hat, <strong>schlägt der Upload fehl, wenn beide Konfigurationen nicht ordnungsgemäß sind</strong>.

クライアント
    │
    ▼(HTTP リクエスト)
┌──────────────────────────────┐
│  Nginx コンテナ              │  ← client_max_body_size で制限
│  client_max_body_size 100m;  │     ここを超えると 413 エラー
└──────────────────────────────┘
    │
    ▼(FastCGI プロトコル)
┌──────────────────────────────┐
│  PHP-FPM コンテナ            │  ← upload_max_filesize / post_max_size で制限
│  upload_max_filesize = 100M  │     ここを超えると UPLOAD_ERR_INI_SIZE
│  post_max_size = 110M        │
└──────────────────────────────┘
# docker/nginx/conf.d/default.conf
server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;
    index index.php;

    # Nginx レベルのアップロード上限
    # PHP の upload_max_filesize / post_max_size 以上にする
    client_max_body_size 110m;

    # タイムアウト設定(大容量ファイル処理用)
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;   # PHP-FPMコンテナのサービス名:ポート
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;

        # FastCGI のタイムアウト設定
        fastcgi_read_timeout 300s;
        fastcgi_send_timeout 300s;
    }
}

Vollständiges Konfigurationsbeispiel für docker-compose.yml

Wir zeigen ein vollständiges Beispiel einer <code>docker-compose.yml</code> mit Nginx + PHP-FPM + Volume Mount.

version: '3.8'

services:
  # Nginx コンテナ
  nginx:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    volumes:
      # アプリのソースコード(Nginx から静的ファイルを配信)
      - ./src:/var/www/html/public:ro
      # Nginx 設定ファイル
      - ./docker/nginx/conf.d:/etc/nginx/conf.d:ro
    depends_on:
      - php
    networks:
      - app-network

  # PHP-FPM コンテナ
  php:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    volumes:
      # アプリのソースコード
      - ./src:/var/www/html
      # PHP カスタム設定(開発時はマウントで即反映)
      - ./docker/php/custom.ini:/usr/local/etc/php/conf.d/99-custom.ini:ro
      # アップロードファイルの一時保存先(権限に注意)
      - upload_tmp:/tmp/php-uploads
    environment:
      PHP_UPLOAD_TMP_DIR: /tmp/php-uploads
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  upload_tmp:
    driver: local
# docker/php/Dockerfile
FROM php:8.3-fpm-alpine

# 必要なシステムパッケージ
RUN apk add --no-cache \
    libpng-dev \
    libjpeg-turbo-dev \
    libwebp-dev \
    freetype-dev

# PHP 拡張のインストール
RUN docker-php-ext-configure gd \
        --with-freetype \
        --with-jpeg \
        --with-webp && \
    docker-php-ext-install \
        gd \
        pdo_mysql \
        opcache \
        exif

# アプリユーザーを作成(www-data と権限を合わせる)
RUN addgroup -g 1000 appuser && \
    adduser -u 1000 -G appuser -s /bin/sh -D appuser

USER appuser
WORKDIR /var/www/html

Wie man überprüft, ob die Einstellung angewendet wurde

Nach Konfigurationsänderungen müssen Sie den Container immer neu starten und bestätigen, dass die Konfiguration korrekt geladen wurde.

# コンテナの再起動(設定ファイル変更を反映)
docker compose restart php

# または特定の設定値だけ確認
docker compose exec php php -r "echo ini_get('upload_max_filesize'), PHP_EOL;"
docker compose exec php php -r "echo ini_get('post_max_size'), PHP_EOL;"
docker compose exec php php -r "echo ini_get('memory_limit'), PHP_EOL;"

# 複数の値をまとめて確認
docker compose exec php php -r "
foreach (['upload_max_filesize', 'post_max_size', 'memory_limit', 'max_execution_time'] as \$key) {
    echo \$key . ' = ' . ini_get(\$key) . PHP_EOL;
}"

# Nginx の設定確認
docker compose exec nginx nginx -T | grep -E "client_max_body|server_name"

# Nginx の設定をリロード(コンテナ再起動なし)
docker compose exec nginx nginx -s reload

Häufige Probleme und Lösungen

Symptom Ursache Lösungsansatz
413 Request Entity Too Large <code>client_max_body_size</code> von Nginx überschritten Erhöhen Sie die Nginx-Konfiguration und führen Sie <code>nginx -s reload</code> aus
UPLOAD_ERR_INI_SIZE auf PHP-Ebene <code>upload_max_filesize</code> überschritten custom.ini ändern und Container neu starten
Die Einstellung wird nicht angewendet, obwohl sie geändert wurde Container-Neustart erforderlich / Bereitstellungspfad der Konfigurationsdatei ist falsch <code>docker compose restart php</code> / Pfad überprüfen
Fehler beim Schreiben in das temporäre Verzeichnis Benutzerberechtigungen des PHP-Containers stimmen nicht mit den Berechtigungen von <code>/tmp</code> überein Überprüfen Sie die Volumeberechtigungen und <code>upload_tmp_dir</code>
Timeout bei großen Dateien <code>fastcgi_read_timeout</code> oder <code>max_execution_time</code> sind zu kurz beide Werte erhöhen

Zusätzliche Hinweise für die Produktionsumgebung

Beachten Sie auch die folgenden Punkte in der Produktionsumgebung.

  • php.ini wird während des Image-Builds mit <code>COPY</code> eingebettet und nicht als Volume gemountet (für Reproduzierbarkeit)
  • Stellen Sie sicher, dass <code>display_errors = Off</code> und <code>log_errors = On</code> gesetzt sind
  • Bei Verwendung von Cloud-Speicher wie S3 als Upload-Ziel sollten Sie den lokalen Container-Speicher nur während der Anfrageverarbeitung behalten
  • Bei einer Konfiguration mit mehreren Replikaten (horizontale Skalierung) können Sie keine lokalen Upload-Ziele verwenden. Verwenden Sie S3 oder gemeinsamen Speicher (EFS/NFS).
  • Die Anzahl der PHP-FPM-Prozesse (<code>pm.max_children</code>) belastet auch den Speicher, wenn viele große Uploads gleichzeitig auftreten

Testdatei zur Verwendung in diesem Artikel (kostenlos)

  • → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Liste von Grenzwert-Testdateien</a> — Fehler nahe den upload_max_filesize-Konfigurationswerten reproduzieren und überprüfen
  • → <a href="/ja/files/images/" class="text-primary-600 dark:text-primary-400 hover:underline">Liste der Testbilder</a> — Überprüfen des Upload-Verhaltens in Docker-Umgebung in verschiedenen Größen

Verwandte Artikel

  • → <a href="/ja/blog/nginx-upload-config/" class="text-primary-600 dark:text-primary-400 hover:underline">Korrekte Konfiguration von Nginx client_max_body_size | Behebung von Upload-Limit-Problemen</a>
  • → <a href="/ja/blog/php-file-upload/" class="text-primary-600 dark:text-primary-400 hover:underline">So implementieren Sie Datei-Upload in PHP | Vollständiger Leitfaden zu Validierung, Speicherung und Sicherheit</a>
  • → <a href="/ja/blog/laravel-file-upload/" class="text-primary-600 dark:text-primary-400 hover:underline">Implementierungsleitfaden für Datei-Uploads in Laravel | Validierung, Storage und S3-Unterstützung</a>

Häufig gestellte Fragen

Wie ändert man upload_max_filesize von PHP in Docker?

Erstellen Sie eine benutzerdefinierte <code>php.ini</code>-Datei und kopieren Sie sie im Dockerfile in <code>/usr/local/etc/php/conf.d/</code> im Container.

Wie konfiguriere ich Uploads in Nginx und PHP-FPM mit docker-compose.yml?

Konfigurieren Sie <code>client_max_body_size</code> in <code>nginx.conf</code> für Nginx und <code>upload_max_filesize</code> in <code>php.ini</code> für PHP und mounten Sie diese jeweils mit Volumes.

Warum werden Upload-Einstellungen in der Docker-Umgebung nicht widergespiegelt?

Der Speicherort von php.ini könnte falsch sein. Überprüfen Sie den aktuellen Konfigurationswert mit <code>php -i | grep upload_max_filesize</code> und bestätigen Sie, welche ini-Datei in Loaded Configuration File gelesen wird.