Solución de problemas de despliegue
Cuatro fallos se comen el primer despliegue. Ejecuta el preflight antes que nada — nombra la mala configuración en lugar de hacerte adivinar:
pnpm import:self-host-checkdocker run --rm --env-file .env ghcr.io/capitality-io/mildport-aio \ bun dist/cli/self-host-check.jsEn Kubernetes, helm test mildport es la misma comprobación dentro del clúster.
Las imágenes no hacen pull (ImagePullBackOff)
Sección titulada «Las imágenes no hacen pull (ImagePullBackOff)»Las imágenes viven en ghcr.io/capitality-io/* y son privadas. Un pod en
ImagePullBackOff / ErrImagePull es casi siempre una de estas:
-
Acceso aún no concedido. Pídelo en Self-hosting de tu cuenta para el usuario GitHub que hará pull. Las concesiones pendientes parecen una contraseña mala.
-
El nodo no ha iniciado sesión. Un
docker loginen el portátil no ayuda al clúster.Terminal window echo $GITHUB_TOKEN | docker login ghcr.io -u <your-github-username> --password-stdinEn Kubernetes esas credenciales van en un
imagePullSecret:Terminal window kubectl create secret docker-registry ghcr-pull \--docker-server=ghcr.io \--docker-username=<your-github-username> \--docker-password=$GITHUB_TOKEN \-n mildportimagePullSecrets:- name: ghcr-pull -
Registro equivocado. Publicamos en GHCR, no en Docker Hub. Si los values aún dicen
capitality/mildport, el pull nunca funcionará. Véase Acceso a imágenes.
Cada import devuelve 401
Sección titulada «Cada import devuelve 401»401 significa que la clave de licencia no verificó. El cuerpo parece
{ "status": "error", "code": "UNAUTHORIZED", "reason": "…" }. El reason es el arreglo:
reason |
Qué significa | Qué hacer |
|---|---|---|
missing |
No hay cabecera Authorization: Bearer … |
Pasa la clave de Licencias |
not_configured |
El motor no tiene IMPORT_LICENSE_PUBLIC_KEY |
Pega la clave pública de Self-hosting; reinicia |
expired |
El exp de la clave está en el pasado |
Regenera en Licencias; la antigua vale hasta caducar |
revoked |
El id de licencia está en IMPORT_LICENSE_REVOKED_IDS |
Quítalo, o usa una clave nueva |
malformed / bad_signature / bad_attestation |
Clave truncada, espacios de más, o de otro emisor | Cópiala de nuevo; no emitas una tú |
Una clave pública ausente es también un fallo de readiness (checks.license: missing) —
el motor responde /health y aun así da 401 a cada import.
No es un 401:
403 ORIGIN_NOT_ALLOWED— la clave es válida, pero se emitió con una lista de orígenes que no incluye esta página. Regenera con los orígenes correctos (o una lista vacía). Esto no es CORS.- CORS en el navegador — la petición nunca recibe un cuerpo JSON. Siguiente sección.
Confirma una clave contra un motor en marcha con
GET /api/import/v1/license/verify. Más sobre claves:
Licencias.
El widget no hace nada (CORS)
Sección titulada «El widget no hace nada (CORS)»La imagen de producción (NODE_ENV=production) rechaza toda llamada de navegador
cross-origin cuando ALLOWED_ORIGINS está vacío — incluido http://localhost:5173. El
localhost de modo dev solo se permite fuera de producción.
Pon el origen exacto de la página que incrusta el widget, esquema y puerto incluidos:
ALLOWED_ORIGINS=https://app.example.com,http://localhost:5173En Helm es app.allowedOrigins. Los llamadores servidor a servidor (sin cabecera Origin)
no se ven afectados; omite la variable solo si nada en un navegador habla con el motor.
La lista de orígenes de la clave (403 ORIGIN_NOT_ALLOWED) es un segundo candado, aparte.
CORS decide si el navegador puede hablar; la clave decide si ese origen puede usar esta
clave.
El pod nunca pasa a Ready
Sección titulada «El pod nunca pasa a Ready»GET /health es liveness. Devuelve {"status":"ok","service":"mildport",…} en cuanto
el proceso puede responder, antes de Mongo o las licencias. La sonda de readiness del chart
es GET /health/ready. Un pod que vive pero nunca es Ready está fallando esa sonda.
curl -i localhost:8090/health/ready503 con cuerpo:
{ "status": "not_ready", "service": "mildport", "checks": { "mongo": "down", "license": "missing" }}| Check | down / missing significa |
Arreglo |
|---|---|---|
mongo |
El motor no puede hacer ping a Mongo (URI mala, network policy, Mongo caído) | MONGO_CONNECTION_STRING; espera a Mongo; helm test |
license |
Sin clave pública y modo desarrollo apagado | IMPORT_LICENSE_PUBLIC_KEY de la página Self-hosting |
license: dev-mode está ready — las claves sintéticas funcionan, y no deberías enviar eso.
Que los sidecars estén caídos no hace fallar la readiness. URLs de decode sin definir
solo significan que esas familias de archivo se rechazan. Un PDF que da 503 mientras
/health/ready es 200 es una URL de sidecar, no un pod atascado.
Siguiente: Tu primer import · Configuración · Acceso a imágenes