# Fully Booked - Implementación Dockerizada con DigitalOcean y Cloudflare

Company: Fully Booked
Service: Ingeniería DevOps
Period: 2023-04 - 2025-06
Tech: Docker, DigitalOcean, Cloudflare, DNS, SSL Certificates, Caddy
Web: https://fully-booked.uk/
Canonical: https://webanion.com/es/portfolio/fully-booked-dockerized-deployment-with-digital-ocean-and-cloudflare

Fully Booked salió como cinco servicios Docker en un único droplet de DigitalOcean detrás de Cloudflare, para que un equipo muy pequeño pudiera operar un marketplace que gestiona depósitos. Un solo repositorio construía cada imagen, un archivo compose y un Makefile reducían una publicación a pull, build y up, un proxy Caddy se encargaba de los certificados y las cabeceras de seguridad, y Playwright generaba en el servidor el PDF de cada presupuesto y factura. Como los servicios eran independientes desde el principio, más tarde pasaron a un clúster de Kubernetes autoalojado sin reconstruir nada.

## La historia completa

La infraestructura que permitió a un mercado que cobra depósitos llevar cinco servicios con un equipo pequeño y sin sorpresas.

### Un mercado que guarda depósitos no puede caerse

<p>Fully Booked cobra los depósitos de los clientes, envía a los operadores sus ganancias y entrega los documentos de los que dependen ambas partes. Aquí una caída no es una simple molestia: el cliente que no puede pagar reserva en otro sitio, y el operador que no puede abrir un presupuesto pierde el trabajo.</p><p>La plataforma son cinco servicios, una web para clientes, una web para operadores, un panel de administración, un sitio de documentación y un único backend, construidos y mantenidos por un equipo muy pequeño. El despliegue tenía que ser lo bastante sencillo para llevarlo a mano y lo bastante sólido para confiar en él.</p>

### Cinco servicios, un repositorio, un comando

<p>Cada servicio se publica como su propia imagen de Docker desde un único repositorio. Las cuatro webs se compilan en pequeños servidores estáticos, el backend en NestJS lleva la API GraphQL, y MongoDB y los archivos subidos viven en volúmenes persistentes. Un archivo compose los conecta en una red privada, y un Makefile reduce cada lanzamiento a pull, build y up.</p>

### Cloudflare delante, con dos excepciones deliberadas

<p>Cloudflare gestiona el DNS de cada subdominio y hace de proxy de las webs públicas para la caché, los certificados y la protección. Dos registros quedan directos a propósito: la web de operadores, para que Apple pueda leer el archivo que permite que los enlaces abran la app, y la API, para que los webhooks de pago de Square lleguen sin bloqueos.</p><p>Equivocarse en cualquiera de los dos rompería los enlaces profundos de cada PDF o impediría que los pagos se confirmaran, y por eso ambos están documentados junto a la tabla de DNS.</p>

### Un proxy inverso que se encarga de la seguridad

<p>Un contenedor de Caddy en el borde emite los certificados automáticamente, comprime las respuestas, redirige cada dirección con www, añade a la API las cabeceras de strict transport, frame y content type, y sirve los archivos de asociación de la app con el content type que esperan las tiendas.</p>

### Documentos generados en producción

<p>Cada presupuesto, carta de cancelación, factura, confirmación de reserva y hoja de conductor se genera en el servidor con Playwright, que corre dentro de la imagen del backend. Conseguir instalar un navegador sin interfaz dentro de un contenedor de producción fue lo más difícil de todo el trabajo, y es lo que permite a un operador enviar un PDF impecable desde el móvil en segundos.</p>

### De un droplet a un clúster

<p>El droplet sostuvo la plataforma durante sus primeras fases. Cuando la factura mensual y los límites de una sola máquina empezaron a pesar, las mismas imágenes pasaron a <a href="/portfolio/fully-booked-zero-downtime-migration-to-self-hosted-kubernetes">un clúster de Kubernetes autoalojado sin tiempo de inactividad</a>, algo posible porque desde el principio se habían construido como servicios independientes.</p><p>Para el fundador supuso no reconstruir nada ni sufrir caídas, y para operadores y clientes nada cambió, salvo que todo siguió funcionando. Los servicios en sí se cuentan en <a href="/portfolio/fully-booked-all-in-one-smart-booking-solution">la historia de Fully Booked</a>.</p>
