WordPress multisite sin WordPress multisite

Como sabrás, WordPress permite alojar varios sitios diferentes con una misma instancia del CMS. Pero este sistema tiene algunas limitaciones:

  • Los sitios deben estar en subdominios o subdirectorios, por ejemplo blog1.example.org o example.org/blog1. No puedes usar nombres de dominio únicos (blog1.com, blog2.com). El plug-in MU Domain Mapping resuelve esta limitación, pero hace magia negra, y no mola.
  • Todos los sitios comparten los themes, plug-ins, usuarios y base de datos (problema de escalabilidad: no podrías usar varios servidores de MySQL). Eso no mola nada. En mi caso, porque tengo diferentes sitios con diferentes administradores y cada uno tiene sus themes y plug-ins.

Así que, viendo cómo funciona el proceso de carga de WordPress, me he dado cuenta de que se puede hacer muy fácilmente un hack que nos permita tener bases de datos, themes y plug-ins separados para cada sitio, y que se puedan mapear a dominios diferentes… más o menos como hace Drupal con el multi-site. Un multi-site de verdad.

Dicho así parece complicado, pero solo hay que pararse un segundo a pensar. Imaginemos que tenemos dos instancias completamente independientes, dos WordPress normales y corrientes, cada uno con su base de datos, etc.

¿Qué tienen de diferente esas dos instancias?

La base de datos, el directorio wp-content y el fichero wp-config.php. Todo lo demás es exactamente igual. Duplicado.

Por tanto, si “engañamos” de alguna forma al cargador de WordPress para cargue un wp-content y wp-config.php u otro en función del nombre de dominio, este se conectará a una u otra base de datos, ya que la información de conexión a MySQL está especificada en wp-config.php. Por tanto, habremos logrado WordPress multi-site.

¿Y cómo hacemos ese truco para “engañar” a WordPress y hacer que cargue uno u otro directorio wp-content y fichero de configuración wp-config.php? En primer lugar, organizaremos nuestros sitios. Por ejemplo, en la raíz de la instancia crearemos un directorio sites, dentro del cual pondremos los wp-config.php y wp-content de cada sitio, en sub-directorios nombrados con el nombre de dominio:

Estructura de ficheros para WordPress multisiteCarpetas para cada sitioCarpeta de un sitio en WordPress multisite

Ahora viene lo bueno. Si echamos un vistazo a wp-load.php vemos que aquí se carga wp-config.php y se declara la constante WP_CONTENT_DIR, que indica la ubicación del directorio wp-content.

Modificaciones en el loader (wp-load.php) para WordPress multisite

Modificamos las declaraciones de WP_CONTENT_DIR y WP_CONFIG poniendo las rutas que nos interesen en función del nombre de dominio solicitado. El código final de wp-load.php quedaría así (código completo de wp-load.php en GitHub):

wp-load.php interceptado (2)

wp-load.php interceptado (1)

Para tener todo listo solo faltan dos detalles: la configuración de Apache y la creación de la base de datos.

Crear la base de datos para el WordPress multisite

Para crear la base de datos de cada site, simplemente tendremos que clonar la BD de un WordPress recién instalado para los demás sitios. No sería difícil automatizarlo con un script.

Configurar Apache

La configuración necesaria para un WordPress multi-sitio con esta receta es muy sencilla: crear tantos vhosts como queramos, haciendo que todos ellos tengan el mismo DocumentRoot. Por ejemplo:


        ServerName wp1.com
        ServerAlias  wp2.com wp3.com
        DocumentRoot /var/www/wp-multisite

Otro detalle importante: para que los administradores de los diferentes sitios puedan acceder a sus directorios wp-content particulares (y solo a los suyos), puedes crear usuarios del sistema (Linux, por supuesto) cuyo directorio $HOME es el subdirectorio de sites que le corresponde. Por ejemplo, para el usuario administrador de blog1.com, su directorio $HOME sería /var/www/wp-multisite/sites/blog1.com, suponiendo que tengamos la instancia de WordPress en /var/www/wp-multisite.

Conclusión

Al final, con este sistema lo que tenemos es prácticamente igual a tener instancias independientes de WordPress, pero con algunas ventajas interesantes:

  • Actualizaciones del núcleo centralizadas, ya que tenemos una sola instancia. Ya no tendrás que ir actualizando sitio por sitio. Eso sí, los plug-ins y themes se deben actualizar independientemente.
  • Ahorro de memoria: ahorras disco duro, y sobre todo ahorras RAM si usas APC (si no lo estás usando… ¡deberías hacerlo!). Una instancia de WordPress ocupa más o menos 20MB en APC; imagínate si tenemos 100 instancias de WordPress en el servidor… ¡compartiendo el código podemos ahorrar Gigas!

Desventajas

  • Es un sistema experimental que aún no he probado en producción, así que puede fallar por cualquier lado :-P
  • No existe una forma automatizada y amigable de crear nuevos sitios. Debes crearlos a mano a partir de plantillas de wp-config.php, wp-content y base de datos.
  • Si se actualiza el núcleo WordPress con el sistema automático, las actualizaciones que afecten a la base de datos solo afectarán a la del sitio desde el cual se haya actualizado el núcleo.
  • Seguridad: a no ser que se establezcan mecanismos adicionales, un administrador de un sitio puede romper con facilidad las otras instancias.
Por

14 comentarios

  1. Buen artículo y buena idea :)

    Para varios WordPress gestionados por la misma persona es buena idea, sólo un admin, todo centralizado para facilitar tareas de mantenimiento, etc.

    Habría que pulirlo aún para otros entornos, pero es un buen comienzo.

    • Gracias por tu comentario Fran. Ya sabes que el botón fork de GitHub hace magia :-D

  2. muy bien articulo me funciono muy bien aunque tuve que cambiar :

    require_once( I_WP_CONFIG );
    define( ‘WP_CONTENT_DIR’, I_WP_CONTENT );

    por

    define( ‘WP_CONTENT_DIR’, I_WP_CONTENT );
    require_once( I_WP_CONFIG );

    y cree un htaccess de esta manera (va en el root)
    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /

    #WP-Content fix
    RewriteCond %{REQUEST_URI} ^/wp-content/(.*|)$
    RewriteRule ^(.*)$ sites/%{HTTP_HOST}/$1 [L,QSA]

    #Wordpress General handling
    RewriteRule ^index\.php$ – [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    # END WordPress

  3. Hola Israel. Genial tu aporte. Tengo una pregunta. ¿Al crear un multisite, sea de la forma tradicional o la que tú explicas, los artículos relacionados se pueden llamar desde el mismo panel de admnistración para cualquier site del multisite?. Me explico:

    Suponemos el site: misitio.com y un subdominio 2.misitio.com

    Suponemos las entradas de misitio.com y un plug-in o shortcode que carga en un widget o en página los artículos que deseamos de sitio misitio.com, pero ¿que pasa si deseo llamarlos en el subdominio 2.misitio.com ? O sea, ¿comparten los mismos datos XML?

    Gracias

  4. Hola Jordi, en el “hack multi-site” del que hablo en el post cada sitio tiene una BD totalmente independiente, así que los sitios son totalmente “agnósticos” entre sí, así que la respuesta es no… aunque no sé de qué plugin, shortcode o datos XML hablas exactamente, quizá haya plugins que sí lo soporten…

  5. Excelente aporte, como dicen antes para varios sites del mismo administrador esta muy bien

  6. Pingback: WordPress Multisitio en 5 pasos | justo a tiempo

  7. Hola la verdad es que quiero hacer un sitio con multiples dominios para posicionarme en países, quiero hacer lo siguiente :

    pe.misitioweb.com
    co.misitioweb.com
    ar.misitioweb.com

    Y asi, pero quiero que mi sitio sea duplicado igualmente en todos, cuan posible es ?

    • Con este método puedes hacer eso, pero tener contenido duplicado no mejora el SEO sino al revés, lo penaliza. Si quieres posicionar para distintos países mejor que crees contenido único para cada uno.

  8. mm intente hacer lo que dices, para volver multisite mi wordpress
    peeeerooo
    solo me repite el sitio del WP principal :(
    serias tan amable de decirme si pudiste probar este metodo que pusite??
    porfavor

    • Obviamente, si lo publiqué es porque sé que funciona. Revisa tu configuración de Apache y las modificaciones al wp-load.php.

      • bueno
        quise hacer esto por que quiero poner dos WP o mas
        pero que tengan el mismo contenido, diferentes temas
        pense que al igual que compartir los usuarios de un WP a otro, seria lo mismo, osea solo compartiendo tablas, pero no me funciono :(
        y pues encontre tu pàgina y me puse a modificar las partes que mencionas
        pero tampoco me funciono
        es necesario modificar APACHE??

        • ¿Modificar Apache? Lo veo francamente complicado xD

          Para hacer eso no te vale esta técnica, pero podrías usar los mismos conceptos para, en vez de “interceptar” el wp-load.php, interceptar solo la parte de WP que carga el theme. He echado un vistazo al código pero no he encontrado el punto donde se podría capturar esa lógica :-(