The setup
Our primary server is a Dell PowerEdge T440 — a tower server running Ubuntu 24.04 with Virtualmin Pro for panel management. It lives in our office on a Verizon FiOS 2.5Gbps symmetric connection, protected behind a Cloudflare Tunnel for zero-trust access.
Specs: dual Xeon Gold 6148 processors, 32GB ECC RAM, RAID storage. It handles:
- Multiple client websites and landing page systems
- CLView — our internal SaaS platform
- LeadForge — our landing page generator
- The CUPS Frozen Yogurt backend API
- Several smaller client tools and dashboards
- Our SEO audit tool (Python/Flask)
- Ollama running local AI models
Why not just use AWS?
AWS, DigitalOcean, and similar cloud providers are excellent. For most startups and small businesses, they're the right choice. But for a studio like ours — where we're running many different projects simultaneously — the economics work out very differently.
A comparable AWS setup (EC2 + RDS + storage) for everything we run would cost $400–800/month. Our server was a one-time hardware purchase, and our monthly costs are electricity + our internet connection (which we'd have anyway).
Over 3 years, the math strongly favors owned hardware for a predictable workload.
The Cloudflare Tunnel is the key
The part that makes self-hosting practical for production web apps is Cloudflare Tunnel. Instead of opening ports on our firewall and managing SSL certificates manually, every domain routes through Cloudflare's network to our server through an encrypted tunnel.
This means:
- No public-facing open ports on our server
- Automatic SSL for every domain
- DDoS protection from Cloudflare's network
- Our home IP address is never exposed
- We can add new domains in minutes from the Cloudflare dashboard
The stack
The full infrastructure stack on our server:
- Ubuntu 24.04 — OS
- Virtualmin Pro — server management panel
- Apache — web server for PHP sites
- Nginx (via NPM) — reverse proxy for non-PHP apps
- MariaDB — database for all PHP applications
- Python / Gunicorn — for Flask-based tools
- Ollama — local AI model inference
- Cloudflare Tunnel — public access layer
- ZimaOS — secondary NAS/Docker host
What we'd do differently
Self-hosting has real tradeoffs. Hardware fails. Power goes out. Internet goes down. We've had all three. Our mitigation:
- UPS battery backup keeps the server running through short outages
- Automated nightly backups to a separate NAS (TrueNAS)
- Cloudflare's caching means most static content serves even if our server is down
- For mission-critical client uptime requirements, we use cloud hosting and keep self-hosting for internal tools
If we were starting over today, we'd probably split the difference: self-host development environments and internal tools, use cloud for any client site with an SLA requirement.
If you're a developer curious about this setup, the key components are: a used PowerEdge server ($300–500 on eBay), Virtualmin (free tier works), and a Cloudflare account (free tier covers most needs). Total setup time is a weekend.