Eugenio Goryaev
Desarrollo, soporte y optimización

El imagen docker perfecta de php-fpm

La ilustración para el artículo El imagen docker perfecta de php-fpm

Para todos los que utilizan el docker en sus proyectos web php, se plantea la cuestión de construir un contenedor para el proyecto. Algunos usan contenedores Apache con php como módulo, pero yo, como la mayoría de los desarrolladores, prefiero construir mi contenedor para aplicaciones basadas en php-fpm.

El problema principal es que php-fpm original no contiene los módulos php suficientes para funcionar plenamente, ni el software de apoyo que se necesita periódicamente.

La situación se agrava si tenemos que mantener varios proyectos en el mismo stack. Este es mi caso, porque tengo más de 10 proyectos en apoyo y perfeccionamiento normalmente tengo más de 10 proyectos en el framework Yii2. Todos los utilizan aproximadamente el mismo stack: [Yii2 framework] (https://www.yiiframework.com/), php-fpm, nginx, memcached y una base como mysql o postgres.

Por lo tanto, sobre la base de mi experiencia, el contenedor de base con php-fpm debe completarse con las siguientes bibliotecas php:

  • GD - que tiene obligatoriamente WEBP;
  • IMAP - para enviar correo electrónico;
  • Zip - como mínimo para el trabajo con los copias de seguridad;
  • Intl - módulo necesario para la internacionalización;
  • Pdo _ mysql - para trabajar con Mysql;
  • Pdo _ pgsq - para trabajar con Postgresql
  • Memcached - para la caché
  • Xdebug - Sólo lo activaré cuando sea necesario.

Además de estas bibliotecas, pongo un software adicional:

  • git
  • composer
  • zip
  • ffmpeg
  • mysql-client
  • postgresql-client

En esta lista, el git se encuentra porque es necesario para el trabajo de composer. Uso Zip porque trabajo con módulo de Yii2 para copias de seguridad que utiliza zip para comprimir. FFmpeg uso para que el módulo de archivos de Yii2 pueda convertir archivos de vídeo. Bueno, los clientes de consola para mysql y postgresql apuestan por la versatilidad, ya que mis aplicaciones funcionan con ambas bases de datos y, en algunos casos, con dos al mismo tiempo.

Al final, yo tengo un contenedor php versátil y flexible que tiene todo lo que necesita para diseñar, iniciar un proyecto en producción o crear una imagen final basada en él.

Para facilitar el soporte de las dos ramas de php que necesito, las tengo en diferentes ramas del mi repositorio. Recolectando a través de gitlab CI y guardándome en público en el , gitlab registry.

Después de la fase de desarrollo, tenemos que reunir todo lo necesario para el proyecto en una imagen de docker separada. Normalmente lo hago a partir de las imágenes mencionadas. Copio en el contenedor:

  • Los archivos de proyecto necesarios para funcionar;
  • php.ini con los parámetros óptimos para el proyecto (por lo menos, el aumento de upload _ max _ file_size' ypost max size`, establecer una zona temporal).
  • Config para nginx, que en el futuro se descifrará con el contenedor que se ejecuta al lado;
  • Config para la base de datos si necesita más configuración.

Después de esto, suelo iniciar la instalación de adicciones con composer install --no-scripts --prefer-set --optimize-autoloader.. Pero también instalo paquetes de dev-z (codeception, yii-debug y otros componentes necesarios para las pruebas). Como monto aplicaciones en un CI de gitlab y hago un contenedor que se envía directamente a la producción. tengo que tener una dependencia dev. Aunque después de las pruebas, podemos eliminar esos paquetes del contenedor. Lo contaré en otros artículos.

Si desea reducir el tamaño de la imagen final, puede editar la imagen original dockerfile eliminando paquetes y bibliotecas que no necesitan en su proyecto.Además, puede quitar todo el software innecesario del contenedor después del conjunto de la aplicación. Sin embargo, ese no es mi enfoque. Es más fácil para mí que las imágenes de los diferentes proyectos no sean diferentes. Y que todos los tengan los útiles instrumentos necesarios para el desarrollo y el debug.

En el momento de escribir el artículo, yo hago la imagen a partir del dockerfile que figura a continuación. Sin embargo, la versión actual puede encontrarse en mi repository de gitlab.

FROM php:7.4-fpm

RUN apt-get update
RUN apt-get install -y \
            git \
            libzip-dev \
            libc-client-dev \
            libkrb5-dev \
            libpng-dev \
            libjpeg-dev \
            libwebp-dev \
            libfreetype6-dev \
            libkrb5-dev \
            libicu-dev \
            zlib1g-dev \
            zip \
            ffmpeg \
            libmemcached11 \
            libmemcachedutil2 \
            build-essential \
            libmemcached-dev \
            gnupg2 \
            libpq-dev \
            libpq5 \
            libz-dev

RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main 9.5' > /etc/apt/sources.list.d/pgdg.list

RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

RUN apt-get update && apt-get install -y postgresql-client-9.5

RUN docker-php-ext-configure gd \
    --with-webp=/usr/include/ \
    --with-freetype=/usr/include/ \
    --with-jpeg=/usr/include/
RUN docker-php-ext-install gd

RUN docker-php-ext-configure imap \
    --with-kerberos \
    --with-imap-ssl
RUN docker-php-ext-install imap

RUN docker-php-ext-configure zip

RUN docker-php-ext-install zip

RUN docker-php-ext-configure intl
RUN docker-php-ext-install intl

RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install pdo_pgsql
RUN docker-php-ext-install exif
RUN docker-php-ext-install fileinfo

RUN pecl install xdebug

RUN curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN pecl install memcached

RUN echo extension=memcached.so >> /usr/local/etc/php/conf.d/memcached.ini

ENV COMPOSER_ALLOW_SUPERUSER 1

WORKDIR /app