¿Cómo cambiar el upload_max_file_size desde el Dockerfile?

Que tiempos aquellos en que el tamaño los archivos que se subían vía HTTP se medía en KB, ¿no? Qué fácil era la vida por entonces.

Pero bueno… el mundo avanza y con él la necesidad de compartir nuestras fotos en alta calidad se hace presente.

En ese contexto, tener un upload máximo de 2 MB puede convertirse en un gran limitante.

Y, casualmente, el tamaño máximo por defecto del upload_max_filesize de PHP es de… 2 MB.

En un ambiente de desarrollo normal modificar esto es fácil, ¿no?

Basta con:

  1. Ejecutar el comando php --ini
  2. Abrir el archivo referido en Configuration File (php.ini)
  3. Buscar la línea upload_max_filesize = 2M
  4. Modificarla por un valor acorde a nuestras necesidades (Por ejemplo upload_max_filesize => 10M)
  5. Reiniciar el servidor (o php-fpm)

Pero si estamos usando un contenedor Docker las cosas no son tan simples.

Es decir, hacer el cambio en sí no presenta una dificultad especial:

docker exec -it 7b8da0fb9892 bash
apt update
apt install -y vim
vim /usr/local/etc/php/php.ini

Modificar el valor de la configuración, guardar y listo.

El problema es que… apenas el contenedor se destruya, el cambio se fue con él y estamos otra vez donde empezamos.

Es todo una cuestión de imagen

La solución basada en el Dockerfile pasa por tener, dentro de la imagen que se construya, una definición del php.ini que contenga los cambios que necesitamos.

¿Cómo lograr eso? Pues se trata de tener, dentro de nuestro proyecto, nuestro propio php.ini y meterlo dentro de la imagen durante el build.

En concreto, supongamos que partimos de un Dockerfile que se ve así:

FROM php:7.4-apache

LABEL authors="Mauro Chojrin <mauro.chojrin@leewayweb.com>"

RUN apt-get update && \
    apt-get install -y \
        libpng-dev \
        libzip-dev

RUN docker-php-ext-install gd && \
    docker-php-ext-install zip && \
    docker-php-ext-install mysqli

ADD app /var/www/html

Con esto podemos crear una imagen para luego levantar un contenedor con un Apache que podrá procesar php para responder a las peticiones.

En este ejemplo, el código (El contenido del directorio /var/www/html dentro del contenedor) será el que se encuentre dentro del directorio app de nuestro proyecto.

Lo que toca hacer es agregar un archivo php.ini dentro del proyecto e indicar a Docker que lo agregue a la imagen durante el build:

FROM php:7.4-apache

LABEL authors="Mauro Chojrin <mauro.chojrin@leewayweb.com>"

RUN apt-get update && \
    apt-get install -y \
        libpng-dev \
        libzip-dev

RUN docker-php-ext-install gd && \
    docker-php-ext-install zip && \
    docker-php-ext-install mysqli

ADD app /var/www/html

ADD php.ini /usr/local/etc/php/

¿Qué debería contener el archivo php.ini? Si queremos asegurarnos de que sólo se modifique el upload_max_filesize necesitamos empezar por un archivo que contenga la configuración presente dentro del contenedor.

Cómo obtener el archivo original

Lo primero que podemos probar es buscar el archivo dentro del contenedor1:

docker exec -it 7b8da0fb9892 php --ini

Esto dará un resultado similar a:

Configuration File (php.ini) Path: /usr/local/etc/php
Loaded Configuration File:         (none)
Scan for additional .ini files in: /usr/local/etc/php/conf.d
Additional .ini files parsed:      /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini

Si tuviera un archivo lo copiaría usando:

docker cp 7b8da0fb9892:/usr/local/etc/php/php.ini .

Pero, como en mi caso me indica que el archivo de configuración cargado es ninguno, tendré que probar otra cosa.

Lo que haré será crear en el directorio del proyecto un pequeño script llamado dump_php_ini.php:

<?php 
$s = []
foreach(ini_get_all() as $k=>$v) {
     if ($v['local_value'] || $v['global_value']) {
        $s[] = sprintf("%s = %s", $k, $v['local_value']?$v['local_value']:$v['global_value']);
    }
}

echo join("\n", $s);

Y luego ejecutar este comando:

docker run -v $(pwd):/var/www/html -it php:7.4-apache php dump_php_ini.php > php.ini

Con eso tengo el archivo que contiene la configuración exacta que se está usando actualmente.

Y ahora sí, puedo editarlo, hacer la modificación que se requiere y volver a construir la imagen usando:

docker build . -t my_apache_php

A partir de aquí, todos los contenedores que sean creados usando este Dockerfile tendrán la configuración deseada y los visitantes del sitio podrán compartir sus fotos sin inconvenientes.

  1. Cambia el ID del contenedor por el tuyo ↩︎
mchojrin

Por mchojrin

Ayudo a desarrolladores PHP a acceder mercados y clientes más sofisticados y exigentes

¿Te quedó alguna duda? Publica aca tu pregunta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.