CushLabs Production Server
Tools
Production

CushLabs Production Server

Self-hosted Docker infrastructure running 6 services on a single VPS for $10.59/mo

El Problema

Running multiple production services across PaaS free tiers creates cold start latency, per-service cost scaling, and zero infrastructure visibility. This project consolidates all CushLabs services onto a single hardened VPS with Docker orchestration, automatic HTTPS, and real user monitoring — eliminating cold starts and reducing hosting to a flat $10.59/mo.

Características Principales

  • 6 Dockerized services running on a single VPS using ~386 MB of 3.7 GB RAM
  • Zero cold start latency — always-on containers replace PaaS sleep cycles
  • $10.59/mo flat vs. per-service PaaS pricing that scales with each new project
  • Bare metal to full production in 1 day with complete documentation
  • Automatic HTTPS via Caddy + Let's Encrypt across 5 subdomains
  • Self-hosted Web Vitals RUM collector tracking Core Web Vitals across all frontends

Overview

This repository orchestrates all CushLabs production infrastructure on a single Hetzner CPX21 VPS. Six Docker containers — four client-facing services, a Redis cache, and a custom Web Vitals collector — run behind Caddy reverse proxy with automatic HTTPS, consuming just 10% of available RAM.

The entire stack was migrated from Render free tier in March 2026. The migration eliminated 30-60 second cold start latency, consolidated hosting costs to a flat $10.59/mo, and gave full SSH access for debugging, monitoring, and infrastructure control.

Every change to the server is documented in a phase-by-phase setup log. The repo contains everything needed to reproduce the environment from a fresh Ubuntu install — Docker Compose definitions, Caddy configuration, environment variable templates, and the vitals collector source code.

The Challenge

  • Cold start latency: Render free tier sleeps services after 15 minutes of inactivity, causing 30-60 second wake-up times for the first request
  • Cost scaling: Each new service on a PaaS adds another billing line item — unsustainable for a growing portfolio
  • No infrastructure visibility: PaaS abstractions hide resource usage, networking, and debugging access behind dashboards
  • Configuration drift risk: Multiple services deployed across different platforms with no centralized configuration management

The Solution

Docker Compose orchestration: All services defined in a single docker-compose.yml with health checks, restart policies, named volumes, and an isolated bridge network. Service ports are bound to 127.0.0.1 — only Caddy talks to the internet.

Caddy reverse proxy with automatic HTTPS: Five subdomains route to their respective containers. Caddy provisions and renews Let's Encrypt certificates without configuration. SPA routing handles React frontends, and trailing-slash normalization prevents FastAPI 307 redirects from dropping auth headers.

Documentation-first operations: Every server change is logged in docs/server-setup.md with exact commands, configuration snippets, and verification steps. The server can be rebuilt from documentation alone — no tribal knowledge, no undocumented SSH sessions.

Self-hosted Web Vitals (vitals.cushlabs.ai): A custom FastAPI service collects Core Web Vitals (LCP, FCP, CLS, INP, TTFB) and pageview analytics from all frontends. A single <script> tag integrates any site. The dark-themed dashboard auto-refreshes and displays metrics by site, page, and time range.

Technical Highlights

  • Phase-based hardening: Structured progression from bare metal through SSH hardening, UFW firewall, unattended upgrades, Docker, Caddy, and Netdata — each step documented and verified
  • 6 containers in ~386 MB: Efficient resource usage leaves 3.3 GB RAM and 77 GB disk as headroom for new services
  • Caddy SPA routing: Static React builds served with proper fallback to index.html, asset 404 handling, and API proxying — all in a readable Caddyfile
  • Cloudflare DNS-only: A records point to the VPS with no proxy (gray cloud), letting Caddy handle TLS termination directly via ACME
  • Environment variable isolation: .env.example.* templates committed to git, actual .env.<service> files live only on the VPS
  • Custom RUM collector: Lightweight PerformanceObserver-based tracker (~2KB) with SQLite storage and no third-party analytics dependencies

Results

For CushLabs Operations:

  • 4 production services migrated from Render to self-hosted Docker in a single day
  • Hosting consolidated from per-service PaaS to $10.59/mo flat — cost stays fixed regardless of service count
  • Zero cold start latency across all endpoints — services respond in milliseconds, not seconds
  • Full infrastructure visibility via Netdata, Docker stats, and SSH access

Technical Demonstration:

  • Linux server administration from bare metal to production
  • Docker Compose orchestration for multi-service architectures
  • Reverse proxy configuration with automatic TLS and SPA routing
  • Infrastructure-as-code principles applied to VPS management
  • Custom monitoring and observability tooling

¿Listo para discutir una solución similar?

Exploremos cómo la automatización con IA puede ayudar a tu negocio.

Agendar una Consulta