Table of Contents
- Trampas del entorno
- Ya NO aplican — eran del jail de CDMON [verificado]
- Siguen vigentes
- Cloudflare bloquea curl y headless [verificado]
- docker cp anida directorios en silencio [verificado]
- hub-proxy nunca devuelve 404
- Charset: el CLI de MySQL conecta en latin1
- La categoría de la carta está partida en tres
- Heredadas, sin re-verificar
- Trampas de herramienta (agentes en WSL)
- wsl -d Ubuntu -- bash -lc '…' rompe bucles y rutas
- wp eval-file y las globales
- Regex en PHP sobre texto español: siempre /u
- La API de wiki de Gitea
- Trampas de método
Trampas del entorno
Consolidado por Opix el 2026-08-12 desde las skills de Hermes, filtrado contra el estado real del servidor tras el cutover a Hetzner del 2026-08-03.
Lo marcado [verificado] se comprobó contra la máquina ese día. El resto es documentación heredada sin re-verificar: trátalo como pista, no como hecho.
Ya NO aplican — eran del jail de CDMON [verificado]
Estas cuatro condicionaban buena parte de los procedimientos antiguos y hoy son falsas. Si las lees en Limitaciones-servidor-prod o en las skills de Hermes, están obsoletas.
| Trampa vieja | Realidad en Hetzner |
|---|---|
proc_open() deshabilitado |
disable_functions vacío, funciona |
No hay mysqldump ni stat |
stat en el contenedor WP; mysqldump 8.4.10 en el de MySQL |
php y grep rotos (GLIBC) |
PHP 8.3.31 y grep correctos |
scp/sftp no funcionan |
scp y docker cp normales |
Importa más de lo que parece: varios procedimientos daban rodeos (subir ficheros con
ssh 'cat > ruta', backups selectivos post a post, usar wp para todo porque php
estaba roto) que hoy son innecesarios. Copiarlos tal cual hereda los rodeos.
Lo que sí falta hoy dentro del contenedor de WordPress: wp, mysql,
mysqldump, git, python3. Sí hay: php, curl, grep, stat, tar.
Siguen vigentes
Cloudflare bloquea curl y headless [verificado]
403 con cf-mitigated: challenge, también desde el propio servidor. Verificación
de prod siempre server-side. Ver Produccion-Hetzner-acceso.
docker cp anida directorios en silencio [verificado]
Si el destino ya existe como directorio, docker cp origen <c>:/ruta/destino crea
destino/origen. Pasó desplegando mu-plugins el 2026-08-12: acabaron en
wp-content/mu-plugins/mu-plugins/ y el lint posterior los dio por desaparecidos,
con la conclusión equivocada de que el volumen no persistía.
Dos consecuencias:
- WordPress no carga mu-plugins desde subdirectorios — solo los
.phpdel primer nivel. Un despliegue anidado no falla: queda inactivo sin avisar. - Antes de concluir "no persiste", mira el mount real:
En feadulta,
docker inspect --format '{{range .Mounts}}{{.Type}} {{.Destination}} <- {{.Source}}{{println}}{{end}}' <container> docker inspect --format 'Created={{.Created}} StartedAt={{.State.StartedAt}} RestartCount={{.RestartCount}}' <container>/var/www/htmles el volumenr2ssjifwj0r0ghyoqd528uaa_wordpress-filesy el contenedor no se recrea desde el 2026-08-03 (RestartCount=0).
Usa docker cp origen/. <c>:/destino/ para volcar contenido sin anidar.
hub-proxy nunca devuelve 404
El nginx del hub responde la portada del Hub con 200 + text/html (20.597 bytes)
para cualquier ruta desconocida. Comprueba content_type y tamaño, no solo el código.
Charset: el CLI de MySQL conecta en latin1
Columnas en utf8mb4. Siempre mysql --default-character-set=utf8mb4, o corrompe acentos.
La categoría de la carta está partida en tres
6 cartasemana → 22 carta-semana-pasada → 21 cartas-de-otras-semanas.
Buscar siempre en las tres. Ver Carta-de-la-semana.
Heredadas, sin re-verificar
- wp-cli y categorías:
wp post term set <ID> category 28asigna el término de nombre "28", no el term_id. Usar el slug. - WP_Tax_Query + Polylang:
get_posts(['lang'=>$x,'category__in'=>[$c]])generaAND 0=1. No pasarlangexplícito.get_term_by('slug',…)en idioma ≠ ES devuelvefalse: usar$wpdb->get_var(). - Títulos en MAYÚSCULAS en la BD (legacy Joomla);
fea_title()los normaliza en el front. Es intencional. - Single posts usan template FSE (Twenty Twenty-Five, post 42359), no Astra.
- Páginas desde CLI: HTML plano con shortcodes, nunca bloques Gutenberg.
- URLs entre entornos: local cuelga de
/fea, prod de la raíz. No copiarpost_contentsin reescribir. - IDs: los de posts ES coinciden local↔prod; los de attachments y user_meta no.
Trampas de herramienta (agentes en WSL)
wsl -d Ubuntu -- bash -lc '…' rompe bucles y rutas
Las variables se pierden, los for … in *.md se comen los argumentos y las rutas
/tmp/x.sh se traducen a rutas de Windows. Escribe el .sh por UNC
(\\wsl.localhost\Ubuntu\tmp\…) y lánzalo con bash -lc 'cd /tmp; bash x.sh'.
wp eval-file y las globales
Dentro de una función, global $X no ve las variables del script: pásalas con use.
Regex en PHP sobre texto español: siempre /u
m[áa]s o eucarist[ií]as sin el modificador u no casan: las vocales
acentuadas ocupan 2 bytes y la clase de caracteres parte el UTF-8. Costó un
diagnóstico entero equivocado el 2026-08-12.
La API de wiki de Gitea
Devuelve content_base64, no content, y da 404 con títulos acentuados aunque
el sub_url sea el que ella misma publica. Clona <repo>.wiki.git en su lugar.
(La wiki vive en el branch main; documentación antigua dice master.)
Trampas de método
- Contar en la BD antes de proponer un comando que muta. No extrapolar el alcance de un fix desde una página renderizada.
- Seguir el camino completo del dato antes de gritar "fuga a producción".
- "El dato no existe" solo vale tras seguir los enlaces, no solo los metas.
- Antes de agrupar por un meta de origen, comprobar que no haya varios: conviven
_fgj2wp_old_k2_id(K2, 18.121) y_fgj2wp_old_id(Joomla core, 9.022). - Verificar las dos mitades de una rotación: que la carta nueva entre y que la anterior salga.
- Un issue no es un diario. Si te retractas, se reescribe entero; el rastro va al canal, no al ticket.