< 4 mins read

Servir un WordPress vía indirección proxy inverso con directiva proxy_pass de Nginx

Mimotic
Full-stack Developer

A veces necesitamos por distintas razones poder servir un sitio que está bajo nuestro control con un dominio diferente desde una ubicación diferente ya sean disintos sites de un mismo servidor o incluso servidores independientes que se puedan ver por red local.

Vemos este patrón en muchas startups que comparten el mismo problema en el que tienen un sistema SPA en Javascript como producto principal y queremos que dentro del domino esté el blog en vez de en un subdominio a parte.

Tiene sentido que este blog pueda ser un WordPress que permite al equipo de comunicación y marketing seguir produciendo cambios a la velocidad deseada sin tener que usar mano de obra de perfil alto que está con labores enfocadas en el producto. El objetivo es quitarle complejidad para abaratar la faceta marketiniana y dar independencia entre equipos y evitar stoppers y sobrecostes.

Claro que una opción es integrarlo headless en el SPA o incluso hacer un JAMStack pero suele ser habitual el cambio de diseño profundo y creación de nuevas tipologías continuamente y si debe pasar por maquetación manual e integración por ejemplo en react js con Gatsby o Next relentizan y encarecen esta pata.

Vamos a contar cómo podemos hacer esto dentro de un mismo servidor que contiendo dos sites.

Un sitio de WordPress estará en wordpress.spa.com y un SPA que vivirá bajo spa.com.

En este caso lo vamos distinguir por dominios, si fueran servidores diferente lo haríamos por IPs privadas.

Lo primero que necesitamos es que se vean por dentro y no tengan que salir a internet.

Así que entramos como root o con un usuario en el grupo sudo y modificamos el hosts para cuando nginx resuelva el dominio vaya por localhost y no necesite salir fuera a internet.

sudo vi /etc/hosts

Y necesitamos añadir los dominios en la línea de la IP de localhost

# /etc/hosts
127.0.0.1       blog.spa.com spa.com otros localhost

# The following lines are desirable for IPv6 capable hosts
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

Ahora ya se ven por dentro sin necesidad de reiniciar ningún servicio.

En nuestro caso el sitio que queremos indireccionar es un WordPress que debemos configurarlo como si sirviera bajo el dominio de destino spa.com/blog así que debemos cambiar las variables de WP_HOME y WP_SITEURL, puedes modificarlas de varias formas como, por ejemplo, cambiarlas en el wp-config.php:

define('WP_HOME', 'https://spa.com/blog/');
define('WP_SITEURL','https://spa.com/blog/');

Recomendamos siempre usar buenas prácticas y tener variables de entorno dentro del wp-config.php para evitar tener claves y entornos mezclados usando nuestro scaffolding de wordpress que hemos mejorado durante años trabajando con miles de proyectos.

Otra opción es hacer un search and replace con WP-CLI, la consola de comandos de WordPress. Esto cambiará los datos directamente en la base de datos. El método anterior tiene prioridad sobre esta segunda aproximación.

wp search-replace https://blog.spa.com/ https://spa.com/blog/

Además de esto siempre que necesitemos tener WordPress bajo una indirección ya sea por este motivo o bien por que lo tengamos bajo un balanceador de carga necesitamos añadir el siguiente código también en el wp-config.php:

/**
 * Allow WordPress detect HTTPS when used behind a reverse proxy or a load balancer
 * See https://codex.wordpress.org/Function_Reference/is_ssl#Notes
 */
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

/**
 * proxy_pass stuff needed
 */
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

Ya tenemos la parte de origen lista ahora necesitamos modificar el comportamiento de Nginx en el destino donde queremos que se muestre la indirección con un la directiva proxy_pass de Nginx, primero vamos a intentar definir qué es.

La directiva proxy_pass de Nginx especifica la dirección del servidor proxy al que se reenviarán las solicitudes. Es esencial en configuraciones de proxy inverso, permitiendo a nginx pasar solicitudes a otro servidor (o grupo de servidores) y devolver su respuesta al cliente original.

Para conseguir esto necesitamos tener acceso al server del site de nginx y añadir lo siguiente:

    location ^~ /blog/ {
        proxy_pass https://blog.spa.com/;
        proxy_ssl_server_name on;
    }

Para poder usar el backoffice y que funcionen los js y css que están en el core de WordPress necesitaremos también indicarle la ruta de acceso (recomendamos cambiar para evitar intentos de hacking, en nuestro caso hemos puesto spaadmin para que no se encuentre de forma tan obvia)

    location ^~ /blog/spaadmin/ {
        proxy_pass https://blog.spa.com/blog/spaadmin/;
        proxy_ssl_server_name on;
    }

Con esto ya tenemos una indirección completa y podemos servir un sitio completo bajo un path de otro dominio en otro servidor o site sin tener que montar un frankenstein con subcarpetas que pueda exponer archivos de configuración, ser inseguro y difícil de mantener.

Si quieres evitar contenido duplicado al ir por red privada puedes quitar los registros tipo A al WordPress inicial y así solo se servirá desde el subpath y no por dos dominios diferentes.

Contacto

Hola!

¿Quieres contarnos tu proyecto? ¡Escríbenos! Todo nuestro equipo teletrabaja el 100% del tiempo.

Ponte en contacto