Cómo desplegar WordPress con Docker

En el desarrollo web moderno, la forma en que desplegamos nuestras aplicaciones es tan crítica como el código que escribimos. Si has llegado hasta aquí buscando wordpress con docker, probablemente ya te has dado cuenta de que los hostings compartidos tradicionales tienen un techo de cristal. En mi experiencia como desarrollador Senior, la transición a una arquitectura de contenedores no es solo una mejora técnica; es una estrategia de negocio para garantizar escalabilidad, seguridad y velocidad.

Hoy vamos a dejar de lado las instalaciones básicas. Vamos a montar un stack de alto rendimiento utilizando Docker Compose, orquestando imágenes específicas como wordpress:fpm, mariadb:latest, redis:7-alpine y opensearchproject/opensearch:2. Prepárate para profesionalizar tu infraestructura.

Tabla de Contenidos

¿Por qué elegir WordPress con Docker sobre un hosting tradicional?

La contenerización ha revolucionado la forma en que administramos servidores. A diferencia de instalar un servidor LAMP (Linux, Apache, MySQL, PHP) directamente en el sistema operativo, Docker nos permite aislar cada servicio.

En mi día a día trabajando con clientes que requieren alta disponibilidad, el uso de wordpress con docker ofrece ventajas innegables:

  • Paridad entre entornos: Lo que funciona en mi local, funciona en producción. Sin sorpresas.
  • Aislamiento: Si la base de datos falla o necesita actualización, no afecta la configuración del servidor web.
  • Escalabilidad: Es trivial añadir más nodos o servicios (como Redis u OpenSearch) sin reconfigurar todo el sistema operativo.

Requisitos de infraestructura y arquitectura

Antes de escribir una sola línea de código, hablemos del hardware. El despliegue profesional de esta arquitectura requiere un servidor propio (VPS, Cloud o Dedicado). Intentar esto en un hosting compartido es inviable debido a las restricciones de permisos y recursos.

La arquitectura recomendada implica la ejecución de contenedores aislados que operan en el mismo servidor pero con configuraciones independientes. Para profundizar en los conceptos básicos de esta separación, recomiendo leer sobre cómo implementar WordPress con un contenedor Docker, donde se detalla la importancia de distinguir entre el servidor web y la base de datos.

Preparando el terreno: Docker Compose

Aunque es posible levantar contenedores uno a uno con el comando docker run, la mejor forma de hacerlo—y la única que recomiendo para entornos de producción—es mediante Docker Compose. Esta herramienta nos permite definir toda nuestra infraestructura en un solo archivo YAML.

Si estás configurando un servidor nuevo, es necesario instalar Docker Compose manualmente. El proceso estándar implica descargar el binario a /usr/local/bin/docker-compose y asignar permisos de ejecución. Según la documentación técnica de Arsys sobre la instalación y configuración de Docker, es vital crear un directorio de trabajo específico para mantener el orden, por ejemplo mkdir wp-docker.

La Arquitectura del Stack: Selección de Imágenes

Para este tutorial, no usaremos la configuración por defecto. Vamos a optimizar el rendimiento usando la imagen FPM de WordPress. Aquí explico por qué he seleccionado estas versiones específicas:

  • wordpress:fpm: A diferencia de la imagen estándar que incluye Apache, la versión FPM (FastCGI Process Manager) es mucho más eficiente gestionando altas cargas de tráfico PHP, aunque requiere un servidor web frontal (como Nginx) para servir los archivos estáticos.
  • mariadb:latest: MariaDB suele ofrecer mejor rendimiento que MySQL en consultas complejas de WordPress.
  • redis:7-alpine: Usaremos Redis para el caché de objetos (Object Cache), lo que reduce drásticamente las consultas a la base de datos.
  • opensearchproject/opensearch:2: Para sitios grandes o WooCommerce, la búsqueda nativa de WordPress es lenta. OpenSearch (un fork de Elasticsearch) soluciona esto.

Configuración Paso a Paso

1. Variables de Entorno y Seguridad (.env)

Seguridad ante todo: Nunca escribas contraseñas directamente en tu archivo docker-compose.yml. Usaremos un archivo .env para inyectar las credenciales.

La configuración de la base de datos se realiza inyectando variables de entorno específicas. Las críticas incluyen MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, y las credenciales del usuario. Esto es fundamental para mantener la seguridad.

Crea un archivo llamado .env en tu directorio de proyecto:

# Base de Datos
DB_NAME=wordpress_db
DB_USER=wp_user
DB_PASSWORD=una_contraseña_muy_segura_y_larga_123!
DB_ROOT_PASSWORD=root_contraseña_super_secreta

# WordPress
WP_URL=midominio.com
WP_TITLE="Mi Sitio Dockerizado"
WP_ADMIN_USER=admin
WP_ADMIN_PASSWORD=admin_password_segura
WP_ADMIN_EMAIL=admin@midominio.com

# Redis & OpenSearch
REDIS_HOST=redis
OPENSEARCH_HOST=opensearch

2. El Archivo Docker Compose

A continuación, presentamos la configuración completa. Nótese que al usar wordpress:fpm, necesitamos un contenedor adicional de Nginx para manejar las peticiones HTTP.

Crea el archivo docker-compose.yml:

version: '3.8'

services:
  # Base de Datos
  db:
    image: mariadb:latest
    container_name: wp_db
    restart: always
    environment:
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - wp-network

  # WordPress FPM
  wordpress:
    depends_on:
      - db
      - redis
      - opensearch
    image: wordpress:fpm
    container_name: wp_app
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: ${DB_USER}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: ${DB_NAME}
    volumes:
      - wp_data:/var/www/html
    networks:
      - wp-network

  # Servidor Web (Nginx) - Necesario para la imagen FPM
  webserver:
    depends_on:
      - wordpress
    image: nginx:alpine
    container_name: wp_nginx
    restart: always
    ports:
      - "80:80"
    volumes:
      - wp_data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
    networks:
      - wp-network

  # Redis (Object Cache)
  redis:
    image: redis:7-alpine
    container_name: wp_redis
    restart: always
    networks:
      - wp-network

  # OpenSearch (Búsqueda avanzada)
  opensearch:
    image: opensearchproject/opensearch:2
    container_name: wp_opensearch
    environment:
      - discovery.type=single-node
      - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - opensearch_data:/usr/share/opensearch/data
    networks:
      - wp-network

volumes:
  db_data:
  wp_data:
  opensearch_data:

networks:
  wp-network:
    driver: bridge

Detalles sobre la Base de Datos y Persistencia

Como señalan en el Taller de Docker de Aula Software Libre, es crucial manejar correctamente el contenedor de MariaDB. Se recomienda iniciarlo de forma que no publique puertos externos (nota que en nuestro compose no hay sección ports bajo db), manteniendo la base de datos accesible solo internamente para el contenedor de WordPress.

Además, la persistencia es vital. En el código anterior, hemos definido volumes. Esto asegura que la información no se pierda al reiniciar los contenedores, enlazando un volumen virtual con el directorio /var/lib/mysql, tal como se recomienda para levantar un WordPress con Docker asegurando los datos.

3. Configuración de Nginx para FPM

Dado que estamos usando la versión super optimizada wordpress:fpm, necesitamos decirle a Nginx cómo procesar los archivos PHP. Crea una carpeta nginx-conf y dentro un archivo default.conf:

server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass wordpress:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Configuración avanzada: wp-config.php dinámico

Uno de los trucos más potentes cuando trabajamos con wordpress con docker es hacer que nuestro archivo wp-config.php lea directamente las variables de entorno del sistema, en lugar de tener las credenciales escritas en código PHP.

Normalmente, Docker inyecta estas variables automáticamente si usas la imagen oficial, pero para configuraciones personalizadas de Redis o OpenSearch, te recomiendo modificar tu wp-config.php para incluir esto:

// Configuración dinámica desde .env
define( 'DB_NAME',     getenv('WORDPRESS_DB_NAME') );
define( 'DB_USER',     getenv('WORDPRESS_DB_USER') );
define( 'DB_PASSWORD', getenv('WORDPRESS_DB_PASSWORD') );
define( 'DB_HOST',     getenv('WORDPRESS_DB_HOST') );

// Configuración Redis
define( 'WP_REDIS_HOST', 'redis' );
define( 'WP_REDIS_PORT', 6379 );

// Forzar SSL si estamos detrás de un proxy reverso (común en prod)
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Despliegue y validación

Una vez que tienes el archivo docker-compose.yml, el archivo .env y la configuración de Nginx, el despliegue es extremadamente sencillo.

Sitúate en la carpeta de tu proyecto y ejecuta:

docker-compose up -d

El parámetro -d (detached) es esencial para que los procesos corran en segundo plano y no se detengan si cierras la terminal.

Integrando los servicios adicionales

Una vez que WordPress esté corriendo, para aprovechar la potencia de las imágenes extra que hemos incluido:

  1. Redis: Instala el plugin «Redis Object Cache» en WordPress. Al activarlo, detectará automáticamente el host redis que definimos en el compose.
  2. OpenSearch: Recomiendo usar un plugin como «ElasticPress» o similar compatible con OpenSearch. Configura el host como http://opensearch:9200. Esto descargará a tu base de datos MariaDB de las consultas de búsqueda pesadas.

Conclusión

Implementar wordpress con docker utilizando una arquitectura separada con FPM, Nginx, Redis y OpenSearch coloca tu sitio web en una categoría superior de rendimiento y seguridad. Has pasado de un simple blog a una aplicación web robusta y escalable.

En mi experiencia, el tiempo invertido en configurar este entorno se recupera con creces gracias a la velocidad de carga (que mejora el SEO y las conversiones) y la facilidad para realizar copias de seguridad y migraciones. No tengas miedo a la terminal; es la mejor aliada para el éxito de tus proyectos web.

Marcos Arcusin

Marcos Arcusin

Desarrollador WordPress Senior, PHP, Vue.js, Plugin development. Mi objetivo es crear webs efectivas que aumenten los ingresos de mis clientes, utilizando WordPress como plataforma.

Artículos relacionados