Fundaia

Entrar Empezar

Dominios

Esta guía explica cómo se publica un servicio en internet: el host que genera la plataforma, un dominio tuyo y qué hace la pasarela con cada petición.

Público o privado

Todo servicio nace privado. Sus vecinos del proyecto lo alcanzan siempre por su nombre (postgres:5432, api:8080), pero nada de fuera de la máquina. Publicarlo es un interruptor: en la pestaña Dominios, Además, accesible desde internet, o desde la terminal:

fundaia expose tienda api          # público: si no tenía host, se genera uno
fundaia expose tienda api --off    # privado otra vez

Hacerlo privado apaga sus hosts y retira sus registros DNS, pero los recuerda: al volver a hacerlo público, un dominio tuyo vuelve tal cual, sin teclearlo otra vez. A un servicio privado no se le pueden añadir hosts.

Host generado

Al publicar un servicio se le genera <proyecto>-<servicio>.fundaia.com, que funciona al momento porque un registro comodín de la zona ya lo cubre. Se puede generar otro con fundaia domains add tienda api.

Algunas etiquetas las usa la propia plataforma (infrastructure, orchestrator, api, www…) y se rechazan como primera parte de un host, también en un dominio propio: api.midominio.com no se acepta, app.midominio.com sí.

Tu propio dominio

fundaia domains add tienda api app.midominio.com

En tu proveedor de DNS, un solo registro:

TipoNombreValor
CNAMEappcname.fundaia.com

El nombre es la etiqueta sola (app), no el host entero: app.midominio.com en ese campo produciría app.midominio.com.midominio.com.

En la raíz del dominio (midominio.com, sin subdominio) un CNAME no vale: usa el ALIAS, ANAME o «CNAME aplanado» que ofrezca tu proveedor, o publica en un subdominio.

Los pasos, y cuánto tardan

La pantalla dibuja el progreso y fundaia domains list lo imprime. Avanza solo, sin recargar:

EstadoQué pasa
Esperando DNSLa plataforma aún no ve tu registro. Lo busca por su cuenta cada poco
Emitiendo certificadoEl registro ya está; el certificado se está emitiendo. Suele ser cuestión de minutos: no cambies el registro
ActivoSirviendo con TLS
Ha falladoEl mensaje dice por qué

Comprobar ahora en la pantalla, o fundaia domains verify <id>, fuerza la comprobación, para cuando acabas de arreglar una errata.

Cuántos

Cada plan incluye un número de dominios propios (ver Facturación), y la instancia puede tener además un tope global; el dominio que lo pasa se rechaza con el motivo. Los hosts generados no cuentan.

Quitar un dominio

fundaia domains remove <id>

Deja de responder en el acto; la plataforma borra también su registro DNS si lo creó ella.

Mantenimiento y contraseña

Dos cosas que la pasarela responde antes de llegar al servicio, sin reiniciar nada y desde la siguiente petición. Están en Ajustes → Acceso de un servicio público.

  • Modo mantenimiento. Cada visitante ve una página de «volvemos enseguida» (un 503 con Retry-After) con tu mensaje, en claro u oscuro según su sistema. El servicio sigue en marcha y no se despierta, así que puedes migrar datos o revisar algo con calma. Un aviso encima de las pestañas lo recuerda y lo apaga con un clic.
  • Contraseña. El navegador pide usuario y contraseña (HTTP Basic) antes de enseñar nada: útil para un staging, una demo o una herramienta interna. La contraseña se guarda con bcrypt, nunca en claro, y el servicio no la ve: la pasarela la quita antes de reenviar. Una API que lea su propia cabecera Authorization no funcionará detrás.
fundaia maintenance tienda web --message "Volvemos a las 18:00"
fundaia maintenance tienda web --off
fundaia protect tienda staging-web --user equipo     # pide la contraseña sin mostrarla
fundaia unprotect tienda staging-web

Con MCP: set_maintenance, protect_service y unprotect_service. Ninguna de las dos se copia al crear otro entorno.

Direcciones IP permitidas y límite de peticiones

Otras dos decisiones de la pasarela, en el mismo Ajustes → Acceso y con el mismo efecto inmediato: se aplican desde la siguiente petición, sin reiniciar nada.

  • Direcciones IP permitidas. Una lista de direcciones o redes, en IPv4 o IPv6 y en notación CIDR (203.0.113.7, 198.51.100.0/24, 2001:db8::/32), de hasta 100 entradas. Solo ellas llegan al servicio; cualquier otra recibe un 403, y también quien llega sin una dirección conocida. Es la primera comprobación de todas: alguien de fuera de la lista no ve ni la página de mantenimiento ni la petición de contraseña, y nunca despierta un servicio dormido. Útil para un panel interno, un staging que solo debe ver la oficina o un servicio detrás de una VPN.
  • Límite de peticiones por IP. Cada dirección puede hacer como mucho N peticiones por minuto; las demás reciben un 429 con Retry-After, sin despertar el servicio ni servir nada de la caché. Se admite una ráfaga de N y el cupo se rellena a ritmo constante. Una dirección IPv6 cuenta por su red /64, que es lo que suele tener una sola casa u oficina. Sirve contra un bot o un script que se ha quedado en bucle; no sustituye a una protección contra ataques de denegación de servicio.

La dirección es la que escribe el borde de la plataforma (el túnel de Cloudflare o el ingress propio), nunca un X-Forwarded-For que el visitante pueda inventarse.

fundaia allow tienda panel 203.0.113.7 198.51.100.0/24   # la lista queda exactamente así
fundaia allow tienda panel 2001:db8::/32 --add           # añade sin quitar las demás
fundaia allow tienda panel --list                        # qué hay ahora, y el límite
fundaia allow tienda panel --clear                       # vuelve a entrar cualquiera
fundaia ratelimit tienda api 600/min
fundaia ratelimit tienda api off

Con MCP: set_ip_allowlist (una lista vacía la quita) y set_rate_limit (perMinute: null lo quita). Cada cambio queda en el historial del proyecto, y las peticiones que la pasarela rechaza por una u otra razón aparecen en la pestaña Peticiones (ver Registros, métricas y avisos). Tampoco se copian al crear otro entorno.

Reglas de la pasarela

Lo que la pasarela contesta o añade sin llegar al servicio: redirecciones, cabeceras de respuesta, CORS, rutas a otros servicios y páginas de error. Están en Ajustes → Reglas de un servicio público, se comprueban mientras escribes y se aplican desde la siguiente petición, sin reiniciar nada. Cada cambio queda en el historial del proyecto.

El orden en la puerta es: la lista de direcciones IP, las redirecciones, el preflight de CORS, el mantenimiento, el límite de peticiones y la contraseña. Una redirección o un preflight no gastan cupo ni piden contraseña (un navegador nunca manda credenciales en un preflight), y nunca despiertan un servicio dormido.

Redirecciones

  • De un host a otro: de uno de los hosts del servicio (tienda.es, o el generado) a otro host, conservando la ruta y la consulta: https://tienda.es/carrito?id=7 → https://tienda.com/carrito?id=7. El host de origen tiene que estar ya en Dominios.
  • De una ruta: exacta (/viejo → /nuevo) o con prefijo (/blog/* → https://blog.tienda.com/:splat, donde :splat es lo que cubrió el *). La consulta pasa al destino salvo que el destino traiga la suya. Una ruta exacta va antes que un prefijo, y gana el prefijo más largo.
  • Códigos 301 (por defecto), 302, 307 y 308. Un 301/308 se puede guardar una hora en el navegador; un 302/307 no se guarda.

No se acepta una redirección que se llamaría a sí misma (/blog/* → /blog/:splat) ni una cadena de hosts (a → b y b → c: manda a directamente a c).

fundaia redirects add tienda web tienda.es tienda.com
fundaia redirects add tienda web '/blog/*' 'https://blog.tienda.com/:splat' --status 308
fundaia redirects list tienda web
fundaia redirects rm tienda web /viejo

Cabeceras de respuesta y CORS

  • Cabeceras que se añaden a cada respuesta: solo si el servicio no la pone, o siempre, sustituyendo la suya. El botón Cabeceras de seguridad (o fundaia headers security) añade Strict-Transport-Security, X-Content-Type-Options: nosniff, Referrer-Policy, X-Frame-Options: SAMEORIGIN y Content-Security-Policy: frame-ancestors 'self' donde falten. También van en las páginas de la propia pasarela (mantenimiento, contraseña, errores), aunque ahí nunca sustituyen sus cabeceras: un 401 sigue pidiendo la contraseña y un mantenimiento sigue sin guardarse en ninguna caché. Set-Cookie, las de CORS y las que describen la conexión no se configuran aquí, y quien no pasa la lista de IPs no recibe ninguna.
  • CORS: los orígenes que pueden llamar desde un navegador (https://tienda.com, https://*.tienda.com para sus subdominios, o *), los métodos, las cabeceras que puede mandar y leer, las credenciales y cuánto recuerda el navegador la respuesta. La pasarela contesta el preflight (OPTIONS) con un 204, o un 403 a un origen que no está, y pone las cabeceras en cada respuesta en lugar de las del servicio. Con credenciales hay que nombrar los orígenes.
fundaia headers security tienda web
fundaia headers set tienda web X-Frame-Options DENY --override
fundaia cors tienda api --origin https://tienda.com --origin 'https://*.tienda.com' --credentials
fundaia cors tienda api --off

Rutas a otros servicios

Un prefijo de los hosts de un servicio lo atiende otro servicio público del mismo entorno: tienda.com/api → api. Gana el prefijo más largo; el resto sigue yendo al propio servicio. La petición llega al otro servicio como si se le pidiera por su propio host: se despierta si dormía, cuenta para sus métricas y aparece en su pestaña Peticiones. Lleva X-Forwarded-Host con el host que escribió el visitante y, si se quita el prefijo (/api/pedidos → /pedidos), X-Forwarded-Prefix con lo que se quitó. Los WebSockets también pasan.

La puerta es primero la del host (su lista de IPs, su mantenimiento, su contraseña) y después la del servicio de destino; las redirecciones, las cabeceras y el CORS son las del host. Si los dos piden contraseña, tiene que ser la misma. Una ruta no encadena con las rutas del otro servicio.

Una ruta a un servicio que se ha borrado o que ya no es público se ve rota en la pantalla y en fundaia routes list, y la pasarela contesta 502 en ese prefijo: nunca la manda a otro sitio.

fundaia routes add tienda web /api api --strip
fundaia routes list tienda web
fundaia routes rm tienda web /api

Páginas de error y de espera

  • Cuando la pasarela no consigue respuesta del servicio, un navegador ve una página con la marca de la plataforma: 502 si no responde, 503 si no pudo arrancar, 504 si tarda más de dos minutos. Cada servicio puede poner su propio HTML, de hasta 64 KB, para cada una. Una petición que no pide HTML (una API, curl) sigue recibiendo el texto de siempre, y lo que conteste el propio servicio, aunque sea un 502, nunca se cambia.
  • Página de espera: un navegador que llega con el servicio dormido la ve al momento, mientras despierta, y se recarga sola cada 3 segundos hasta que responde. Si despertar falla, la siguiente recarga enseña la página del 503 en lugar de prometer otra vez.
fundaia error-page tienda web 502 caido.html
fundaia error-page tienda web 503 --default
fundaia error-page tienda web waiting              # encendida, con la página de la plataforma
fundaia error-page tienda web waiting --off

Probar una dirección

Debajo de las reglas, Probar una dirección dice qué haría la pasarela con una dirección, un método y un origen, con lo que estás editando y antes de guardarlo: si redirige y adónde, si contesta un preflight, a qué servicio y con qué ruta llega, y con qué cabeceras. Lo mismo, con lo guardado:

fundaia rules tienda web --try https://tienda.es/blog/hola
fundaia rules tienda api --try /pedidos --method OPTIONS --origin https://tienda.com

Con MCP: read_gateway_rules, update_gateway_rules (cada parte que pasas sustituye esa parte entera) y preview_gateway_rules.

Al copiar un entorno las reglas viajan con cada servicio, menos las redirecciones de host y las que mandan a un host del entorno de origen: la copia no tiene esos dominios, y no debe mandar a sus visitantes a producción. Una ruta apunta al servicio del mismo nombre en el entorno nuevo.

Qué hace la pasarela

Toda petición pública pasa por la pasarela de la plataforma, que enruta por el Host y además:

  • Despierta el servicio si estaba dormido y retiene la petición mientras arranca; ver Dormir y despertar.
  • Sigue sirviendo con el contenedor anterior mientras se construye un despliegue nuevo.
  • Quita sus propias cookies de sesión antes de reenviar, así que un servicio publicado bajo fundaia.com nunca ve la credencial de la plataforma. Las cookies de tu aplicación pasan intactas.
  • Reenvía WebSockets.
  • Guarda en caché, si lo activas en Ajustes → Caché, las respuestas de recursos estáticos (JavaScript, CSS, imágenes, fuentes, JSON). Nunca HTML, ni respuestas con Set-Cookie, ni peticiones que llevan credenciales. Un Cache-Control del servicio manda sobre el tiempo configurado.
  • Responde la página de mantenimiento o pide la contraseña si lo has activado; ver Mantenimiento y contraseña.
  • Deja fuera las direcciones que no están en la lista y frena a quien pasa del límite de peticiones por minuto; ver Direcciones IP permitidas y límite de peticiones.
  • Redirige, contesta el preflight de CORS, añade cabeceras, manda un prefijo a otro servicio y enseña las páginas de error y de espera que hayas configurado; ver Reglas de la pasarela.
  • Anota las últimas 500 peticiones de cada servicio para la pestaña Peticiones.
  • Cuenta peticiones, respuestas y latencia para las métricas.

Los contenedores solo escuchan en 127.0.0.1: lo único que llega desde la red es lo que pasa por la pasarela.