Guarda los datos en las bases de datos del stack
Pon los datos que importan en las bases de datos del stack (Postgres, MySQL, MongoDB o Redis), no en archivos bajo/app. Las bases de datos entran en snapshots, se restauran, se revierten y se actualizan por la plataforma, y nunca se cierran, así que se comportan igual en una plantilla cerrada. Un archivo en /app de una plantilla cerrada es invisible para el usuario y es responsabilidad tuya.
Cuando el software ofrece una opción, exponla: n8n deja al usuario elegir entre Postgres gestionado o el SQLite integrado mediante una pregunta, y usa sets para activar o desactivar la base de datos. Consulta Placeholders e inputs.
/app es el único disco persistente
El sistema de archivos raíz es de solo lectura. /app es el directorio de trabajo y el HOME de la app, y el único lugar donde los archivos sobreviven a un reinicio, a un despliegue y a un snapshot. Apunta todo lo que escribe el software ahí con una variable:
VOLUME en un Dockerfile se ignora. No dependas de ninguna otra ruta para el estado: el resto del sistema de archivos es de solo lectura.
/app/.vertra/ está reservada para la plataforma (certificados de bases de datos). Nunca escribas ahí ni incluyas archivos ahí.
Ejecuta como uid 1000
Los procesos se ejecutan como el usuario sin privilegios con uid 1000, sin nuevos privilegios y con raíz de solo lectura. El software que debe arrancar como root, cambiar de usuario al arrancar (usermod, chown de rutas del sistema), usar un sistema init como PID 1 o escribir en /opt o /var no funciona tal cual. Adáptalo:
- Usa una imagen o un Dockerfile que arranque como usuario normal y guarde sus datos bajo
/app. - Elimina los pasos de arranque que necesiten root.
- Prueba con raíz de solo lectura y uid 1000 antes de publicar; consulta Validar y probar.
Define el puerto
Para un servicio de imagen, defineport con el puerto en el que escucha el software (el EXPOSE de la imagen). Un servicio de código sigue las mismas reglas que cualquier app (consulta Aplicaciones) y no puede definir port. No definas PORT en env: la plataforma lo controla, y el manifiesto se rechaza con forbidden_env si lo intentas.
Escribe un healthcheck honesto
El healthcheck decide cuándo el asistente dice «listo». Elige una ruta que responda solo cuando el software realmente pueda atender:- Prefiere una ruta de readiness a una de liveness. El
/healthzde n8n se abre antes de que terminen sus migraciones, así que su plantilla usa/healthz/readiness, que espera a la base de datos. - Define
timeoutcon el primer arranque más lento que hayas medido, con margen. Las migraciones y la descarga de imágenes hacen el primer arranque más lento que los siguientes. - Un servicio sin HTTP (un bot, un worker) omite
path: se aplica la comprobación de listo habitual y un proceso que termina aparece como un despliegue fallido.
Nunca pongas un secreto en la plantilla
Una plantilla se copia, se comparte y, en el catálogo público, lo lee todo el mundo.- Genera lo que el usuario no necesita saber:
{{secret:48}}, un nombre desecretsdeclarado o una pregunta congenerate. - Pregunta lo que solo tiene el usuario, como el token de un bot, con una pregunta
secret. El valor llega a la app cifrado y no se guarda en la plantilla. - Oculta lo que te pertenece (una clave de licencia) con
env_hidden, en una plantilla privada cerrada. - No dejes archivos
.env*, claves privadas ni tokens en el código. La plataforma rechaza una subida de código que los contenga (TEMPLATE_SECRET_IN_SOURCE), y el validador rechaza una variable cuyo nombre parezca un secreto (*_KEY,*_TOKEN,*_SECRET,PASSWORD…) con un valor literal (secret_in_manifest).
Variables que controla la plataforma
Algunos nombres son de la plataforma, y un manifiesto que los define se rechaza conforbidden_env: PORT, HOST, NODE_ENV, RACK_ENV, RAILS_ENV, APP_ID, PATH, HOME, USER, SHELL, además de LD_PRELOAD, LD_LIBRARY_PATH, LD_AUDIT, NODE_OPTIONS y cualquier nombre que empiece por DYLD_. La comparación ignora mayúsculas y minúsculas. Pasa los ajustes al software mediante sus propias variables.
Fija lo que publicas
- Fija una imagen por digest (
name@sha256:...). Una plantilla pública con solo una etiqueta se rechaza coninvalid_source, y una versión fijada significa que todos los que usan una versión concreta de tu plantilla obtienen el mismo software. - Fija las versiones de runtime y de dependencias en las plantillas de código, y haz commit del lock file.
- Mantén la memoria honesta:
ram.mines lo que el software necesita para arrancar con las respuestas por defecto, yrecommendedes lo que ejecutarías en producción.
Escribe la documentación que necesita un usuario
ElREADME.md y la carpeta opcional docs/ se muestran en la página de la plantilla. Explica qué crea la plantilla, qué debe hacer el usuario después del despliegue (crear la primera cuenta, invitar a un bot) y dónde viven los datos. Pon también los primeros pasos en los outputs, donde el usuario los ve cuando termina el despliegue.
Relacionado
Permisos
Qué puede cambiar el usuario después.
Ajustes de despliegue
Cuándo bloquear blue-green en off.