Como mapear dominios en multisitio con sunrise.php en WordPress

Contents

Introducción

Este artículo explica con todo detalle cómo mapear dominios en una instalación WordPress Multisite usando sunrise.php. Cubriremos la teoría, los requisitos, la configuración de DNS y servidor, la activación de SUNRISE en wp-config.php, varios ejemplos prácticos (estáticos y dinámicos) y recomendaciones para HTTPS, cookies y resolución de problemas. Todos los fragmentos de código se presentan listos para copiar y adaptar.

¿Por qué usar sunrise.php?

sunrise.php es un archivo que WordPress Multisite carga muy temprano durante la inicialización cuando está habilitada la constante SUNRISE. Esto permite interceptar la petición HTTP y decidir a qué sitio dentro de la red corresponde el dominio solicitado antes de que WordPress determine el sitio actual. Es útil cuando:

  • se manejan muchos dominios externos y no quieres editar cada sitio manualmente desde el panel
  • necesitas lógica personalizada para asignar dominios a blogs (por ejemplo, desde una tabla externa)
  • quieres soportar dominios por cliente con configuración centralizada

Requisitos previos

  • Instalación de WordPress Multisite operativa.
  • Acceso al servidor (SFTP/SSH) para editar wp-config.php y crear wp-content/sunrise.php.
  • Acceso a la base de datos si vas a mantener una tabla propia de mapeos o para comprobar wp_blogs.
  • Entradas DNS de cada dominio apuntando a la IP del servidor, o configuración de wildcard si aplica.
  • Configuración de host virtual (vhost) en el servidor web que acepte los dominios mapeados (SNI para HTTPS si usas certificados distintos).

Pasos generales

  1. Preparar DNS y servidor web.
  2. Habilitar SUNRISE en wp-config.php.
  3. Crear wp-content/sunrise.php con la lógica de mapeo (estática o dinámica).
  4. Probar y ajustar cookies, HTTPS y redirecciones.
  5. Monitorear y depurar errores (logs, WP_DEBUG, server logs).

1) DNS y servidor web

Para que un dominio A o CNAME sea servido por tu instalación Multisite debes:

  • Añadir A record con la IP del servidor o CNAME apuntando al dominio principal según tu arquitectura DNS.
  • Configurar el vhost del servidor web (Apache, Nginx) para aceptar peticiones por los dominios mapeados. Lo normal es un vhost catch-all que responda a cualquier ServerName/ServerAlias y permita que WordPress resuelva internamente.
  • Configurar certificados SSL: puedes usar certificados individuales (SNI) o soluciones wildcard/Lets Encrypt con múltiples dominios — asegurarte de que el TLS esté presente para cada dominio que vaya a recibir tráfico HTTPS.

2) Habilitar sunrise en wp-config.php

Abre wp-config.php y, antes de la línea que dice / Thats all, stop editing! /, añade la constante SUNRISE. Ejemplo:

lt?php
// wp-config.php (fragmento)
define(MULTISITE, true)
define(SUBDOMAIN_INSTALL, true)
/ Habilitar sunrise para mapeo de dominios /
define(SUNRISE, on)
/ Resto del wp-config.php /

3) Crear wp-content/sunrise.php (ejemplos)

WordPress incluirá wp-content/sunrise.php muy temprano. A partir de ahí puedes implementar la lógica que determine, en función de _SERVER[HTTP_HOST] y _SERVER[REQUEST_URI], cuál es el blog objetivo. A continuación varios enfoques:

Ejemplo A — Mapeo estático simple

Útil para pocos dominios conocidos. El script busca el host entrante y lo redirige a la entrada del multisite equivalente.

lt?php
// wp-content/sunrise.php - mapeo estático básico
if ( isset(_SERVER[HTTP_HOST]) ) {
    host = strtolower( _SERVER[HTTP_HOST] )
    // mapa host => blog_id
    map = array(
        example.com      =gt 2, // blog_id 2
        customer.local   =gt 3, // blog_id 3
    )

    if ( isset(map[host]) ) {
        // Establece una variable global que luego usaremos más abajo
        GLOBALS[sunrise_mapped_blog_id] = (int) map[host]
        // Opcional: normaliza HTTP_HOST para que WP lo lea igual
        _SERVER[HTTP_HOST] = host
    }
}

Con ese fragmento, más adelante WordPress hará la resolución del blog por ID cuando proceda. En instalaciones donde necesites forzar más, puedes leer la variable global y ajustar GLOBALS[current_blog] y GLOBALS[current_site] (ver ejemplo avanzado).

Ejemplo B — Mapeo desde tabla personalizada (dinámico)

Si tienes muchos dominios o quieres administrar mapeos desde una tabla propia, crea una tabla SQL que relacione host → blog_id y utiliza wpdb para consultar.

-- Crear tabla simple para mapeo
CREATE TABLE wp_domain_map (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  domain VARCHAR(255) NOT NULL,
  blog_id BIGINT UNSIGNED NOT NULL,
  is_primary TINYINT(1) DEFAULT 1,
  UNIQUE KEY (domain)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
lt?php
// wp-content/sunrise.php - mapeo desde tabla personalizada
global wpdb

if ( isset(_SERVER[HTTP_HOST]) ) {
    host = strtolower( _SERVER[HTTP_HOST] )
    table = wpdb->prefix . domain_map

    // Intentamos obtener el blog_id desde nuestra tabla
    blog_id = wpdb->get_var( wpdb->prepare(
        SELECT blog_id FROM {table} WHERE domain = %s LIMIT 1,
        host
    ) )

    if ( blog_id ) {
        // Guardamos para uso posterior en ms-settings/wp-load
        GLOBALS[sunrise_mapped_blog_id] = (int) blog_id

        // Opcional: forzar HTTP_HOST a la forma registrada (útil si trabajas con mayúsculas/minúsculas)
        _SERVER[HTTP_HOST] = host
    }
}

Ejemplo C — Forzar las estructuras internas de WP (avanzado)

En algunos casos necesitas que WordPress piense que el blog actual es uno concreto desde el inicio. Este ejemplo establece GLOBALS[current_blog] y GLOBALS[current_site] usando datos de wp_blogs. Es avanzado pero efectivo. Ten cuidado y prueba en entorno de desarrollo antes de usar en producción.

lt?php
// wp-content/sunrise.php - establecer current_blog/current_site (avanzado)
global wpdb

if ( isset(_SERVER[HTTP_HOST]) ) {
    host = strtolower( _SERVER[HTTP_HOST] )

    // Buscar BLOG_ID por dominio (ejemplo: en wp_blogs o en tabla personalizada)
    blog_id = wpdb->get_var( wpdb->prepare(
        SELECT blog_id FROM {wpdb->blogs} WHERE domain = %s LIMIT 1,
        host
    ) )

    if ( blog_id ) {
        // Obtener los datos del blog
        blog = wpdb->get_row( wpdb->prepare(
            SELECT blog_id, domain, path, site_id FROM {wpdb->blogs} WHERE blog_id = %d LIMIT 1,
            blog_id
        ) )

        if ( blog ) {
            // Construir objetos esperados por el resto de WP
            GLOBALS[current_blog] = (object) array(
                blog_id => (int) blog->blog_id,
                domain  => blog->domain,
                path    => blog->path,
            )

            GLOBALS[current_site] = (object) array(
                id     => (int) blog->site_id,
                domain => blog->domain,
                path   => blog->path,
            )

            // Aseguramos que WP lea el host correcto
            _SERVER[HTTP_HOST] = blog->domain

            // Evitar problemas de cookies: usar dominio vacío para que el navegador gestione la cookie por host
            if ( ! defined(COOKIE_DOMAIN) ) {
                define(COOKIE_DOMAIN, )
            }
        }
    }
}

4) HTTPS y encabezados/proxies

Si usas balanceadores o proxies (o Cloudflare), asegúrate de detectar correctamente si la petición es HTTPS para generar URLs y redirecciones correctas:

lt?php
// Detectar HTTPS detrás de proxy en sunrise.php
if ( isset(_SERVER[HTTP_X_FORWARDED_PROTO])  _SERVER[HTTP_X_FORWARDED_PROTO] === https ) {
    _SERVER[HTTPS] = on
}
if ( isset(_SERVER[HTTP_X_FORWARDED_SSL])  _SERVER[HTTP_X_FORWARDED_SSL] === on ) {
    _SERVER[HTTPS] = on
}

Adicionalmente, configura certificados TLS para cada dominio o una solución que cubra todos los dominios mapeados (SNI o certificados comodín/multi-domains). No olvides renovar certificados automáticamentes (Lets Encrypt cron/certbot, por ejemplo).

5) Cookies, administración y login

Al mapear dominios debes prestar atención a las cookies (iniciar sesión en un dominio debe ser válido para ese host en particular). Recomendaciones:

  • En sunrise, establece COOKIE_DOMAIN a cadena vacía para que WordPress use el dominio actual como cookie host:
lt?php
if ( ! defined(COOKIE_DOMAIN) ) {
    define(COOKIE_DOMAIN, )
}
  • Comprueba que la ruta y dominio en la tabla wp_blogs coincidan con el dominio mapeado para evitar redirecciones a la URL incorrecta.
  • Para acceder al wp-admin de un sitio mapeado, usa el dominio mapeado (https://mapped-domain.com/wp-admin) para que las cookies pertenezcan al host correcto.

6) Redirecciones canónicas y dominio principal

WordPress puede redirigir al dominio que tenga guardado en wp_blogs para evitar contenido duplicado. Si quieres que cada dominio muestre el contenido del blog sin forzar redirecciones hacia el dominio almacenado, asegúrate de que la entrada en wp_blogs (domain path) coincida con el dominio mapeado, o maneja la cabecera Host correctamente en sunrise antes de que WordPress haga la comprobación.

Checklist de implementación

  1. Verificar que la constante SUNRISE está definida en wp-config.php.
  2. Crear y subir wp-content/sunrise.php con la lógica de mapeo deseada.
  3. Asegurar que DNS de dominios apunten al servidor.
  4. Configurar servidor web para aceptar los dominios (vhost/SNI).
  5. Configurar certificados SSL (SNI, Lets Encrypt, wildcard) para cada dominio.
  6. Probar acceso público a la URL y comprobar que WordPress muestra el sitio correcto.
  7. Probar login en dominio mapeado y verificar cookies y permisos.
  8. Monitorizar logs y ajustar reglas de rewrite/redirección si hace falta.

Problemas comunes y soluciones

404 al acceder por dominio mapeado

Revisar que:

  • DNS apunta correctamente al servidor.
  • vhost del servidor web acepta el dominio (host virtual). Muchas veces se necesita un ServerAlias o catch-all.
  • sunrise.php está presente y no provoca errores PHP (revisa error_log y WP_DEBUG).
  • La tabla wp_blogs contiene la entrada con domain path correctos para el blog.

Bucle de redirección

Frecuente cuando WordPress redirige al dominio guardado en wp_blogs y teie otra lógica que intenta reescribir el host. Solución: asegurarte en sunrise que el host se normaliza antes de que WP haga comprobaciones de canonical host, o mantener la entrada en wp_blogs sincronizada con el dominio mapeado.

Problemas de login y cookies

Verifica COOKIE_DOMAIN y las rutas de cookies. Si las cookies no se establecen, comprueba que el navegador no rechaza cookies por protocolo (HTTP vs HTTPS) y que las cabeceras Secure/HttpOnly están bien asignadas.

Buenas prácticas y seguridad

  • Probar siempre en un entorno staging antes de producción.
  • Mantener backups de la base de datos antes de crear tablas de mapeo o editar wp_blogs.
  • Limitar el acceso a wp-content/sunrise.php (permisos correctos) y validar entradas para evitar inyecciones al consultar la base de datos.
  • Si ofreces mapeo a clientes, registra logs de cambios y controla la lista de dominios permitidos para evitar abuso.
  • Evitar lógica demasiado pesada en sunrise: como se ejecuta en cada petición temprana, operaciones costosas pueden penalizar el rendimiento. Caching simple (memcached/redis) para la resolución host→blog_id es recomendable.

Ejemplo completo práctico (resumen)

Pasos mínimos para un caso típico con tabla de mapeo y caching básico en transients:

  1. Habilitar SUNRISE en wp-config.php.
  2. Crear tabla wp_domain_map con columnas (domain, blog_id).
  3. Crear wp-content/sunrise.php que:
    1. Compruebe _SERVER[HTTP_HOST].
    2. Busque blog_id en transients/cache si no, consulte la tabla y guarde en cache.
    3. Si encuentra blog_id, establezca GLOBALS[current_blog] y GLOBALS[current_site] (o al menos guarde la variable GLOBALS[sunrise_mapped_blog_id]).
    4. Asegure COOKIE_DOMAIN vacío y gestione HTTPS desde X-Forwarded- si procede.
  4. Probar y ajustar vhost/SSL.

Conclusión

sunrise.php ofrece un punto de entrada muy potente para mapear dominios en WordPress Multisite con flexibilidad. Puedes implementar desde soluciones estáticas hasta integraciones dinámicas con una base de datos propia, siempre teniendo en cuenta DNS, configuración del servidor, SSL y el manejo de cookies. Prueba cuidadosamente, usa caching para rendimiento y protege la lógica para evitar problemas de seguridad y rendimiento.

Recursos útiles



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *