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.