Pasar un WordPress de un hosting compartido a un VPS te da recursos dedicados, control sobre la versión de PHP y la caché, y acceso completo al servidor. La migración en sí es sencilla (copiar archivos y base de datos), pero para hacerla sin cortes ni pérdida de datos conviene seguir un orden: preparar el servidor, copiar, probar el sitio en el VPS antes de que lo vea nadie y solo entonces cambiar el DNS. En este tutorial migrarás un WordPress a un VPS con Ubuntu 24.04, Nginx, PHP 8.3-FPM y MySQL 8.0, y lo pondrás en marcha con HTTPS.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM y espacio en disco de sobra para el sitio y una copia.
  • Un usuario no root con privilegios sudo.
  • Acceso al hosting actual: panel (cPanel, Plesk o similar) con phpMyAdmin y gestor de archivos, o mejor aún acceso SSH.
  • Acceso a la gestión DNS de tu dominio. En los ejemplos se usa example.com; sustitúyelo por el tuyo y your_server_ip por la IP del VPS.

Paso 1: Planificar la migración

Unos minutos de preparación evitan la mayoría de los problemas.

Baja el TTL del DNS. Al menos 24 horas antes de la migración, reduce el TTL de los registros A de example.com y www.example.com a 300 segundos en tu proveedor DNS. Así, cuando cambies la IP, los visitantes llegarán al VPS en minutos en lugar de horas.

Anota las versiones. En el panel de WordPress, ve a Herramientas > Salud del sitio > Información y apunta la versión de WordPress, la de PHP y el prefijo de las tablas de la base de datos. Ubuntu 24.04 trae PHP 8.3; si tu sitio funciona con PHP 7.4 o anterior, actualiza antes los plugins y el tema en el hosting actual y comprueba que son compatibles con PHP 8.

Comprueba dónde está el correo. Si tus buzones @example.com están en el hosting compartido, al migrar solo moverás la web: cambiarás únicamente los registros A y dejarás intactos los registros MX. Revisa también si el hosting te daba el DNS; en ese caso, antes de cancelar la cuenta tendrás que llevar la zona a otro proveedor.

Elige una ventana de poco tráfico. Si el sitio recibe pedidos o comentarios, todo lo que ocurra en el hosting antiguo entre la copia y el cambio de DNS se perdería. Lo resolverás con una sincronización final en el paso 9.

Paso 2: Preparar el VPS

Actualiza el sistema e instala Nginx, MySQL, PHP-FPM y las extensiones de PHP que necesita WordPress:

sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx mysql-server php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-intl php8.3-mbstring php8.3-xml php8.3-zip php-imagick unzip

Abre el firewall para SSH y para la web:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Instala WP-CLI, que usarás para ajustar la configuración y comprobar el sitio:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Comprueba que los servicios están activos:

systemctl is-active nginx mysql php8.3-fpm
active
active
active

Paso 3: Crear la base de datos

Crea una base de datos y un usuario dedicados para WordPress. Sustituye your_strong_password por una contraseña larga y aleatoria (puedes generarla con openssl rand -base64 24):

sudo mysql
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
EXIT;

Comprueba que el usuario puede conectarse:

mysql -u wpuser -p -e "SHOW DATABASES;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| wordpress          |
+--------------------+

Paso 4: Exportar el sitio del hosting compartido

Necesitas dos cosas: los archivos de WordPress (sobre todo wp-content, que contiene temas, plugins y medios) y un volcado de la base de datos. Elige la opción según el acceso que te dé tu hosting.

Opción A: con acceso SSH

Es la opción más rápida y fiable. Conéctate al hosting y exporta la base de datos desde la carpeta de WordPress (normalmente public_html):

ssh your_hosting_user@your_hosting_host
cd ~/public_html
wp db export ~/wordpress.sql

Si el hosting no tiene WP-CLI, usa mysqldump con los datos de DB_NAME, DB_USER y DB_HOST que aparecen en wp-config.php:

mysqldump -h localhost -u hosting_db_user -p --single-transaction --no-tablespaces hosting_db_name > ~/wordpress.sql

Sal del hosting y, desde el VPS, trae los archivos y el volcado con rsync, que se puede reanudar si se corta la conexión:

sudo mkdir -p /var/www/example.com
sudo chown your_user:your_user /var/www/example.com
rsync -avz --progress your_hosting_user@your_hosting_host:public_html/ /var/www/example.com/
rsync -avz your_hosting_user@your_hosting_host:wordpress.sql ~/

Muchos hostings compartidos usan un puerto SSH distinto del 22; si es tu caso, añade -e 'ssh -p PUERTO' a rsync. La barra final en public_html/ copia el contenido de la carpeta, no la carpeta en sí.

Opción B: solo con el panel del hosting

  1. En phpMyAdmin, selecciona la base de datos de WordPress, abre Exportar, elige el método Rápido y el formato SQL, y descarga el archivo.
  2. En el Administrador de archivos, comprime la carpeta public_html (o la del sitio) en un ZIP y descárgalo.

Sube ambos archivos al VPS desde tu equipo:

scp wordpress.sql public_html.zip your_user@your_server_ip:~/

Y en el VPS, descomprime el ZIP en la carpeta del sitio:

sudo mkdir -p /var/www/example.com
sudo chown your_user:your_user /var/www/example.com
unzip ~/public_html.zip -d ~/public_html_tmp

Según cómo se haya creado, el ZIP puede contener una carpeta public_html dentro. Localiza la carpeta que contiene wp-config.php y copia su contenido al destino:

find ~/public_html_tmp -maxdepth 2 -name wp-config.php
rsync -a ~/public_html_tmp/public_html/ /var/www/example.com/

Comprobar la copia

En cualquiera de los dos casos, comprueba que están los archivos clave y que el volcado no está vacío ni truncado. Un volcado completo termina con la línea -- Dump completed (mysqldump y WP-CLI) o con el cierre de la última tabla (phpMyAdmin):

ls /var/www/example.com/wp-config.php /var/www/example.com/wp-content
du -sh /var/www/example.com
tail -n 1 ~/wordpress.sql
/var/www/example.com/wp-config.php

/var/www/example.com/wp-content:
index.php  languages  plugins  themes  uploads
1.8G	/var/www/example.com
-- Dump completed on 2026-09-25 10:14:02

Paso 5: Importar la base de datos

Importa el volcado en la base de datos que creaste en el paso 3:

mysql -u wpuser -p wordpress < ~/wordpress.sql

Comprueba que las tablas están y anota su prefijo:

mysql -u wpuser -p -e "SHOW TABLES;" wordpress | head -5
Tables_in_wordpress
wp_commentmeta
wp_comments
wp_links
wp_options

Si el hosting usaba un prefijo distinto de wp_ (por ejemplo wpxy_), no lo cambies: el wp-config.php que has copiado ya contiene el valor correcto en $table_prefix.

Paso 6: Ajustar wp-config.php y los permisos

El wp-config.php copiado sigue apuntando a la base de datos del hosting. Actualiza los datos de conexión con WP-CLI:

cd /var/www/example.com
wp config set DB_NAME wordpress
wp config set DB_USER wpuser
wp config set DB_PASSWORD 'your_strong_password'
wp config set DB_HOST localhost

Revisa además restos del hosting anterior que no funcionarán en el VPS:

  • Carpeta wp-content/mu-plugins: muchos hostings instalan aquí plugins propios (de caché, de su panel o de seguridad). Si ves archivos que corresponden al hosting, muévelos fuera de esa carpeta.
  • Archivos wp-content/advanced-cache.php y wp-content/object-cache.php: si los creó un plugin de caché del hosting (por ejemplo LiteSpeed Cache, que depende del servidor LiteSpeed), desactiva ese plugin y borra estos archivos.
  • Archivo .htaccess: Nginx no lo usa. Puedes dejarlo, pero cualquier regla personalizada que tuviera (redirecciones, bloqueos) hay que trasladarla a la configuración de Nginx.

Para desactivar un plugin de caché del hosting sin entrar al panel:

wp plugin deactivate litespeed-cache --skip-plugins --skip-themes

Asigna los archivos al usuario de Nginx y PHP-FPM, con permisos 755 para directorios y 644 para archivos:

sudo chown -R www-data:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} +
sudo find /var/www/example.com -type f -exec chmod 644 {} +
sudo chmod 640 /var/www/example.com/wp-config.php

Comprueba que WordPress conecta con la base de datos y lee la URL del sitio:

sudo -u www-data wp --path=/var/www/example.com option get siteurl
https://example.com

Paso 7: Configurar Nginx

Todavía no puedes obtener un certificado de Let's Encrypt porque el dominio apunta al hosting antiguo. Mientras tanto usarás el certificado autofirmado que genera Ubuntu (snakeoil), suficiente para probar el sitio. Asegúrate de que existe:

sudo apt install -y ssl-cert
ls /etc/ssl/certs/ssl-cert-snakeoil.pem

Crea el bloque de servidor:

sudo nano /etc/nginx/sites-available/example.com
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name example.com www.example.com;

    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    root /var/www/example.com;
    index index.php;
    client_max_body_size 64m;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.(?!well-known) {
        deny all;
    }
}

La redirección a HTTPS está dentro de location / a propósito: así Certbot podrá añadir su ruta de validación en el paso 10 sin que la redirección la intercepte.

Activa el sitio, desactiva el sitio por defecto y recarga Nginx:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx

Sube también el límite de subida de PHP para que coincida con el de Nginx:

sudo nano /etc/php/8.3/fpm/conf.d/99-wordpress.ini
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
sudo systemctl restart php8.3-fpm

Paso 8: Probar el sitio antes de cambiar el DNS

Puedes ver el sitio del VPS con su dominio real sin que el resto del mundo lo vea, haciendo que solo tu equipo resuelva example.com a la IP del VPS. Desde el servidor, compruébalo primero con curl:

curl -skI --resolve example.com:443:127.0.0.1 https://example.com/ | head -1
HTTP/2 200

Después, en tu equipo local, edita el archivo hosts (/etc/hosts en Linux y macOS, C:\Windows\System32\drivers\etc\hosts en Windows, abriendo el editor como administrador) y añade:

your_server_ip  example.com www.example.com

Abre https://example.com en el navegador. Verás un aviso de certificado no válido porque es el autofirmado: acéptalo temporalmente. Revisa:

  • La portada, varias entradas y páginas, y el buscador.
  • Que las imágenes cargan (están en wp-content/uploads).
  • El acceso a /wp-admin y que puedes subir una imagen nueva.
  • Formularios, carrito y checkout si los tienes.

Mientras navegas, vigila los errores en el servidor:

sudo tail -f /var/log/nginx/error.log /var/log/php8.3-fpm.log

Cuando termines, quita la línea del archivo hosts para volver a ver el sitio real.

Paso 9: Sincronizar los últimos cambios y cambiar el DNS

Si desde la copia del paso 4 se han publicado entradas, recibido comentarios o pedidos, vuelve a copiar la base de datos justo antes del cambio. Para no perder nada entre la copia y el cambio de DNS, activa en el hosting antiguo el modo mantenimiento o evita publicar durante ese rato.

Con acceso SSH, repite la exportación en el hosting y, desde el VPS, trae el volcado y los medios nuevos:

rsync -avz your_hosting_user@your_hosting_host:wordpress.sql ~/
rsync -avz your_hosting_user@your_hosting_host:public_html/wp-content/uploads/ /tmp/uploads-sync/
sudo rsync -a --chown=www-data:www-data /tmp/uploads-sync/ /var/www/example.com/wp-content/uploads/

Si solo tienes acceso al panel, repite la exportación de phpMyAdmin, descarga las carpetas de uploads que hayan cambiado y súbelas con scp como en el paso 4.

Los volcados de mysqldump y wp db export incluyen DROP TABLE antes de cada tabla, así que reemplazan los datos anteriores al importarlos. Los de phpMyAdmin no lo incluyen por defecto: en ese caso, borra antes las tablas de WordPress con sudo -u www-data wp --path=/var/www/example.com db clean --yes. Después importa el volcado:

mysql -u wpuser -p wordpress < ~/wordpress.sql

Ahora cambia en tu proveedor DNS los registros A de example.com y www.example.com (y los AAAA si existen) a your_server_ip. No toques los registros MX ni los TXT del correo. Comprueba la resolución:

dig +short example.com
dig +short www.example.com
203.0.113.10
203.0.113.10

Con el TTL a 300 segundos, la mayoría de los visitantes llegarán al VPS en pocos minutos.

Paso 10: Obtener el certificado de Let's Encrypt

Cuando el dominio ya resuelve al VPS, sustituye el certificado autofirmado por uno válido. El plugin de Nginx de Certbot lo obtiene y lo instala en el bloque de servidor:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Comprueba que Nginx usa ya el certificado nuevo y que la renovación automática funciona:

sudo nginx -T 2>/dev/null | grep ssl_certificate
sudo certbot renew --dry-run
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot

Si el sitio del hosting usaba http://, actualiza las URL guardadas en la base de datos. Revisa primero cuántas se cambiarían con --dry-run:

sudo -u www-data wp --path=/var/www/example.com search-replace 'http://example.com' 'https://example.com' --skip-columns=guid --dry-run

Si el resultado es razonable, ejecútalo sin --dry-run. search-replace maneja correctamente los datos serializados de PHP, algo que un simple REPLACE en SQL rompería.

Paso 11: Tareas posteriores a la migración

Correo saliente. En el hosting compartido, WordPress enviaba los correos (formularios, pedidos, restablecimiento de contraseña) con el servidor de correo del hosting. El VPS no tiene uno configurado, así que esos correos no saldrán. Instala un plugin SMTP y configúralo con tu proveedor de correo o un servicio de envío transaccional usando el puerto 587 con autenticación.

WP-Cron. Para que las tareas programadas se ejecuten aunque no haya visitas, desactiva WP-Cron y lánzalo desde el cron del sistema:

sudo -u www-data wp --path=/var/www/example.com config set DISABLE_WP_CRON true --raw
echo '*/5 * * * * www-data /usr/local/bin/wp --path=/var/www/example.com cron event run --due-now --quiet' | sudo tee /etc/cron.d/wordpress

Enlaces permanentes. Si alguna URL da 404, entra en Ajustes > Enlaces permanentes y pulsa Guardar sin cambiar nada para regenerar las reglas.

No canceles el hosting todavía. Mantenlo al menos una semana: algunos visitantes con DNS en caché seguirán llegando allí durante unas horas y te servirá como copia de seguridad. Cuando canceles, conserva el volcado y el archivo de la copia en un lugar seguro fuera del VPS.

Solución de problemas

  • "Error establishing a database connection": los datos de wp-config.php no coinciden con los del paso 3. Compruébalos con wp config get DB_USER y prueba a conectar a mano con mysql -u wpuser -p wordpress.
  • Pantalla en blanco o error 500: casi siempre es un plugin incompatible con PHP 8.3. Revisa /var/log/php8.3-fpm.log y /var/log/nginx/error.log, y desactiva el plugin que aparezca con wp plugin deactivate nombre --skip-plugins.
  • Bucle de redirecciones: suele venir de un plugin de caché o de redirecciones del hosting, o de un siteurl con www distinto del que usas. Comprueba wp option get siteurl y wp option get home.
  • Imágenes rotas con URL del hosting antiguo: si el sitio usaba un dominio temporal o una ruta distinta, sustituye la URL antigua por la nueva con wp search-replace.
  • ERROR 1273 Unknown collation al importar: el volcado usa una intercalación que tu servidor no reconoce. Ocurre al importar en MariaDB un volcado de MySQL 8 con utf8mb4_0900_ai_ci; con MySQL 8.0 en el VPS, como en esta guía, no pasa.

Conclusión

Has migrado WordPress de un hosting compartido a un VPS con Ubuntu 24.04: preparaste Nginx, PHP-FPM y MySQL, copiaste archivos y base de datos, probaste el sitio con el archivo hosts antes de que lo viera nadie, sincronizaste los últimos cambios, cambiaste el DNS y activaste HTTPS con Let's Encrypt. Como siguientes pasos, configura copias de seguridad automáticas fuera del servidor, añade caché de página y de objetos para aprovechar los recursos del VPS, y endurece la seguridad de WordPress ajustando permisos y protegiendo el acceso.