Estás arrancando la dockerización de tu aplicación PHP.
Como para probar un poco, arrancaste un contenedor usando un comando:
docker run -v $(pwd):/app -it php:latest index.php
Y ahí nomás te encontraste con el primero de los problemas:
PHP Fatal error: Uncaught Error: Class "ZipArchive" not found
Claro! Tu aplicación necesita de la extensión Zip para funcionar! ¿Y ahora?
Bueno, a no desesperar.
Tenés varias opciones disponibles:
- Buscar una imagen que ya tenga la extensión zip instalada
- Agregar las instrucciones para que se compile e instale la extensión durante el build de la imagen
- Usar un script de instalación
Para el resto de los ejemplos tomaré una versión hiper simplificada de lo que puede ser tu aplicación:
<?php $zip = new ZipArchive(); if ($zip->open($argv[1]) == TRUE) { for ($i = 0; $i < $zip->numFiles; $i++) { echo $zip->getNameIndex($i).PHP_EOL; } }
Y asumiré que tienes un archivo comprimido llamado compressed.zip
.
Una imagen Docker PHP con la extensión zip
Seguramente habrá muchas opciones, una de ellas, como para salir del paso, es thecodingmachine/php:7.3-v4-slim-cli
(Podés encontrar otras similares acá).
Para usarla este comando puede ser útil: docker run -v $(pwd):/usr/src/app --rm -it thecodingmachine/php:7.3-v4-slim-cli php index.php compressed.zip
Como decía, esta solución no es ni de lejos la mejor.
¿Por qué? Básicamente porque tenés muy poco control sobre lo que tiene la imágen. En otras palabras, no sabés muy bien qué otras cosas te estás trayendo además de la extensión zip.
En el mejor de los casos vas a terminar con una imagen más grande de lo necesario.
En el peor vas a incluir extensiones que no necesitás y exponerte a riesgos de seguridad.
Mejor seguir leyendo.
Compilar la extensión zip dentro del build de la imagen
Una forma de contar con la extensión zip (o cualquier otra en realidad) en tu contenedor es compilar php de modo que lo tenga incorporado.
Por ejemplo, usando un Dockerfile como este:
FROM ubuntu:latest ADD https://www.php.net/distributions/php-8.4.1.tar.gz /php/php.tar.gz RUN apt-get update && \ apt-get install -y libzip-dev build-essential pkg-config libxml2-dev libsqlite3-dev && \ tar xzf /php/php.tar.gz -C /php/ && \ cd /php/php-8.4.1/ && \ ./configure --prefix=/usr/local/php-8.4.1 --with-zip && \ make && make install && \ ln -s /usr/local/php-8.4.1/bin/php /usr/local/bin WORKDIR /app
Y construtendo la imagen usando docker build . -t php-zip
Podrías ejecutar tu script usando: docker run -v $(pwd):/app --rm -it php-zip php index.php compressed.zip
Y no verás el error que estaba al comienzo.
Esta opción, si bien es más correcta que la primera, puede resultar un poco overkill. Particularmente, si tenés que instalar varias extensiones, llegar al Dockerfile correcto puede ser bastante laborioso.
En la siguiente sección te doy la que personalmente recomiendo
Un script de instalación de extensiones PHP para Docker
Bueno, en realidad no es un script de instalación si no dos.
Arranco por el más conocido: php-ext-install
.
Lo bueno de este script es que, si partís de una imagen oficial de php, no tenés que hacer nada para tenerlo disponible.
Lo malo de este script es que requiere bastante ayuda para hacer lo suyo.
Por ejemplo, instalar la extensión zip implica agregar a tu Dockerfile
:
RUN docker-php-ext-install zip
Pero… con eso sólo no alcanza. Si lo intentas, al hacer el build verás este error:
Package 'libzip', required by 'virtual:world', not found
Package 'libzip', required by 'virtual:world', not found
Package 'libzip', required by 'virtual:world', not found
Lo que quiere decir que necesitas, antes de esto, instalar la librería zip.
En definitiva, el Dockerfile
que te dará lo que buscas es uno que se parezca a:
FROM php:8.4.1-cli RUN apt update && apt-get install -y libzip-dev && docker-php-ext-install zip
En este caso no ha sido tan terrible, cierto, pero hay otras extensiones que también requieren ciertos cambios en configuraciones. Nada del otro mundo pero es algo más que hay que recordar.
El script que me gusta más, y el que recomiendo usar, es docker-php-extension-installer
.
A diferencia del primero, docker-php-extension-installer
debe ser instalado explícitamente pero, una vez instalado, es mucho más cómodo.
Aquí un ejemplo de Dockerfile
para la extensión zip:
FROM php:8.4.1-cli ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ RUN install-php-extensions zip WORKDIR /app
Nuevamente, ejecutando docker run -v $(pwd):/app --rm -it php-zip php index.php compressed.zip
verás el listado de los archivos contenidos en el archivo comprimido.
- Cómo usar PHPUnit - 03/12/2024
- ¿Cómo instalar extensiones PHP en Docker? - 26/11/2024
- Cómo agregar una página de error 500 en un proyecto PHP - 31/10/2024