Cómo migrar un sitio WordPress desde un entorno sandbox a producción paso a paso

Cómo migrar un sitio WordPress desde un entorno sandbox a producción paso a paso

Migrar un sitio WordPress desde un entorno sandbox a producción no debería hacerse copiando archivos “a ojo” ni improvisando cambios sobre la web real. Lo recomendable es trabajar con un procedimiento ordenado, verificable y reversible.

Un entorno sandbox permite preparar cambios, probar plugins, modificar diseño, revisar contenidos y corregir errores sin afectar al sitio público. Cuando todo está listo, llega el momento delicado: pasar esa versión al entorno de producción.

En este artículo se explica un proceso técnico, prudente y paso a paso para migrar WordPress desde un sandbox a producción usando Linux, SSH, copias de seguridad, bases de datos y comprobaciones básicas.

Antes de empezar

Antes de tocar producción conviene tener claro qué se va a migrar: archivos, base de datos, configuración del servidor, certificados, reglas de Nginx o Apache, plugins, tema, medios subidos y ajustes internos de WordPress.

También es importante decidir si se va a sustituir completamente la web de producción o si solo se van a incorporar cambios parciales. En una migración completa, lo habitual es reemplazar los archivos y la base de datos de producción por la versión ya validada en sandbox.

Antes de ejecutar comandos, conviene hacer al menos tres cosas:

  • Crear una copia de seguridad de la producción actual.
  • Crear una copia de seguridad del sandbox.
  • Guardar los ficheros SQL y las copias de archivos en una carpeta fechada.

La idea es sencilla: si algo sale mal, debe ser posible volver atrás.

Organización recomendada de directorios

Una forma sencilla de evitar confusiones es crear una carpeta de trabajo para la migración y, dentro de ella, separar claramente la copia del sandbox y la copia de producción.

En este ejemplo se usará una ruta común para guardar copias de migraciones:

/srv/copias-migraciones/

Dentro de esa ruta, cada migración se puede guardar en una carpeta con la fecha en formato AAAAMMDD. Por ejemplo, para una migración realizada el 4 de julio de 2026:

/srv/copias-migraciones/20260704/

Para crear la estructura mínima de trabajo, usaríamos estos comandos:

mkdir -p /srv/copias-migraciones/20260704/sandbox
mkdir -p /srv/copias-migraciones/20260704/produccion

Con esta estructura se mantiene una organización limpia:

/srv/copias-migraciones/20260704/
├── sandbox/
└── produccion/

En la carpeta sandbox se guardará la copia del entorno de pruebas. En la carpeta produccion se guardará la copia del sitio real antes de modificarlo.

Esta separación evita errores peligrosos, como sobrescribir una copia buena con otra incorrecta o no saber después qué archivo pertenece a cada entorno.

Además, si en el futuro se hacen más migraciones, cada una podrá quedar separada por fecha:

/srv/copias-migraciones/
├── 20260704/
├── 20260712/
└── 20260803/

Esta forma de trabajar ayuda mucho cuando se administran varios cambios, varias webs o varias pruebas sucesivas.

Copiar los archivos de WordPress

Supongamos una estructura como esta:

/var/www/sandbox.miempresa.com
/var/www/miempresa.com

Primero puede guardarse una copia de seguridad de los archivos actuales de producción:

rsync -aHAX --numeric-ids /var/www/miempresa.com/ /srv/copias-migraciones/20260704/produccion/

Después se guarda una copia del contenido del sandbox:

rsync -aHAX --numeric-ids /var/www/sandbox.miempresa.com/ /srv/copias-migraciones/20260704/sandbox/

Una vez verificadas ambas copias, se puede actualizar el contenido de producción copiando los archivos del sandbox. Es recomendable excluir el archivo wp-config.php, ya que normalmente contiene la configuración específica de producción (base de datos, usuario, contraseña y otros parámetros que no deben sobrescribirse).

Antes de realizar la copia definitiva, conviene ejecutar una simulación para comprobar qué archivos se copiarán, modificarán o eliminarán:

rsync -aHAX --delete --numeric-ids --dry-run \
  --exclude='wp-config.php' \
  /var/www/sandbox.miempresa.com/ \
  /var/www/miempresa.com/

Si el resultado de la simulación es el esperado, puede ejecutarse la copia real:

rsync -aHAX --delete --numeric-ids \
  --exclude='wp-config.php' \
  /var/www/sandbox.miempresa.com/ \
  /var/www/miempresa.com/

La opción --delete elimina en producción los archivos que ya no existan en el sandbox, dejando ambos directorios sincronizados. Debe utilizarse con especial cuidado, ya que un error en las rutas de origen o destino puede provocar la eliminación de archivos importantes.

Tras finalizar la copia, conviene revisar que el archivo wp-config.php de producción mantiene la configuración correcta, especialmente el nombre de la base de datos, el usuario, la contraseña y el prefijo de tablas que utilizará la instalación de producción.

Cómo comprobar que la copia se ha realizado correctamente

Una comprobación rápida consiste en revisar el número de archivos y el tamaño ocupado:

du -sh /var/www/sandbox.miempresa.com
du -sh /var/www/miempresa.com

find /var/www/sandbox.miempresa.com -type f | wc -l
find /var/www/miempresa.com -type f | wc -l

Sin embargo, esa comprobación solo da una orientación. Dos directorios pueden tener el mismo número de archivos y un tamaño parecido, pero contener diferencias internas.

Para una verificación mucho más sólida se pueden comparar hashes fichero a fichero. Esta comprobación calcula una huella criptográfica de cada archivo y permite detectar diferencias reales de contenido.

Primero generamos la lista de hashes del sandbox:

cd /var/www/sandbox.miempresa.com
find . -type f -print0 | sort -z | xargs -0 sha256sum > /srv/copias-migraciones/20260704/hashes-sandbox.sha256

Después generamos la lista de hashes de producción:

cd /var/www/miempresa.com
find . -type f -print0 | sort -z | xargs -0 sha256sum > /srv/copias-migraciones/20260704/hashes-produccion.sha256

Y finalmente comparamos ambos ficheros:

diff -u /srv/copias-migraciones/20260704/hashes-sandbox.sha256 /srv/copias-migraciones/20260704/hashes-produccion.sha256

Si el comando diff no muestra diferencias, los archivos comparados tienen el mismo contenido.

Esta verificación es muy sólida, pero puede ser muy larga si el sitio tiene mucho contenido, muchas imágenes, copias antiguas, cachés, backups o miles de archivos en wp-content/uploads. En webs grandes puede tardar bastante y consumir recursos de disco y CPU.

Si se quiere excluir cachés u otros directorios temporales, se puede adaptar el comando:

cd /var/www/sandbox.miempresa.com
find . -type f \
  ! -path "./wp-content/cache/*" \
  ! -path "./wp-content/uploads/cache/*" \
  -print0 | sort -z | xargs -0 sha256sum > /srv/copias-migraciones/20260704/hashes-sandbox.sha256

cd /var/www/miempresa.com
find . -type f \
  ! -path "./wp-content/cache/*" \
  ! -path "./wp-content/uploads/cache/*" \
  -print0 | sort -z | xargs -0 sha256sum > /srv/copias-migraciones/20260704/hashes-produccion.sha256

diff -u /srv/copias-migraciones/20260704/hashes-sandbox.sha256 /srv/copias-migraciones/20260704/hashes-produccion.sha256

Otra opción, antes de copiar realmente, es usar rsync en modo simulación:


rsync -aHAX --delete --numeric-ids --dry-run \
  --exclude='wp-config.php' \
  /var/www/sandbox.miempresa.com/ \
  /var/www/miempresa.com/

Con --dry-run se puede ver qué haría rsync sin modificar todavía los archivos de producción.

Exportar la base de datos del sandbox

La base de datos contiene entradas, páginas, usuarios, ajustes de WordPress, configuraciones de plugins, menús, widgets y muchas opciones internas del sitio.

Para exportar la base de datos del sandbox se puede usar mysqldump:

mysqldump -u usuario_sandbox -p nombre_bd_sandbox > /srv/copias-migraciones/20260704/sandbox/sandbox.sql

También se puede usar WP-CLI si está disponible:

cd /var/www/sandbox.miempresa.com
wp db export /srv/copias-migraciones/20260704/sandbox/sandbox.sql

Si WordPress debe ejecutarse con el usuario del servidor web, puede ser necesario usar:

cd /var/www/sandbox.miempresa.com
sudo -u www-data wp db export /srv/copias-migraciones/20260704/sandbox/sandbox.sql

Después conviene comprobar que el fichero SQL existe y tiene contenido:

ls -lh /srv/copias-migraciones/20260704/sandbox/sandbox.sql

Importar la base de datos en producción

Antes de importar nada, conviene guardar una copia de la base de datos actual de producción:

mysqldump -u usuario_produccion -p nombre_bd_produccion > /srv/copias-migraciones/20260704/produccion/produccion-antes-migracion.sql

También se puede hacer con WP-CLI desde el directorio de producción:

cd /var/www/miempresa.com
sudo -u www-data wp db export /srv/copias-migraciones/20260704/produccion/produccion-antes-migracion.sql

Después se puede importar la base de datos del sandbox sobre la base de datos de producción:

mysql -u usuario_produccion -p nombre_bd_produccion < /srv/copias-migraciones/20260704/sandbox/sandbox.sql

En algunos casos es preferible vaciar primero la base de datos de producción o crear una base de datos nueva y cambiar después el wp-config.php. Esta segunda opción suele ser más limpia cuando se quiere conservar intacta la base de datos anterior durante un tiempo.

Si se crea una base de datos nueva para producción, hay que asegurarse después de que wp-config.php apunte a esa nueva base de datos y no a la antigua.

Aviso a navegantes: alinear el prefijo de tablas entre sandbox y producción

Cuando se vuelca la base de datos del sandbox sobre producción, conviene aprovechar el momento para revisar si el prefijo de tablas de WordPress debe quedar igual que en el sandbox.

Este punto es importante porque WordPress no solo necesita conectarse a la base de datos correcta. También necesita usar el prefijo de tablas correcto, definido en el archivo wp-config.php mediante la variable $table_prefix.

Para comparar el prefijo del sandbox y el de producción:

grep "table_prefix" /var/www/sandbox.miempresa.com/wp-config.php
grep "table_prefix" /var/www/miempresa.com/wp-config.php

Si se ha importado en producción una base de datos procedente del sandbox, lo normal es que producción deba usar el mismo prefijo de tablas que tenía el sandbox en esa base de datos importada.

Este ajuste no consiste en inventar un prefijo nuevo, sino en hacer que el wp-config.php de producción coincida con el prefijo real de las tablas que se acaban de importar.

Por ejemplo, si el sandbox usa:

$table_prefix = 'abc123_';

y la base de datos importada contiene tablas como:

abc123_options
abc123_posts
abc123_users
abc123_usermeta

entonces el archivo wp-config.php de producción también debe tener:

$table_prefix = 'abc123_';

Si el prefijo de wp-config.php no coincide con el prefijo real de las tablas importadas, WordPress puede cargar una instalación vacía, mostrar errores, no encontrar usuarios o comportarse como si el sitio no estuviera correctamente instalado.

Por eso, antes de dar por buena la migración, hay que revisar y comparar siempre los dos archivos wp-config.php: el del sandbox y el de producción. La regla práctica es sencilla: la base de datos importada y el $table_prefix de producción deben hablar el mismo idioma.

Ubicación correcta de ABSPATH y wp-settings.php en wp-config.php

El archivo wp-config.php se procesa de arriba hacia abajo. Durante ese proceso,
WordPress todavía no ha cargado el núcleo ni los plugins, por lo que cualquier constante
personalizada que deba influir en su funcionamiento debe definirse antes de iniciar la carga
de WordPress.

La definición de ABSPATH y la llamada a
require_once ABSPATH . 'wp-settings.php'; deben situarse al final del archivo.
A partir de ese momento comienza la carga del núcleo de WordPress, los plugins, el tema y el
resto del entorno de ejecución.

Si se utilizan constantes para configurar determinados plugins (por ejemplo de SMTP,
seguridad, caché u otras integraciones), deben declararse antes de ejecutar:

require_once ABSPATH . 'wp-settings.php';

Si dichas constantes se definen después, es posible que el plugin ya se haya inicializado y
no tenga en cuenta esa configuración. Dependiendo del caso, esto puede provocar que la
configuración sea ignorada, aparezcan avisos de PHP o se produzcan comportamientos
inesperados.

La estructura recomendada al final del archivo es la siguiente:

/* Constantes de configuración de plugins */
define( 'MI_CONSTANTE', 'valor' );
...

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

Como regla general, la llamada a
require_once ABSPATH . 'wp-settings.php'; debe ser la última instrucción
ejecutable del archivo wp-config.php
. De este modo se garantiza que
toda la configuración necesaria esté disponible antes de que WordPress comience su proceso de
inicialización.

Revisión del archivo wp-config.php

El archivo wp-config.php es crítico. Define, entre otras cosas, el nombre de la base de datos, el usuario, la contraseña y el servidor MySQL que WordPress debe utilizar.

Para ver rápidamente los datos principales de conexión a base de datos en el sandbox:

grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST" /var/www/sandbox.miempresa.com/wp-config.php

Para verlos en producción:

grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST" /var/www/miempresa.com/wp-config.php

Si se quiere sacar cada dato por separado, se pueden usar estos comandos.

Nombre de la base de datos:

grep "DB_NAME" /var/www/miempresa.com/wp-config.php

Usuario de la base de datos:

grep "DB_USER" /var/www/miempresa.com/wp-config.php

Contraseña de la base de datos:

grep "DB_PASSWORD" /var/www/miempresa.com/wp-config.php

Servidor de base de datos:

grep "DB_HOST" /var/www/miempresa.com/wp-config.php

También se puede obtener solo el valor, limpiando la salida con sed:

grep "DB_NAME" /var/www/miempresa.com/wp-config.php | sed -E "s/.*'DB_NAME',[[:space:]]*'([^']+)'.*/\1/"
grep "DB_USER" /var/www/miempresa.com/wp-config.php | sed -E "s/.*'DB_USER',[[:space:]]*'([^']+)'.*/\1/"
grep "DB_PASSWORD" /var/www/miempresa.com/wp-config.php | sed -E "s/.*'DB_PASSWORD',[[:space:]]*'([^']+)'.*/\1/"
grep "DB_HOST" /var/www/miempresa.com/wp-config.php | sed -E "s/.*'DB_HOST',[[:space:]]*'([^']+)'.*/\1/"

Si se quieren revisar esos mismos valores en el sandbox, basta con cambiar la ruta:

grep "DB_NAME" /var/www/sandbox.miempresa.com/wp-config.php | sed -E "s/.*'DB_NAME',[[:space:]]*'([^']+)'.*/\1/"
grep "DB_USER" /var/www/sandbox.miempresa.com/wp-config.php | sed -E "s/.*'DB_USER',[[:space:]]*'([^']+)'.*/\1/"
grep "DB_PASSWORD" /var/www/sandbox.miempresa.com/wp-config.php | sed -E "s/.*'DB_PASSWORD',[[:space:]]*'([^']+)'.*/\1/"
grep "DB_HOST" /var/www/sandbox.miempresa.com/wp-config.php | sed -E "s/.*'DB_HOST',[[:space:]]*'([^']+)'.*/\1/"

Hay que tratar estos datos con cuidado, especialmente la contraseña. No conviene pegarlos en tickets, chats, capturas de pantalla ni documentos compartidos sin necesidad.

Si se ha copiado el wp-config.php del sandbox a producción, es imprescindible comprobar que producción apunta a la base de datos correcta. Un error aquí puede hacer que la web real use la base de datos del sandbox o que directamente deje de funcionar.

Cambiar las URLs del sitio

Antes de modificar las URLs almacenadas en la base de datos, conviene comprobar que WordPress reconoce correctamente la instalación utilizando la configuración actual del archivo wp-config.php. Esta comprobación permite detectar problemas de conexión con la base de datos o discrepancias en el valor de $table_prefix antes de realizar cambios adicionales.

cd /var/www/miempresa.com
sudo -u www-data wp core is-installed

Si todo es correcto, el comando devolverá un mensaje similar a:

Success: WordPress is installed.

Si aparece un error, conviene revisar nuevamente el contenido de wp-config.php, especialmente el nombre de la base de datos, el usuario, la contraseña, el servidor MySQL y el valor de $table_prefix, antes de continuar con la migración.

Una vez comprobado que WordPress funciona correctamente, es habitual que todavía existan referencias al dominio del entorno sandbox dentro de la base de datos.

Por ejemplo:

https://sandbox.miempresa.com

Debe sustituirse por:

https://miempresa.com

Con WP-CLI es recomendable realizar primero una simulación para comprobar cuántas referencias se modificarían:

cd /var/www/miempresa.com
sudo -u www-data wp search-replace "https://sandbox.miempresa.com" "https://miempresa.com" --dry-run

La opción --dry-run no modifica la base de datos; únicamente muestra los cambios que se realizarían. Si el resultado es el esperado, puede ejecutarse el reemplazo definitivo:

cd /var/www/miempresa.com
sudo -u www-data wp search-replace "https://sandbox.miempresa.com" "https://miempresa.com"

Después conviene comprobar que las opciones principales del sitio contienen ya la URL de producción:

cd /var/www/miempresa.com
sudo -u www-data wp option get siteurl
sudo -u www-data wp option get home

Si fuese necesario, pueden actualizarse manualmente:

cd /var/www/miempresa.com
sudo -u www-data wp option update siteurl "https://miempresa.com"
sudo -u www-data wp option update home "https://miempresa.com"

Por último, es recomendable comprobar que no quedan referencias al dominio del sandbox en la base de datos:

cd /var/www/miempresa.com
sudo -u www-data wp db search "sandbox.miempresa.com"

Revisar permisos y propietarios

Después de copiar archivos, es frecuente que algunos permisos o propietarios no queden como deberían.

En servidores con Nginx o Apache usando www-data, puede aplicarse una revisión básica:

chown -R www-data:www-data /var/www/miempresa.com

find /var/www/miempresa.com -type d -exec chmod 755 {} \;
find /var/www/miempresa.com -type f -exec chmod 644 {} \;

Esta configuración es una base común, aunque puede variar según el servidor, el panel de hosting, el usuario PHP-FPM o la política de seguridad aplicada.

En servidores administrados manualmente, los permisos incorrectos pueden provocar errores al subir imágenes, actualizar plugins, generar caché o escribir archivos temporales.

Vaciar cachés

Una vez migrado el sitio, pueden quedar restos en varias capas de caché:

  • Caché del navegador.
  • Caché de WordPress.
  • Caché de plugins.
  • Caché del servidor.
  • Caché de CDN, si existe.

Con WP-CLI se puede intentar vaciar la caché interna de WordPress:

cd /var/www/miempresa.com
sudo -u www-data wp cache flush

Si se usa un plugin de caché, también conviene vaciarlo desde el panel de WordPress o mediante sus propios comandos, si los tiene.

En Nginx, Apache, PHP-FPM o Redis puede ser necesario reiniciar servicios, dependiendo de la configuración:

systemctl reload nginx
systemctl restart php8.1-fpm

La versión de PHP debe adaptarse al servidor real. Por ejemplo, en otro servidor podría ser php8.2-fpm, php8.3-fpm u otra versión.

Pruebas finales

Antes de dar por terminada la migración, conviene revisar la web desde fuera y desde dentro.

Comprobaciones recomendadas:

  • La portada carga correctamente.
  • Las páginas principales funcionan.
  • Los artículos del blog se ven bien.
  • Las imágenes cargan desde el dominio correcto.
  • Los formularios funcionan.
  • El área de administración permite entrar.
  • Los enlaces internos no apuntan al sandbox.
  • El certificado HTTPS es válido.
  • No hay errores relevantes en los logs.

Para revisar errores en Nginx:

tail -f /var/log/nginx/error.log

Para revisar accesos:

tail -f /var/log/nginx/access.log

Si el servidor tiene logs separados por dominio, conviene revisar los logs específicos del sitio migrado.

También es recomendable abrir la web en una ventana privada del navegador o desde otro dispositivo para evitar confundir un problema real con una caché local.

Preguntas frecuentes

¿Es obligatorio usar SSH para migrar WordPress?

No siempre, pero SSH ofrece mucho más control. En sitios pequeños se puede migrar con plugins, pero en servidores propios o webs con cierto tamaño suele ser más fiable trabajar con comandos, copias verificables y exportaciones SQL.

¿Puedo migrar solo los archivos y no la base de datos?

Depende del cambio. Si solo se han modificado archivos del tema, plugins o medios, quizá sea suficiente. Pero si en el sandbox se han cambiado páginas, entradas, menús, widgets o ajustes, también habrá que migrar la base de datos.

¿Por qué hay que cambiar las URLs después de importar la base de datos?

Porque WordPress guarda muchas referencias internas al dominio. Si la base de datos viene del sandbox, puede contener enlaces, imágenes o ajustes apuntando todavía al dominio de pruebas.

¿La comparación de hashes es imprescindible?

No siempre es imprescindible, pero es una verificación muy sólida. Permite confirmar fichero a fichero que el contenido copiado coincide. En webs grandes puede tardar bastante, por lo que conviene usarla cuando se necesita una comprobación especialmente rigurosa.

¿Qué hago si después de migrar sigo viendo la web antigua?

Puede ser un problema de caché del navegador, caché de WordPress, caché del servidor, CDN o incluso DNS. Conviene revisar cada capa por separado y probar la web desde una ventana privada o desde otro dispositivo.

Conclusión

Migrar WordPress desde un sandbox a producción no consiste solo en copiar archivos. También hay que proteger la versión anterior, exportar e importar correctamente la base de datos, revisar el archivo wp-config.php, cambiar URLs internas, comprobar permisos, limpiar cachés y validar el resultado final.

Un procedimiento ordenado reduce mucho el riesgo de caída, pérdida de datos o errores difíciles de localizar. En sitios pequeños puede parecer excesivo, pero cuando se trabaja con una web real de empresa, la prudencia técnica es parte del trabajo.

La clave está en no improvisar sobre producción: primero copia, después verifica, luego migra y finalmente comprueba.

Scroll al inicio