Configurar la instancia
Esta página es para quien administra una instancia de Fundaia: quién puede entrar y qué hay que configurar en el servidor para cada integración. Cómo se instala y actualiza el código en la máquina está en deploy/README.md del repositorio, y la entrada pública (TLS, DNS) en deploy/ingress/README.md.
Quién entra
| Dueño | Miembro | |
|---|---|---|
| Cómo llega | Reclamó la instancia con el código de arranque y una passkey | Entró con GitHub |
| Cuántos | Exactamente uno | Los que se admitan |
| Qué ve | Todos los espacios y proyectos | Los espacios a los que pertenece |
El código de arranque está en ~/.orchestrator/bootstrap-code; tras la primera passkey, el registro de passkeys se cierra para siempre.
El registro está cerrado salvo que se abra: solo entran por GitHub las cuentas de ORCHESTRATOR_ALLOWED_GITHUB_LOGINS (y el dueño). Con ORCHESTRATOR_OPEN_REGISTRATION=true puede entrar cualquiera con cuenta de GitHub, y cada persona que entra puede arrancar contenedores en la máquina. Cerrarlo no echa a nadie que ya tenga cuenta.
Dónde va la configuración
En ~/.orchestrator/infra.env (permisos 600, nunca en git), que la unidad orchestrator.service carga al arrancar. Tras cambiarlo, reinicia el servicio. Toda integración cuya configuración falta se apaga sin romper nada: sin GitHub no hay botón de GitHub, sin Stripe no se cobra.
| Área | Variables |
|---|---|
| Sitio | ORCHESTRATOR_DOMAIN (dominio raíz), PORT (5273), INFRA_GATEWAY_PORT (5274) |
| Cifrado | ORCHESTRATOR_SECRET_KEYS, obligatoria: 1:<clave base64 de 32 bytes>, separadas por comas para rotar |
| Acceso | ORCHESTRATOR_OPEN_REGISTRATION, ORCHESTRATOR_ALLOWED_GITHUB_LOGINS, ORCHESTRATOR_OWNER_GITHUB_LOGIN |
| GitHub | GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRET, GITHUB_APP_SLUG, FUNDAIA_APP_ID, FUNDAIA_APP_PRIVATE_KEY, FUNDAIA_APP_WEBHOOK_SECRET |
| Correo | RESEND_API_KEY, RESEND_FROM (por defecto no-reply@<dominio>) |
| Dominios | CLOUDFLARE_ZONE_ID, CLOUDFLARE_TUNNEL_ID, CLOUDFLARE_TOKEN, INFRA_CUSTOM_DOMAIN_TARGET (por defecto cname.<dominio>), INFRA_CUSTOM_DOMAIN_LIMIT, INFRA_INGRESS_ADDRESS, INFRA_TLS_AUTHORISATION_TOKEN |
| Métricas | INFRA_PROMETHEUS_URL, INFRA_METRICS_TOKEN |
| Copias | INFRA_BACKUP_REMOTE |
| Agentes | CLAUDE_CODE_OAUTH_TOKEN (el token de Claude de los componentes del dueño), INFRA_MCP_READ_ONLY |
| Facturación | STRIPE_*, INFRA_UNGOVERNED_WORKSPACES |
| Subidas | INFRA_UPLOAD_MAX_BYTES (100 MB por defecto) |
GitHub
La OAuth App: entrar con GitHub
Registra una OAuth App en GitHub con la URL de callback exacta https://infrastructure.fundaia.com/api/auth/github/callback (una OAuth App admite una sola), y pon su client ID y un secreto recién generado en GITHUB_OAUTH_CLIENT_ID y GITHUB_OAUTH_CLIENT_SECRET. El botón aparece solo con las dos.
En esta instancia la aplicación ya está registrada en la cuenta alex28042:
| Application name | Fundaia Infrastructure |
| Homepage URL | https://infrastructure.fundaia.com |
| Authorization callback URL | https://infrastructure.fundaia.com/api/auth/github/callback |
| Client ID | Ov23li8d1QtoFtMp3vMx |
El secreto se genera en la página de la aplicación y GitHub lo enseña una sola vez: va del portapapeles a infra.env y a ningún otro sitio.
GITHUB_APP_SLUG convierte el botón de entrar en el «Install & Authorize» de la GitHub App, para que una sola autorización cubra la identidad y los repositorios.
La GitHub App: clonar, registrar despliegues y el webhook
Con FUNDAIA_APP_ID y FUNDAIA_APP_PRIVATE_KEY (el PEM, con los saltos de línea como \n), la plataforma clona cada repositorio con un permiso de solo lectura concedido por su dueño, registra los despliegues en GitHub y puede abrir pull requests del autofix.
Los permisos que la App necesita, y para qué:
| Permiso | Acceso | Para qué |
|---|---|---|
| Contents | Lectura y escritura | clonar; empujar la rama de un arreglo del autofix |
| Pull requests | Lectura y escritura | abrir el pull request del arreglo; saber quién fusionó un commit |
| Issues | Lectura y escritura | el botón «Abrir issue» y fundaia issue |
| Deployments | Lectura y escritura | apuntar cada despliegue junto a su commit |
| Commit statuses | Lectura y escritura | el estado de los workflows en cada commit |
| Metadata | Lectura | obligatorio en GitHub |
| Email addresses (cuenta) | Lectura | reconocer al autor de un commit por su correo |
Al añadir un permiso, cada instalación tiene que aceptarlo en Settings → Applications → Installed GitHub Apps; hasta entonces GitHub responde 403 a lo que lo necesita.
Para que un push llegue en segundos en vez de en el siguiente sondeo de dos minutos:
Elige un secreto
Una cadena larga y aleatoria, por ejemplo openssl rand -hex 32.
Configura el webhook de la App
En la página de la GitHub App, sección Webhook: activa Active, URL https://infrastructure.fundaia.com/api/infra/github/webhook, pega el secreto y suscribe los eventos Push, Repository (avisa de un repositorio renombrado) y Pull request (los entornos por pull request).
Dáselo a la instancia
FUNDAIA_APP_WEBHOOK_SECRET=<el secreto> en infra.env, y reinicia. Sin él, el endpoint responde 404 y los pushes siguen llegando por el sondeo.
El webhook solo avisa: la plataforma vuelve a leer la cabeza de la rama con git y aplica la misma regla de aprobación que el sondeo.
Stripe
Sin STRIPE_SECRET_KEY o sin STRIPE_WEBHOOK_SECRET la plataforma calcula el consumo para la pantalla y no cobra a nadie, que es como corre el desarrollo local.
STRIPE_SECRET_KEY=sk_live_…
STRIPE_WEBHOOK_SECRET=whsec_…
STRIPE_METER_EVENT_NAME=fundaia_consumo # por defecto
STRIPE_PRICE_BASE=price_… # el fijo del plan
STRIPE_PRICE_BASE_USAGE=price_… # el de consumo del plan
STRIPE_PRICE_PRO=price_…
STRIPE_PRICE_PRO_USAGE=price_…
STRIPE_PRICE_CREDITS_C10=price_… # un precio de pago único por paquete de crédito
STRIPE_PRICE_CREDITS_C25=price_…
STRIPE_PRICE_CREDITS_C50=price_…
STRIPE_PRICE_CREDITS_C100=price_…
INFRA_UNGOVERNED_WORKSPACES=wsp_…,wsp_… # espacios que no pagan; vacío es lo seguro
Un plan sin sus dos precios no se ofrece, y un paquete de crédito sin el suyo tampoco.
Lo que hay que montar en Stripe:
- Un medidor (
fundaia_consumo, agregaciónsum) cuya unidad es un céntimo de consumo. - Por plan, un precio fijo mensual y un precio de consumo graduado con el primer tramo a cero (900 unidades en Base, 1800 en Pro): ese tramo es el consumo incluido.
- Un producto de crédito con un precio de pago único por paquete.
- Un webhook a
/api/infra/billing/webhookconcheckout.session.completed,checkout.session.async_payment_succeeded(los pagos que se confirman días después, como SEPA) y los trescustomer.subscription.*.
Esta instancia
Cuenta acct_1U04pMBkszImu6qD, en euros.
| Producción | Sandbox | |
|---|---|---|
STRIPE_PRICE_BASE | price_1U04wjBkszImu6qDAo7Y74IM | price_1U05KyBkszImu6qDy4zHdJIy |
STRIPE_PRICE_BASE_USAGE | price_1U04yUBkszImu6qDzUIewUH6 | price_1U05KzBkszImu6qDURXDXmWX |
STRIPE_PRICE_PRO | price_1U04xEBkszImu6qDcsgXwUnv | price_1U05KzBkszImu6qDSwJgy3Ht |
STRIPE_PRICE_PRO_USAGE | price_1U04zJBkszImu6qD62CxWYw6 | price_1U05L0BkszImu6qDc35npUzl |
Para probar en local con el sandbox, sk_test_… como clave y, en vez de un webhook público:
stripe listen --forward-to localhost:5273/api/infra/billing/webhook
El whsec_… que imprime es el STRIPE_WEBHOOK_SECRET mientras dure esa sesión.
Abonar crédito a mano
El dueño puede abonar crédito de agente a un espacio sin pasar por Stripe (una prueba, una compensación). Queda en el historial como abono, distinto de una compra:
curl -X POST https://infrastructure.fundaia.com/api/infra/workspaces/<espacio>/credits/grant \
-H "Authorization: Bearer fdi_…" \
-H "content-type: application/json" \
-d '{"amountCents": 2000, "detail": "Saldo inicial"}'
Métricas
Las gráficas de la pestaña Métricas salen de un Prometheus que raspa /api/infra/metrics con un token. Sin INFRA_METRICS_TOKEN ese endpoint responde 404; sin INFRA_PROMETHEUS_URL la pestaña enseña solo las cifras del momento. La puesta en marcha está en deploy/observability/README.md.
Buscadores y vistas previas
La portada, las guías y las novedades llegan con su título, su descripción, Open Graph, datos estructurados y el texto de la página ya escrito, así que un buscador o una vista previa de Slack los leen sin ejecutar JavaScript. Quien entra con sesión recibe solo la cabecera; las pantallas de la aplicación van con noindex.
- **
/robots.txty/sitemap.xml** se generan solos, con la dirección pública de la instancia (ORCHESTRATOR_DOMAINuORCHESTRATOR_ORIGIN), y dejan fuera la API y las pantallas privadas. - **Las novedades salen de
CHANGELOG.md**, el de la raíz del repositorio, leído una vez al arrancar; en una release es el dereleases/<sha>/. Sin el fichero, la página dice que aún no hay versiones. - **
/site.webmanifest** permite instalar la web como aplicación, con los iconos de la marca.
Otras
- Dominios propios.
INFRA_CUSTOM_DOMAIN_LIMITpone un tope al número de dominios propios de toda la instancia; el que lo pasa se rechaza con el motivo. - Copias fuera de la máquina.
INFRA_BACKUP_REMOTEes un remoto dercloney una ruta (b2:fundaia-backups/nucbox); verdeploy/README.md. - MCP de solo lectura.
INFRA_MCP_READ_ONLY=truedeja en el MCP solo las herramientas que leen, para enseñar la plataforma sin dejar tocarla.