Local, desarrollo, pre-producción, producción… entornos de desarrollo habituales en cualquier proyecto web. Cada uno de ellos con características y configuraciones diferentes, distintos usuarios de base de datos, distintos permisos, etc… y es en el wp-config.php donde para cada uno de ellos necesitaremos configurar valores distintos para algunas constantes.
Aunque necesarios, probablemente en más de una ocasión nos hayan dado más de un dolor de cabeza. Y más que probable es que hayamos tirado de nuestra frase preferida: ¡en mi local funciona!
Uno de los archivos que cambiará en función del entorno es el wp-config.php, que es donde se configuran el nombre de la base de datos, usuario, contraseña, etc… (entre otras cosas que también pueden ser diferentes como el debug, table_prefix…). Estos datos suelen ser diferentes en los 4 entornos habituales de desarrollo: local, desarrollo, pre (o staging) y pro.
Es decir, el archivo wp-config.php debe ser diferente en estos 4 entornos. El problema se acentúa además cuando sois varias personas en el mismo equipo de trabajo y utilizáis control de versiones. Puede que mi usuario/clave/nombre bbdd en mi local sea diferente al de los compañeros/as, y ese archivo bajo un control de versiones se convierte en un caos.
Voy a ser sincero, desde que trabajo con WordPress bajo control de versiones he probado diferentes métodos que explico a continuación:
Añadir el wp-config.php a .gitignore
La ventaja es que ese archivo no entra dentro del control de versiones, por lo tanto cada miembro del equipo de trabajo y cada entorno de desarrollo pueden tener su fichero wp-config.php diferente.
En su ventaja está implícito su inconveniente: Al no estar bajo el control de versiones cada persona del equipo de trabajo debe descargarse a parte este archivo, o pasárselo de unos a otros. Además implica el subir manualmente por FTP o rsync a cada entorno este archivo configurado de manera independiente.
El problema es que cada persona y cada entorno tendrán un wp-config.php distinto, y si se define una constante o se realiza alguna configuración adicional, hay que avisar a todos los miembros del equipo e ir entorno por entorno realizando el mismo cambio en ese archivo.
Lo ideal entonces es que agreguéis al proyecto un wp-config.php.dist para que cada miembro del equipo lo tenga disponible y pueda generar el config a raíz de este archivo y modificarlo según sus necesidades. Recordad que al estar en el .gitignore, no se subirá al hacer commit/push.
Añadir un condicional en wp-config.php
Éste método simplemente implica sustituir la definición de las constantes de conexión a la base de datos, debug, caché y table_prefix por algo como esto:
if ( 'local_server_name' === filter_var($_SERVER['SERVER_NAME'], FILTER_SANITIZE_STRING) ) {
// Entorno local
define( 'DB_NAME', 'local_db_name' );
define( 'DB_USER', 'local_db_user' );
define( 'DB_PASSWORD', 'local_db_pass' );
define( 'DB_HOST', 'local_db_host' );
$table_prefix = 'localprefix_';
// Para el entorno local puede que quieras que el debug esté activo y la cache inactiva
define( 'WP_DEBUG', true );
define( 'WP_CACHE', false );
} elseif( 'dev_server_name' === filter_var($_SERVER['SERVER_NAME'], FILTER_SANITIZE_STRING) ) {
// Entorno desarrollo
define( 'DB_NAME', 'dev_db_name' );
define( 'DB_USER', 'dev_db_user' );
define( 'DB_PASSWORD', 'dev_db_pass' );
define( 'DB_HOST', 'dev_db_host' );
$table_prefix = 'devprefix_';
// Para el entorno local puede que quieras que el debug esté activo y la cache inactiva
define( 'WP_DEBUG', true );
define( 'WP_CACHE', false );
} elseif( 'pre_server_name' === filter_var($_SERVER['SERVER_NAME'], FILTER_SANITIZE_STRING) ) {
// Entorno PRE
define( 'DB_NAME', 'pre_db_name' );
define( 'DB_USER', 'pre_db_user' );
define( 'DB_PASSWORD', 'pre_db_pass' );
define( 'DB_HOST', 'pre_db_host' );
$table_prefix = 'preprefix_';
// Para el entorno PRE puede que quieras que sea igual a PRO
define( 'WP_DEBUG', false );
define( 'WP_CACHE', true );
} else {
// Entorno PRO
define( 'DB_NAME', 'pro_db_name' );
define( 'DB_USER', 'pro_db_user' );
define( 'DB_PASSWORD', 'pro_db_pass' );
define( 'DB_HOST', 'pro_db_host' );
$table_prefix = 'proprefix_';
// Para el entorno PRO tendremos el debug desactivado y la caché activa
define( 'WP_DEBUG', false );
define( 'WP_CACHE', true );
}
Es un if donde preguntamos por en nombre del servidor: $_SERVER[‘SERVER_NAME’], y en función de éste parámetro se establecen las distintas constantes. También podríamos preguntar por $_SERVER[‘HTTP_HOST’].
De esta manera el archivo wp-config.php puede volver al control de versiones sin problema, ¿o no? Pues no del todo, la parte local puede ser diferente entre los miembros del equipo de trabajo.
Esto podemos solucionarlo con variables de entorno en el Virtual Host. Cada miembro del equipo de trabajo deberá crear una variables de entorno en su vhost, teniendo algo parecido a:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName wptest.dev
ServerAlias wptest.dev
SetEnv ENV_DB_NAME 'dev_db_name'
SetEnv ENV_DB_USER 'dev_db_user'
SetEnv ENV_DB_PASS 'dev_db_pass'
SetEnv ENV_DB_HOST 'dev_db_host'
DocumentRoot /var/www/html/wp-test
<Directory /var/www/html/wp-test>
Options FollowSymLinks Indexes
AllowOverride All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error-wptest.log
CustomLog ${APACHE_LOG_DIR}/access-wptest.log combined
</VirtualHost>
Y en el wp-config.php, dentro del if de entorno local recuperaremos los valores de estas variables de entorno:
// Entorno local
define( 'DB_NAME', getenv('ENV_DB_NAME') );
define( 'DB_USER', getenv('ENV_DB_USER') );
define( 'DB_PASSWORD', getenv('ENV_DB_PASS') );
define( 'DB_HOST', getenv('ENV_DB_HOST') );
De este modo cada miembro del equipo podrá tener configurado de manera independiente sus datos de acceso a la base de datos, y el fichero wp-config.php será el mismo para todos.
Una solución más «elegante»
La configuración de variables y entornos de trabajo no es algo inherente a WordPress. En muchos frameworks tienen diferentes archivos que se cargan en función de un entorno u otro. ¿Cómo podríamos aplicar esto a WordPress?
Podemos crear en la raíz de nuestra instalación un directorio llamado wp-config, y dentro incluir los ficheros:
- wp-db-local.php
- wp-db-dev.php
- wp-db-pre.php
- wp-db-pro.php
En cada uno de estos ficheros se configurarán las constantes correspondientes a cada entorno. Por ejemplo para wp-db-local.php quedaría algo así:
<?php
// Prevent file from being accessed directly
if (!defined('ABSPATH')) exit();
// Entorno local
define( 'DB_NAME', getenv('ENV_DB_NAME') );
define( 'DB_USER', getenv('ENV_DB_USER') );
define( 'DB_PASSWORD', getenv('ENV_DB_PASS') );
define( 'DB_HOST', getenv('ENV_DB_HOST') );
$table_prefix = 'localprefix_';
// Para el entorno local puede que quieras que el debug esté activo y la cache inactiva
define( 'WP_DEBUG', true );
define( 'WP_CACHE', false );
En nuestro wp-config.php incluiremos estas líneas:
// Set your environment/url pairs
$environments = array(
'local' => 'local.mydomain.com',
'dev' => 'dev.mydomain.com',
'pre' => 'pre.mydomain.com',
'pro' => 'mydomain.com'
);
// Get the hostname
$http_host = filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_STRING);
// Loop through $environments to see if there’s a match
foreach($environments as $environment => $hostname) {
if (stripos($http_host, $hostname) !== FALSE) {
define('ENVIRONMENT', $environment);
break;
}
}
// Exit if ENVIRONMENT is undefined
if (!defined('ENVIRONMENT')) exit('No database configured for this host');
// Location of environment-specific configuration
$wp_db_config = 'wp-config/wp-db-' . ENVIRONMENT . '.php';
// Check to see if the configuration file for the environment exists
if (file_exists(__DIR__ . '/' . $wp_db_config)) {
require_once($wp_db_config);
} else {
// Exit if configuration file does not exist
exit('No database configuration found for this host');
}
Comprobaremos en qué entorno estamos y cargaremos el archivo de configuración correspondiente. De este modo podemos tener todo organizado en archivos independientes.
¿Y qué pasa con la línea de comandos?
Pero como no todo va a ser un camino de rosas, si optas por utilizar variables de entorno y utilizas WP-CLI en tu día a día verás que deja de funcionarte y te salta algo como esto:
Error: Error al establecer una conexión con la base de datos. Esto significa que, o la información de nombre de usuario y contraseña de tu archivo ‘wp-config.php’ es incorrecto o que no podemos contactar con el servidor de la base de datos en ». Esto podría significar que el servidor de tu base de datos está caído.
WP CLI
Para solucionar esto, al menos en linux, dirígete al archivo environment que encontrarás en la carpeta /etc. Debemos configurar las constantes.
export ENV_DB_NAME="local_db_name"
export ENV_DB_USER="local_db_user"
export ENV_DB_PASS="local_db_pass"
export ENV_DB_HOST="local_db_host"
La pega es que tenemos los datos de acceso a base de datos en dos sitios diferentes: /etc/environment y virtual host. Además deberemos hacer la llamada al fichero /etc/environment desde nuestro .profile para que estén disponibles estas variables desde la línea de comandos.