Despliegue y Compilación de un Stack LNMP con PHP 8.1.18 y Contenedores Docker

La compilación de bases de datos como MySQL desde el código fuente requiere una cantidad considerable de recursos de hardware y tiempo. Por este motivo, el presente guide se centra exclusivamente en la compilación de Nginx y PHP 8.1.18, así como en la integración de ambos componentes. La integración con MySQL es un proceso independiente que se adapta a los requerimientos específicos de cada arquitectura.

Compilación e Instalación de Nginx

Preparación del Entorno

En primer lugar, se debe crear un usuario dedicado sin acceso a shell para eejcutar los procesos del servidor web:

groupadd webapp
useradd -s /sbin/nologin -g webapp webapp

A continuación, se instalan las bibliotecas y herramientas de desarrollo necesarias:

yum -y install gcc gcc-c++ make zlib-devel pcre pcre-devel openssl openssl-devel \
libxslt-devel gd gd-devel GeoIP GeoIP-devel libxml2 libxml2-devel

Descarga y Compilación

Se procede a descargar el código fuente y a descomprimirlo:

wget --no-check-certificate https://nginx.org/download/nginx-1.22.1.tar.gz
tar -xvf nginx-1.22.1.tar.gz
cd nginx-1.22.1/

La configuración de compilación se realiza definiendo rutas personalizadas y habilitando los módulos requeridos:

./configure \
--user=webapp \
--group=webapp \
--prefix=/opt/nginx \
--sbin-path=/opt/nginx/sbin/nginx \
--conf-path=/opt/nginx/conf/nginx.conf \
--error-log-path=/opt/nginx/logs/error.log \
--http-log-path=/opt/nginx/logs/access.log \
--pid-path=/var/run/nginx.pid \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module \
--with-http_image_filter_module \
--with-http_geoip_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gzip_static_module \
--with-http_gunzip_module \
--with-http_auth_request_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-pcre \
--with-http_v2_module

make -j $(nproc) && make install
ln -sf /opt/nginx/sbin/nginx /usr/local/bin/nginx

Configuración del Servidor Web

Se ajusta el archivo de configuración principle para optimizar el rendimiento y definir los hosts virtuales:

vim /opt/nginx/conf/nginx.conf
user webapp;
worker_processes auto;
pid /var/run/nginx.pid;
error_log logs/error.log warn;
worker_rlimit_nofile 65535;

events {
    use epoll;
    worker_connections 65535;
}

http {
    include mime.types;
    default_type application/octet-stream;
    
    log_format custom_log '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';

    access_log logs/access.log custom_log;
    server_tokens off;
    
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 65;

    server_names_hash_bucket_size 128;
    client_max_body_size 30m;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 3;
    gzip_types text/plain application/javascript text/css application/xml;
    gzip_vary on;
    
    server {
        listen 80;
        charset utf-8;
        access_log logs/host.access.log custom_log;
        
        location / {
            root html;
            index index.html index.htm index.php;
        }
        
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        
        location = /50x.html {
            root html;
        }
    }
}

Gestión del Servicio

# Ejecución en primer plano
nginx -g "daemon off;"

# Ejecución en segundo plano
nginx

# Detener el servicio
nginx -s stop

# Recargar configuración
nginx -s reload

Compilación e Instalación de PHP 8.1.18

La versión 8.1 de PHP es requerida por aplicaciones modernas como PowerDNS Admin. Es importante notar que los pasos de compilación difieren significativamente de las ramas 7.x.

Dependencias y Bibliotecas Auxiliares

Se instalan las dependencias base y se elimina cualquier versión previa de libzip para evitar conflictos:

yum -y install libxml2-devel bzip2-devel libjpeg-turbo-devel libpng-devel \
freetype-devel zlib-devel libcurl-devel openssl-devel sqlite-devel libwebp-devel
yum remove -y libzip

Compilación de libzip, freetype y libiconv desde el código fuente:

# Libzip
wget --no-check-certificate https://libzip.org/download/libzip-1.3.2.tar.gz
tar -xvf libzip-1.3.2.tar.gz && cd libzip-1.3.2
./configure && make -j $(nproc) && make install
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/"
ldconfig
cd ..

# Freetype
wget --no-check-certificate https://download.savannah.gnu.org/releases/freetype/freetype-2.10.4.tar.gz
tar -xvf freetype-2.10.4.tar.gz && cd freetype-2.10.4
./configure --prefix=/opt/freetype && make -j $(nproc) && make install
cd ..

# Libiconv
wget --no-check-certificate https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.17.tar.gz
tar -xvf libiconv-1.17.tar.gz && cd libiconv-1.17
./configure --prefix=/opt/libiconv && make -j $(nproc) && make install
cd ..

Se configura el repositorio Remi para obtener la biblioteca oniguruma:

wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/remi/enterprise/remi-release-7.rpm
rpm -ivh remi-release-7.rpm
yum -y install --enablerepo=remi oniguruma5php oniguruma5php-devel

Compilación de PHP

wget --no-check-certificate https://www.php.net/distributions/php-8.1.18.tar.gz
tar -xvf php-8.1.18.tar.gz && cd php-8.1.18

./configure \
--prefix=/opt/php81 \
--with-config-file-path=/opt/php81/etc \
--with-config-file-scan-dir=/opt/php81/conf.d \
--enable-fpm \
--with-fpm-user=webapp \
--with-fpm-group=webapp \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-iconv \
--with-freetype=/opt/freetype \
--with-jpeg \
--with-zlib \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-ftp \
--enable-gd \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-zip \
--enable-soap \
--with-gettext \
--enable-opcache \
--with-xsl \
--with-pear \
--with-webp 

make -j $(nproc) && make install

Configuración y Optimización de PHP

Se crean los enlaces simbólicos y se ajusta el archivo php.ini:

ln -sf /opt/php81/bin/php /usr/local/bin/php
ln -sf /opt/php81/sbin/php-fpm /usr/local/bin/php-fpm

cp php.ini-production /opt/php81/etc/php.ini
mkdir -p /opt/php81/conf.d

# Ajustes de rendimiento y seguridad
sed -i 's/^post_max_size.*/post_max_size = 64M/' /opt/php81/etc/php.ini
sed -i 's/^upload_max_filesize.*/upload_max_filesize = 64M/' /opt/php81/etc/php.ini
sed -i 's/^;date.timezone.*/date.timezone = UTC/' /opt/php81/etc/php.ini
sed -i 's/^short_open_tag.*/short_open_tag = On/' /opt/php81/etc/php.ini
sed -i 's/^;cgi.fix_pathinfo.*/cgi.fix_pathinfo=0/' /opt/php81/etc/php.ini
sed -i 's/^max_execution_time.*/max_execution_time = 300/' /opt/php81/etc/php.ini

Integración de Nginx y PHP-FPM

Se configura el pool de procesos de PHP-FPM:

cp /opt/php81/etc/php-fpm.conf.default /opt/php81/etc/php-fpm.conf
cd /opt/php81/etc/php-fpm.d/
cp www.conf.default app_pool.conf

Edición del pool app_pool.conf:

[app_pool]
user = webapp
group = webapp
listen = 127.0.0.1:9001
pm = dynamic
pm.max_children = 60
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 35
listen.owner = webapp
listen.group = webapp
listen.mode = 0660
pm.max_requests = 1024
request_terminate_timeout = 120

Se actualiza la configuración de Nginx para procesar archvios PHP mediante FastCGI:

location ~ \.php$ {
    root html;
    fastcgi_pass 127.0.0.1:9001;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /opt/nginx/html$fastcgi_script_name;
    include fastcgi_params;
}

Contenerización con Docker

Para facilitar el despliegue y la portabilidad, se encapsulan los servicios en imágenes de Docker.

Dockerfile para Nginx

FROM rockylinux:8
LABEL maintainer="devops-team"

ADD ./nginx-1.22.1.tar.gz /tmp/
WORKDIR /tmp/nginx-1.22.1

RUN dnf -y install gcc gcc-c++ make zlib-devel pcre-devel openssl-devel gd-devel GeoIP-devel libxml2-devel && \
    ./configure \
    --user=root \
    --group=root \
    --prefix=/opt/nginx \
    --sbin-path=/opt/nginx/sbin/nginx \
    --conf-path=/opt/nginx/conf/nginx.conf \
    --error-log-path=/opt/nginx/logs/error.log \
    --http-log-path=/opt/nginx/logs/access.log \
    --pid-path=/var/run/nginx.pid \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_realip_module \
    --with-http_gzip_static_module \
    --with-stream \
    --with-stream_ssl_module && \
    make -j $(nproc) && make install && \
    dnf clean all && rm -rf /tmp/*

COPY ./nginx.conf /opt/nginx/conf/nginx.conf
EXPOSE 80 443
HEALTHCHECK --interval=10s --timeout=3s CMD curl -fs http://localhost/ || exit 1
CMD ["/opt/nginx/sbin/nginx", "-g", "daemon off;"]

Dockerfile para PHP

FROM rockylinux:8
LABEL maintainer="devops-team"

ADD ./freetype-2.10.4.tar.gz /tmp/
ADD ./libiconv-1.17.tar.gz /tmp/
ADD ./libzip-1.3.2.tar.gz /tmp/
ADD ./php-8.1.18.tar.gz /tmp/

ENV PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/"

RUN dnf -y install epel-release && \
    dnf -y install gcc gcc-c++ make libxml2-devel bzip2-devel libjpeg-turbo-devel \
    libpng-devel zlib-devel libcurl-devel openssl-devel sqlite-devel libwebp-devel \
    libxslt-devel libicu-devel oniguruma-devel && \
    cd /tmp/libzip-1.3.2 && ./configure && make && make install && ldconfig && \
    cd /tmp/freetype-2.10.4 && ./configure --prefix=/opt/freetype && make && make install && \
    cd /tmp/libiconv-1.17 && ./configure --prefix=/opt/libiconv && make && make install

WORKDIR /tmp/php-8.1.18
RUN ./configure \
    --prefix=/opt/php81 \
    --with-config-file-path=/opt/php81/etc \
    --enable-fpm \
    --with-fpm-user=webapp \
    --with-fpm-group=webapp \
    --enable-mysqlnd \
    --with-mysqli=mysqlnd \
    --with-pdo-mysql=mysqlnd \
    --with-freetype=/opt/freetype \
    --with-jpeg \
    --with-zlib \
    --enable-mbstring \
    --enable-intl \
    --enable-gd \
    --with-openssl \
    --with-zip \
    --enable-opcache && \
    make -j $(nproc) && make install && \
    cp php.ini-production /opt/php81/etc/php.ini && \
    groupadd -r webapp && useradd -r -g webapp webapp && \
    chown -R webapp:webapp /opt/php81 && \
    dnf clean all && rm -rf /tmp/*

COPY ./www.conf /opt/php81/etc/php-fpm.d/www.conf
EXPOSE 9000
CMD ["/opt/php81/sbin/php-fpm", "-F"]

Orquestación con Docker Compose

Se define el archivo de composición para levantar el stack completo, incluyendo un contenedor de MySQL 8.0:

version: '3.8'
services:
  web_server:
    image: custom-nginx:1.22
    container_name: frontend_web
    ports:
      - "80:80"
      - "443:443"
    restart: unless-stopped
    volumes:
      - ./config/nginx.conf:/opt/nginx/conf/nginx.conf
      - ./public_html:/opt/nginx/html
    networks:
      - app_network
    depends_on:
      - php_processor

  php_processor:
    image: custom-php:8.1.18
    container_name: backend_php
    restart: unless-stopped
    volumes:
      - ./config/php-fpm.conf:/opt/php81/etc/php-fpm.d/www.conf
      - ./public_html:/opt/nginx/html
    networks:
      - app_network

  database:
    image: mysql:8.0
    container_name: db_mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: secure_root_pass
      MYSQL_DATABASE: app_db
      MYSQL_USER: app_user
      MYSQL_PASSWORD: secure_user_pass
    networks:
      - app_network
    volumes:
      - db_data:/var/lib/mysql
      - ./config/my.cnf:/etc/my.cnf
    ports:
      - "3306:3306"
    command: --default-authentication-plugin=mysql_native_password

networks:
  app_network:
    driver: bridge

volumes:
  db_data:

Es fundamental ajustar el parámetro --default-authentication-plugin en MySQL 8.0 si se requiere compatibilidad con clientes que no soportan el método de autenticación por defecto caching_sha2_password.

Etiquetas: Nginx PHP-FPM docker-compose LNMP linux

Publicado el 9-28 07:27