Cómo Publicar una Página Web con Apache, PHP y URL Amigables Usando Docker

En este artículo, te guiaré paso a paso sobre cómo configurar un entorno de desarrollo para publicar una página web que requiere Apache, PHP y el módulo mod_rewrite para soportar URLs amigables. Utilizaremos Docker para simplificar la implementación y administración de este entorno, además de usar Docker Compose para gestionar los servicios involucrados.

Archivos Necesarios:

Primero, revisaremos los archivos esenciales que usaremos para esta configuración:

  • Dockerfile
  • docker-compose.yml
  • Archivo .env
  • Configuración adicional para apache2.conf y 000-default.conf.

Paso 1: Configuración del Dockerfile

El Dockerfile es el archivo base donde definimos cómo se construirá la imagen de Docker para nuestro contenedor. Este archivo es esencial porque especifica los pasos que Docker debe seguir para crear un entorno adecuado para tu aplicación, en este caso, un servidor web con Apache, PHP y el módulo mod_rewrite.

Contenido del Dockerfile

# Usamos una imagen oficial de PHP con Apache preinstalado
FROM php:8.3-apache

# Actualizamos los paquetes e instalamos las extensiones necesarias de PHP
RUN apt-get update && docker-php-ext-install mysqli pdo pdo_mysql

# Habilitamos los módulos de Apache que necesitamos, en este caso headers y rewrite
RUN a2enmod headers rewrite

# Configuramos el nombre del servidor en Apache para evitar advertencias al iniciar el servicio
RUN echo "ServerName yagolivas.com" >> /etc/apache2/apache2.conf

# Exponemos el puerto 80 para permitir el acceso HTTP al servidor
EXPOSE 80

Explicación Detallada de Cada Instrucción

  1. FROM php:8.3-apache:
    • Esta línea especifica la imagen base de Docker que vamos a utilizar. Estamos eligiendo una imagen oficial de PHP con Apache ya preinstalado. La versión 8.3 de PHP se menciona explícitamente para asegurarnos de que el contenedor use esta versión en particular.
  2. RUN apt-get update && docker-php-ext-install mysqli pdo pdo_mysql:
    • apt-get update: Este comando actualiza la lista de paquetes disponibles e información sobre versiones.
    • docker-php-ext-install: Este comando instala extensiones de PHP dentro de la imagen Docker. Aquí estamos instalando tres extensiones:
      • mysqli: Extensión para interactuar con bases de datos MySQL.
      • pdo y pdo_mysql: Estas extensiones permiten el uso de PDO (PHP Data Objects) para acceder a bases de datos MySQL de manera más segura y flexible.
  3. RUN a2enmod headers rewrite:
    • a2enmod es una herramienta de Apache que habilita módulos. En este caso, estamos habilitando:
      • headers: Este módulo permite modificar o añadir cabeceras HTTP en las respuestas.
      • rewrite: Este módulo es crucial para manejar las URLs amigables, ya que permite reescribir las URLs de manera flexible.
  4. RUN echo “ServerName yagolivas.com” >> /etc/apache2/apache2.conf:
    • Apache puede mostrar una advertencia si no se especifica un ServerName. Esta línea asegura que el nombre del servidor esté configurado como “yagolivas.com”, lo que previene este tipo de advertencias durante el inicio del servidor.
  5. EXPOSE 80:
    • Con este comando, indicamos que el contenedor expondrá el puerto 80, que es el puerto predeterminado para tráfico HTTP. Esto permite que las solicitudes externas puedan acceder a tu servidor web dentro del contenedor.

¿Por qué es Importante Cada Paso?

  • Imagen Base (FROM): Elegir la imagen correcta es crucial porque define el entorno sobre el cual construirás tu aplicación. Al usar una imagen de PHP con Apache, ahorramos tiempo en configuraciones manuales.
  • Instalación de Extensiones (RUN apt-get… & docker-php-ext-install): Las extensiones de PHP que instalamos son necesarias para que la aplicación web pueda interactuar con la base de datos MySQL.
  • Habilitación de Módulos de Apache (RUN a2enmod…): El módulo mod_rewrite es especialmente importante para manejar URLs amigables, lo que es crucial para muchas aplicaciones web modernas.
  • Configuración de ServerName: Configurar un nombre de servidor ayuda a evitar errores y advertencias, lo que hace que el servidor Apache se inicie sin problemas.
  • Exposición del Puerto (EXPOSE): Exponer el puerto 80 asegura que el contenedor esté listo para recibir tráfico web desde fuera del contenedor, haciendo que tu sitio web esté accesible.

Conclusión

El Dockerfile es la base para crear un entorno de desarrollo o producción consistente. Al seguir los pasos descritos, te aseguras de que tu contenedor Docker tenga todo lo necesario para ejecutar tu aplicación web con Apache y PHP, y que esté preparado para manejar URLs amigables, lo que es crucial para SEO y la experiencia del usuario. Este es el primer paso esencial para desplegar tu aplicación web de manera efectiva usando Docker.

Paso 2: Configuración de Docker Compose

El archivo docker-compose.yml es fundamental para definir y gestionar múltiples servicios Docker como un solo conjunto. Docker Compose permite declarar todos los servicios necesarios para tu aplicación en un único archivo, facilitando la orquestación, la configuración y la puesta en marcha de todo el entorno con un solo comando.

Contenido del docker-compose.yml

services:
  www:
    build: ./
    container_name: ${CONTAINER}-www
    restart: unless-stopped
    volumes:
      - ${WWWPATH}:/var/www/html
      - ./apache/apache2.conf:/etc/apache2/apache2.conf
      - ./apache/000-default.conf:/etc/apache2/sites-available/000-default.conf
      - ./log/apache2/:/var/log/apache2
    networks:
      - npm-nw
      - webdb

networks:
  webdb:
    external: true
  npm-nw:
    external: true

Explicación Detallada de Cada Elemento

  1. version: ‘3.8’:
    • Esta línea especifica la versión de la sintaxis de Docker Compose que estás utilizando. La versión 3.8 es ampliamente compatible y permite el uso de características modernas de Docker Compose.
  2. www:
    • Este es el nombre del servicio que definimos para el contenedor que ejecutará Apache y PHP.
  3. build: ./:
    • La directiva build indica a Docker Compose que construya la imagen Docker utilizando el Dockerfile en el directorio actual (./). Esto significa que Docker Compose tomará el Dockerfile que creaste y lo utilizará para construir el contenedor.
  4. container_name: ${CONTAINER}-www:
    • Aquí estamos definiendo el nombre del contenedor, utilizando una variable de entorno ${CONTAINER} que se define en el archivo .env. Esto permite una mayor flexibilidad y reutilización del archivo docker-compose.yml en diferentes entornos.
  5. restart: unless-stopped:
    • Esta política de reinicio indica que el contenedor debería reiniciarse automáticamente si falla, excepto si se ha detenido explícitamente. Esto es útil para asegurar que el contenedor permanezca en funcionamiento en caso de fallos temporales.
  6. volumes:
    • Los volúmenes permiten mapear directorios desde tu sistema anfitrión (host) al sistema de archivos dentro del contenedor. En este caso:
      • ${WPPATH}:/var/www/html: Mapea el directorio de tu proyecto web en el sistema anfitrión a /var/www/html dentro del contenedor. Esto es donde Apache buscará los archivos de tu sitio web.
      • ./apache/apache2.conf:/etc/apache2/apache2.conf: Mapea un archivo de configuración de Apache desde tu sistema anfitrión al contenedor, asegurando que Apache utilice tu configuración personalizada.
      • ./apache/000-default.conf:/etc/apache2/sites-available/000-default.conf: Mapea el archivo de configuración del Virtual Host para tu sitio web.
      • ./log/apache2/:/var/log/apache2: Mapea el directorio de logs de Apache para que puedas acceder a los registros de acceso y error desde tu sistema anfitrión.
  7. networks:
    • Esta sección define las redes en las que operará el servicio www.
    • npm-nw y webdb son redes externas que permiten la comunicación entre el contenedor www y otros contenedores dentro del ecosistema Docker.
    • webdb: Esta red es utilizada para la comunicación con el contenedor de la base de datos. Permite que tu contenedor www, donde corre Apache y PHP, pueda conectarse a la base de datos MariaDB que se encuentra en otro contenedor, garantizando así que las aplicaciones web puedan realizar consultas y operaciones de base de datos sin problemas.
    • npm-nw: Esta red está configurada para la comunicación con el Nginx Proxy Manager, que es un contenedor que gestiona los proxies y facilita la configuración SSL. El Proxy Manager actúa como intermediario para gestionar las solicitudes entrantes y dirigirlas al contenedor adecuado. Al incluir el servicio www en esta red, aseguramos que las solicitudes HTTP/HTTPS entrantes sean correctamente manejadas y dirigidas a Apache dentro del contenedor.
  8. networks (global):
    • Aquí es donde declaras las redes externas que usarán los servicios. external: true indica que estas redes ya existen y no deben ser creadas nuevamente por Docker Compose. Esto es particularmente útil cuando tienes múltiples aplicaciones que necesitan interactuar en las mismas redes, como en el caso de una red compartida para bases de datos o proxies inversos.

Importancia de Cada Componente

  • Volúmenes: Te permiten mantener los datos persistentes, incluso si el contenedor es destruido o reconstruido. También facilitan la actualización del código o configuración sin necesidad de reconstruir todo el contenedor.
  • Redes:
    • webdb: Es esencial para permitir que el contenedor www se comunique con la base de datos MariaDB, asegurando que la aplicación web pueda realizar consultas y almacenar datos.
    • npm-nw: Facilita la integración del contenedor www con Nginx Proxy Manager, lo que es crucial para manejar las solicitudes HTTP/HTTPS, redirigir tráfico y gestionar certificados SSL de manera eficiente.
  • Política de Reinicio: Asegura la alta disponibilidad de tu aplicación al reiniciar automáticamente el contenedor en caso de fallos.
  • Configuración Modular: Al utilizar variables de entorno y archivos de configuración mapeados, Docker Compose permite que tu entorno sea altamente flexible y fácil de modificar según las necesidades de diferentes entornos (desarrollo, pruebas, producción).

Paso 3: Archivo .env para Variables de Entorno

El archivo .env es clave para almacenar las variables de entorno que se utilizarán en el docker-compose.yml. Este archivo te permitirá cambiar rápidamente configuraciones como el nombre del contenedor o la ruta de los archivos de tu proyecto.

CONTAINER=yagolivas
WWWPATH=/var/www/yagolivas.com
NWI=yagolivas.com
DBNAME=xxxxxxx
DBUSER=aaaaaaaaa
DBPASS=bbbbbbbbb
DBPASSROOT=cccccccccc

Nota: Asegúrate de proteger este archivo adecuadamente, ya que contiene información sensible como las contraseñas de la base de datos.

Paso 4: Configuración del Virtual Host en Apache

Para finalizar la configuración de Apache, necesitarás definir un Virtual Host que apunte a tu sitio web. Esto se realiza en el archivo 000-default.conf, que debería ubicarse en la carpeta de configuración de Apache dentro del contenedor.

Aquí tienes un ejemplo del archivo 000-default.conf:

<VirtualHost *:80>
    ServerAdmin guiskas@gmail.com
    DocumentRoot /var/www/html
    ServerName yagolivas.com
    ServerAlias www.yagolivas.com

    <Directory /var/www/html>
        #AllowOverride All    ### Descomentar si es necesario
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # Para redirigir todo el tráfico HTTP a HTTPS, descomenta las siguientes líneas:
    #RewriteEngine on
    #RewriteCond %{SERVER_NAME} =www.yagolivas.com [OR]
    #RewriteCond %{SERVER_NAME} =yagolivas.com
    #RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Explicación del Archivo:

  • ServerAdmin: Define la dirección de correo del administrador del servidor.
  • DocumentRoot: Especifica la ruta donde se encuentra la raíz de los archivos de tu sitio web.
  • ServerName y ServerAlias: Configuran el nombre de dominio principal y cualquier alias que el servidor debería reconocer.
  • Directory: En este bloque puedes definir reglas específicas para el directorio raíz del sitio web. Por ejemplo, puedes descomentar la línea AllowOverride All para permitir que los archivos .htaccess sobreescriban configuraciones globales.
  • ErrorLog y CustomLog: Especifican las ubicaciones para los registros de errores y accesos.
  • RewriteEngine: Si necesitas redirigir todo el tráfico HTTP a HTTPS, puedes descomentar las líneas correspondientes que utilizan RewriteEngine, RewriteCond y RewriteRule.

Este archivo es crucial para definir cómo tu sitio será servido a los usuarios, y asegura que Apache maneje correctamente las solicitudes para tu dominio. Recuerda adaptar las rutas y configuraciones según tu entorno específico.

Paso 5: Configuración de la Base de Datos con Docker Compose

Si estás utilizando una base de datos que está en un contenedor separado, también puedes definirlo en su propio archivo docker-compose.yml. En este caso, usaremos MariaDB y phpMyAdmin para gestionar la base de datos.

services:
  db:
    image: mariadb
    container_name: webdb
    restart: always
    volumes:
      - ./db_data:/var/lib/mysql
    environment:
      MARIADB_ROOT_HOST: 172.%
      MARIADB_AUTO_UPGRADE: "1"
      MARIADB_INITDB_SKIP_TZINFO: "1"
    networks:
      - webdb

  phpmyadmin:
    image: phpmyadmin
    container_name: phpmyadmin
    restart: always
    ports:
      - 4444:80
    networks:
      - webdb
      - npm-nw

networks:
  webdb:
    external: true
  npm-nw:
    external: true

Paso 6: Uso de Nginx Proxy Manager (Opcional)

El Nginx Proxy Manager es una herramienta poderosa y fácil de usar para gestionar proxies inversos y certificados SSL en un entorno Docker. Es especialmente útil cuando tienes múltiples aplicaciones o servicios corriendo en diferentes contenedores y necesitas administrar el tráfico HTTP/HTTPS entrante de manera eficiente.

Integración con Docker Compose

En la configuración de Docker Compose que hemos visto, incluimos el contenedor www en la red npm-nw, que es la red compartida con el Nginx Proxy Manager. Esto permite que Nginx Proxy Manager funcione como intermediario para gestionar el tráfico entrante y redirigirlo correctamente al contenedor de Apache/PHP.

¿Cómo Funciona?
  1. Red npm-nw: Esta red conecta tu contenedor www con el Nginx Proxy Manager. Cualquier solicitud que llegue al servidor, ya sea HTTP o HTTPS, es primero manejada por Nginx Proxy Manager, quien decide a cuál contenedor redirigir la solicitud basándose en las reglas que configures en su interfaz.
  2. Configuración del Proxy Inverso:
    • En la interfaz de Nginx Proxy Manager, puedes crear un “Proxy Host” que apunte a tu contenedor www. Configuras el dominio o subdominio (por ejemplo, yagolivas.com), el puerto en el cual el contenedor está escuchando (puerto 80 para HTTP), y cualquier ajuste adicional, como redirecciones HTTPS o cabeceras personalizadas.
    • Nginx Proxy Manager se encargará de manejar el tráfico SSL si decides activar esta opción. Puedes cargar tus propios certificados SSL o utilizar la integración con Let’s Encrypt para obtener certificados gratuitos y gestionarlos automáticamente.
  3. Seguridad y Flexibilidad:
    • Al utilizar Nginx Proxy Manager, no solo simplificas la gestión del tráfico HTTP/HTTPS, sino que también añades una capa adicional de seguridad. El proxy inverso puede filtrar, redirigir, y hasta bloquear solicitudes maliciosas antes de que lleguen a tu aplicación web.
    • Además, puedes utilizar Nginx Proxy Manager para gestionar múltiples sitios y aplicaciones con diferentes dominios, todo desde una única interfaz, lo que lo hace extremadamente flexible.

Ejemplo de Configuración

Imagina que tienes el dominio yagolivas.com apuntando a tu servidor. Con Nginx Proxy Manager, puedes configurar un proxy host como sigue:

  1. Host Details:
    • Domain Names: yagolivas.com, www.yagolivas.com
    • Scheme: http (o https si has configurado SSL)
    • Forward Hostname/IP: yagolivas-www (o la IP interna del contenedor si lo prefieres)
    • Forward Port: 80
  1. SSL Settings:
    • Selecciona “Request a new SSL Certificate” y sigue las indicaciones para obtener un certificado SSL de Let’s Encrypt.
    • Activa la opción “Force SSL” para redirigir todo el tráfico HTTP a HTTPS automáticamente.
  2. Advanced Settings (opcional):
    • Puedes añadir reglas adicionales para gestionar cabeceras, tiempos de espera, o incluso implementar protección básica mediante autenticación.

Ventajas de Usar Nginx Proxy Manager

  • Gestión Simplificada: Todo el manejo de proxies, redirecciones y SSL se realiza a través de una interfaz gráfica sencilla.
  • Flexibilidad: Puedes gestionar múltiples aplicaciones y dominios desde un solo lugar.
  • Seguridad: Implementa SSL fácilmente y asegura que todo el tráfico sensible esté cifrado.

Conclusión

El uso de Nginx Proxy Manager en combinación con Docker Compose facilita enormemente la gestión de proxies inversos y certificados SSL en tu entorno de desarrollo o producción. Al integrar tu contenedor www con la red npm-nw, te aseguras de que el tráfico entrante sea correctamente gestionado y redirigido, proporcionando una experiencia de usuario segura y profesional para tu sitio web. Esto es especialmente útil si manejas múltiples aplicaciones o servicios, ya que te permite centralizar y simplificar la administración de todo el tráfico web.

Paso 7: Implementación y Pruebas

Con todo configurado, puedes ejecutar tus contenedores con el siguiente comando en la terminal:

docker-compose up -d

Este comando creará y levantará los contenedores definidos en el archivo docker-compose.yml. Una vez que los contenedores estén en funcionamiento, tu aplicación web estará disponible y podrás acceder a ella mediante el navegador.

Conclusión

Esta configuración te permitirá desplegar rápidamente una página web con soporte para PHP y URLs amigables utilizando Docker. La separación de servicios mediante Docker Compose, junto con la configuración de un proxy inverso, garantiza que tu entorno de desarrollo o producción sea fácil de gestionar y altamente flexible.

Si tienes más servicios que agregar o necesitas ajustes adicionales, Docker Compose te permitirá hacerlo sin mucha complicación. ¡Felices despliegues!

Deja un comentario