Saltar al contenido

Cómo configurar opciones de carga de archivos de PHP en Docker | php.ini, Nginx, docker-compose

Categoría: Docker / PHP
Este artículo está disponible actualmente solo en japonés. Estamos trabajando en las traducciones.

En entornos Docker, problemas como "configuración aplicada localmente pero no reflejada en el contenedor" o "corregido el contenedor Nginx pero la configuración del contenedor PHP-FPM permanece" son comunes. Esto se debe a que los contenedores Docker tienen entornos aislados donde los archivos de configuración se separan entre el host y el contenedor. Este artículo explica sistemáticamente cómo configurar correctamente las cargas de archivos con contenedores Nginx y PHP-FPM.

Métodos de configuración personalizada de PHP en Docker

Hay principalmente dos formas de aplicar configuración personalizada de php.ini a un contenedor PHP: copiar el archivo durante la compilación de imagen en Dockerfile, o usar montaje de volumen en docker-compose.

Método 1: Copiar <code>php.ini</code> en Dockerfile

# 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

Método 2: Montar volumen con docker-compose

# 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

El montaje de volumen es adecuado para entornos de desarrollo y se puede aplicar simplemente modificando el archivo de configuración e reiniciando el contenedor. Para entornos de producción, se recomienda el método Dockerfile de copiar a la imagen (para mantener la reproducibilidad de la imagen).

Valores de configuración requeridos y cómo escribir <code>php.ini</code>

Hay 4 valores de configuración relacionados con cargas de archivos. Prepararemos un archivo <code>custom.ini</code> con estas configuraciones consolidadas.

; 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

Cómo encontrar la ubicación del archivo de configuración php.ini

Para verificar cuál <code>php.ini</code> se está cargando dentro del contenedor, utilice el siguiente comando.

# コンテナ内で実行(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

Para verificar a través de la web, use <code>phpinfo()</code>.

<?php
// /var/www/html/public/info.php (一時的なデバッグ用)
phpinfo();
// ※ 本番環境では削除すること(サーバー情報が丸見えになる)
Flujo de subida en Docker (Nginx + PHP-FPM) Client Browser Contenedor Nginx Nginx client_max_body_size Contenedor PHP-FPM PHP-FPM upload_max_filesize post_max_size App /var/www HTTP POST FastCGI :9000 Ambos límites deben coincidir o la subida falla Ruta de subida en configuración Docker de 2 contenedores
Fig 1: Flujo de subida con configuración de 2 contenedores

Relación de configuración entre contenedores Nginx y PHP-FPM

Una configuración típica de PHP en Docker es una arquitectura de 2 contenedores que separa los contenedores de Nginx y PHP-FPM. Como cada uno tiene límites independientes, <strong>las cargas fallarán si ambos no están configurados correctamente</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;
    }
}

Ejemplo completo de configuración de docker-compose.yml

Aquí se muestra un ejemplo completo de docker-compose.yml que incluye Nginx + PHP-FPM + montaje de volumen.

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

Cómo verificar si los ajustes se han aplicado

Después de cambiar la configuración, siempre reinicie el contenedor y verifique que la configuración se esté cargando correctamente.

# コンテナの再起動(設定ファイル変更を反映)
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

Problemas comunes y soluciones

Síntomas Causa Solución
413 Request Entity Too Large Límite de <code>client_max_body_size</code> de Nginx superado Aumenta la configuración de Nginx y ejecuta <code>nginx -s reload</code>
UPLOAD_ERR_INI_SIZE a nivel de PHP <code>upload_max_filesize</code> superado Modificar custom.ini y reiniciar el contenedor
Los ajustes no se aplican aunque se cambien Se requiere reiniciar el contenedor / Ruta de montaje incorrecta para el archivo de configuración <code>docker compose restart php</code> / Verificar la ruta
Error al escribir en el directorio temporal Desajuste entre los permisos de usuario del contenedor PHP y los permisos de <code>/tmp</code> Verifique la configuración de permisos de volumen y <code>upload_tmp_dir</code>
Tiempo de espera agotado con archivos grandes <code>fastcgi_read_timeout</code> o <code>max_execution_time</code> es demasiado corto Aumentar ambos valores

Notas para el entorno de producción

También considere los siguientes puntos en el entorno de producción.

  • Incorporar php.ini con <code>COPY</code> durante la compilación de la imagen y no montarlo como volumen (para reproducibilidad)
  • Siempre configure <code>display_errors = Off</code> y <code>log_errors = On</code>
  • Cuando el destino de carga es almacenamiento en la nube como S3, mantenga el almacenamiento temporal en el local del contenedor solo durante el procesamiento de la solicitud.
  • En una configuración de múltiples réplicas (escala horizontal), no puede usar destinos de carga locales. Use S3 o almacenamiento compartido (EFS, NFS) en su lugar.
  • El número de procesos PHP-FPM (<code>pm.max_children</code>) también puede sobrecargar la memoria cuando ocurren muchas cargas grandes simultáneamente

Archivos de prueba para este artículo (gratis)

  • → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de archivos de prueba de valores límite</a> — Reproducir y verificar errores alrededor del límite upload_max_filesize
  • → <a href="/ja/files/images/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de imágenes de prueba</a> — Verificar el comportamiento de carga en el entorno Docker con varios tamaños

Artículos relacionados

  • → <a href="/ja/blog/nginx-upload-config/" class="text-primary-600 dark:text-primary-400 hover:underline">Cómo Configurar Correctamente client_max_body_size en Nginx | Solución de Problemas de Límites de Carga</a>
  • → <a href="/ja/blog/php-file-upload/" class="text-primary-600 dark:text-primary-400 hover:underline">Cómo Implementar la Carga de Archivos en PHP | Guía Completa de Validación, Almacenamiento y Seguridad</a>
  • → <a href="/ja/blog/laravel-file-upload/" class="text-primary-600 dark:text-primary-400 hover:underline">Guía de Implementación de Carga de Archivos en Laravel | Validación, Storage y S3</a>

Preguntas frecuentes

¿Cómo cambiar upload_max_filesize de PHP en Docker?

Cree un archivo <code>php.ini</code> personalizado y cópielo a <code>/usr/local/etc/php/conf.d/</code> dentro del contenedor a través del Dockerfile.

¿Cómo configurar los ajustes de carga para Nginx y PHP-FPM en docker-compose.yml?

Configure client_max_body_size en nginx.conf para Nginx y upload_max_filesize en php.ini para PHP, luego monte cada uno con volumes.

¿Por qué no se reflejan las opciones de carga en entornos Docker?

La ubicación de php.ini podría ser incorrecta. Verifique el valor de configuración actual con <code>php -i | grep upload_max_filesize</code> y compruebe qué archivo ini se está cargando en Loaded Configuration File.