Adiós a Local en Windows: cómo migré mi WordPress a DDEV con WSL2

Va lento, se cae cada dos por tres, explota cuando le da la gana… y lo peor es que ni siquiera puedo echarle toda la culpa a Local. El verdadero problema es Windows y su sistema de ficheros, que sigue arrastrando manías del prehistórico que le hacen la vida imposible a cualquier entorno tipo Docker que corra por encima. Local no tiene la culpa de eso, pero da igual, yo ya no puedo más.

Antes de llegar a DDEV probé las alternativas obvias. WordPress Studio y DevKinsta se me quedan cortos, entre que buscan tenerte encerrado en su propio ecosistema y que no van bien con webs que ya viven en otros hostings, que es mi caso casi siempre. Y lo de WordPress Studio en concreto tiene una pega gorda de fondo: su deuda técnica con SQLite todavía no aguanta bien sitios complejos, grandes, con muchos datos interconectados entre sí. Para un proyectillo rápido vale, para lo que yo manejo, no.

Y hoy, después de toda esa via crucis, he visto el cielo en Windows: DDEV corriendo dentro de WSL2. Qué locura, qué bien va. Eso sí, he visto cómo mi máquina se ha puesto a consumir 50 de mis 64GB de RAM como si nada, así que tampoco es que sea gratis del todo, pero al menos no se me cae cada dos minutos.

La curva de entrada es suave. Necesitas ir aprendiendo comandos, sí, pero son bastante sencillos, y si ya te manejas con WP-CLI, te vas a manejar con esto sin sudar. Encima trae hasta una mini interfaz gráfica dentro para lo básico.

Este post lo escribo sobre todo como recordatorio para mí mismo, porque tiene toda la pinta de que me voy a quedar trabajando en local con este montaje una buena temporada. Aquí dejo todo el proceso, de principio a fin, por si a alguien más le sirve o si dentro de seis meses se me olvida cómo iba esto (que seguro).

Requisitos antes de empezar

  • WSL2 activado, con Docker Desktop integrado.
  • Docker Desktop con la integración de WSL2 habilitada.
  • DDEV instalado (choco install ddev o el instalador oficial).
  • Trabajar dentro del filesystem de WSL2, no en C:\Users\.... Esto es importante, si trabajas desde el lado Windows del filesystem vas a notar una lentitud horrible, justo el tipo de problema del que estoy intentando escapar.

Preparar y arrancar el proyecto

mkdir mi-proyecto
cd mi-proyecto
# Copiar aquí el WordPress exportado (wp-admin, wp-content, wp-includes, wp-config.php, index.php...) o haz pull de tu proyecto

ddev config --project-type=wordpress --docroot=. --create-docroot
ddev start

Si tu WordPress vive en una subcarpeta (tipo app/public, que es lo típico si vienes de Local), ajusta el --docroot para que apunte ahí. Pero si quieres empezar desde cero, puedes poner los ficheros en esa misma raíz.

Importar base de datos y archivos

# Base de datos
ddev import-db --file=/ruta/a/mi-base-de-datos.sql

# Archivos subidos por usuarios (si no vinieron ya con el código)
ddev import-files --source=/ruta/a/wp-content/uploads

Corregir las URLs antiguas en la base de datos

ddev wp option get siteurl
ddev wp option get home

ddev wp search-replace 'https://url-vieja.com' 'https://mi-proyecto.ddev.site'

Revisa también que en tu wp-config.php no tengas WP_HOME o WP_SITEURL con la URL antigua puesta a fuego, porque si es así, el search-replace de la base de datos no va a servir de nada.

El tema del prefijo de tablas

DDEV genera un wp-config-ddev.php (marcado como #ddev-generated, así que se puede sobrescribir en cada restart) que fija el prefijo así:

$table_prefix = getenv('DB_PREFIX') ?: 'wp_';

Si tu proyecto usa un prefijo distinto de wp_ (a mí me pasa con proyectoa_, por ejemplo), configúralo como variable de entorno de DDEV, así te persiste entre restarts en vez de tener que andar tocándolo a mano cada vez:

ddev config --web-environment-add=DB_PREFIX=proyectoa_
ddev restart

Y para comprobar que ha quedado bien puesto:

ddev exec env | grep DB_PREFIX

Diagnóstico de errores 404 (que pueden que te salten)

Hay varios tipos, y cada uno apunta a un sitio distinto:

  • 404 tipo «Nginx» (sin estilo, texto plano): te falta el index.php en el docroot que configuraste. Revisa ddev describe y corrige el --docroot.
  • 404 con el estilo del tema de WordPress: normalmente es cosa de permalinks o de que la base de datos no se importó bien del todo.
  • Confirmar que las tablas se importaron: ddev mysql -e "SHOW TABLES;"
  • Revisar logs: ddev logs -s web

Y el caso raro que a mí me tocó vivir: el «Laravel Herd 404 Site not found». Esto pasa porque Laravel Herd y el router de DDEV (Traefik) se pelean por el puerto 80/443, los dos quieren ser los que mandan ahí. Cierra por completo todo los programas del mismo estilo como WordPress Studio, Local, DEVKinsta e, incluso, Cursor.

Las soluciones, de más simple a más definitiva:

  • Pausar o cerrar Herd mientras trabajas con DDEV, la opción más rápida.
  • Comprobar qué está ocupando los puertos: netstat -ano | findstr ":80" o ":443" desde PowerShell como admin.
  • Cambiar los puertos del router de DDEV:
  ddev config --router-http-port=8080 --router-https-port=8443
  ddev restart
  • Si DDEV va a ser tu herramienta principal a partir de ahora, plantéate directamente desinstalar Herd o cualquier sistema que uses para trabajar con múltiples proyectos.

Plugins que te pueden liar en local

Cuando migras una base de datos de producción, hay plugins que se ponen tontos en local:

  • Los de seguridad (firewall, 2FA, bloqueo por dominio o IP) pueden darte 403/404 porque no reconocen el dominio .ddev.site.
  • Los de optimización o CDN de imágenes a veces desactivan los editores de imagen nativos de WordPress, porque esperan que el redimensionado lo haga un servicio externo que en local, obviamente, no existe.
ddev wp plugin list --status=active
ddev wp plugin deactivate <slug>

WP-CLI con DDEV

ddev wp <comando>          # ejecutar un comando WP-CLI directamente
ddev ssh                   # entrar al contenedor y usar "wp ..." sin prefijo

Los más típicos:

ddev wp core version # Versión actual del wp
ddev wp option get siteurl # Obtener la URL 
ddev wp plugin list # Listar los plugins
ddev wp plugin deactivate <slug> # Desactivar un plugin
ddev wp cache flush # Limpiar la cache
ddev wp transient delete --all # Limpiar los transients
ddev wp rewrite flush # Forzar la limpieza de los enlaces permanentes
ddev wp search-replace 'url-vieja' 'url-nueva' # Cambiar la URL antigua por la nueva

Certificados SSL

DDEV gestiona los certificados automáticamente con mkcert.

ddev restart                    # suele regenerar solo si detecta un problema
ddev stop && ddev start         # forzar la regeneración

mkcert -install                 # reinstalar la CA en el almacén de confianza

Si el problema persiste:

ddev poweroff
rm -rf ~/.local/share/mkcert
mkcert -install
ddev start

Nota importante para Windows + WSL2: los almacenes de confianza de Windows y de WSL2 son distintos entre sí. Si el navegador de Windows no confía en el certificado aunque dentro de WSL2 todo esté bien, puede que tengas que ejecutar mkcert -install también desde el lado de Windows (PowerShell), o compartir la CA entre los dos entornos.

Chuleta de comandos rápidos

ddev describe                  # estado y URLs del proyecto
ddev launch                    # abrir el proyecto en el navegador (URL correcta)
ddev ssh                       # entrar al contenedor web
ddev logs -f -s web            # logs en vivo del servidor web
ddev mysql -e "SHOW TABLES;"   # comprobar tablas de la BD
ddev import-db --file=...      # importar base de datos
ddev import-files --source=... # importar archivos subidos
ddev snapshot                  # snapshot de la BD
ddev xdebug on|off             # activar/desactivar Xdebug
ddev poweroff                  # apagar todo sin perder datos
ddev list                      # listar todos los proyectos DDEV

Después de tantos meses dando tumbos entre Local, WordPress Studio y DevKinsta, esto es lo primero que me ha hecho sentir que trabajar en local en Windows no tiene por qué ser un castigo. Sí, se come la RAM que da gusto, pero al menos ahora es rápido y no se me cae solo cada dos por tres.