DEV Community

Cover image for I Built a Free Alternative to cPanel - Here's What I Learned
Juan Denis
Juan Denis

Posted on

I Built a Free Alternative to cPanel - Here's What I Learned

The Problem

Last year I was managing a handful of WordPress sites and a few Python apps for clients. My options were:

  1. cPanel - $45/month per server. For 3 servers, that's $1,620/year just for a control panel.

  2. Coolify - Great for Docker but felt like overkill for WordPress sites. I don't need Kubernetes.

  3. CloudPanel - Nice and lightweight but no Docker support. I need both.

  4. HestiaCP - Free and feature-rich but the UI looks like it's from 2008.

I wanted something in between: the simplicity of traditional hosting panels with the power of modern deployment tools.

So I built ServerKit.

What is ServerKit?

ServerKit is an open-source server management panel that lets you:

  • Deploy WordPress, Flask, Django, and Node.js apps
  • Manage Docker containers alongside traditional apps
  • Automatic HTTPS via Let's Encrypt
  • Real-time monitoring with alerts to Discord/Slack/Telegram
  • Visual firewall and cron job management
  • 2FA security with ClamAV malware scanning

Dashboard Screenshot

The Tech Stack

Backend:

  • Python 3.11 with Flask
  • SQLAlchemy ORM
  • Flask-SocketIO for real-time updates
  • Gunicorn for production

Frontend:

  • React 18 with Vite
  • WebSocket connection for live metrics
  • LESS for styling

Infrastructure:

  • Nginx reverse proxy
  • Let's Encrypt via Certbot
  • Docker & Docker Compose
  • MySQL/PostgreSQL support

Architecture Decisions

Why Flask over FastAPI?

FastAPI is great for pure APIs, but ServerKit needs:

  • WebSocket support (Flask-SocketIO is mature)
  • Template rendering for some pages
  • Simpler debugging during development

Real-Time Metrics

Every second, the backend collects:

metrics = {
    'cpu': psutil.cpu_percent(),
    'memory': psutil.virtual_memory().percent,
    'disk': psutil.disk_usage('/').percent,
    'network': get_network_stats()
}
socketio.emit('metrics', metrics, broadcast=True)
Enter fullscreen mode Exit fullscreen mode

The React frontend subscribes and updates the dashboard live. No polling, no page refreshes.

Dynamic Nginx Configuration

Each app type has a Jinja2 template:

# PHP app nginx config
server {
    listen 80;
    server_name {{ app.domain }};
    root {{ app.path }}/public;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php{{ app.php_version }}-fpm.sock;
        # ...
    }
}
Enter fullscreen mode Exit fullscreen mode

When you create an app, ServerKit generates the config, symlinks it, and reloads Nginx.

What I Learned

1. Start with the UI

I built the backend first and regretted it. Users don't see your clean API - they see the interface. Start with mockups, validate the UX, then build the backend to support it.

2. Security is Non-Negotiable

Server management panels are high-value targets. From day one:

  • JWT with short expiration
  • TOTP 2FA with backup codes
  • All secrets encrypted at rest
  • No shell commands built from user input

3. Real-Time Feels Premium

Static dashboards feel dead. Adding WebSocket-based live metrics made the app feel 10x more polished with relatively little code.

4. Don't Reinvent Everything

I use:

  • Certbot for SSL (don't roll your own ACME)
  • ClamAV for malware (don't write an antivirus)
  • systemd for service management (it works)

Focus on the glue, not the components.

Try It

One-line install:

curl -fsSL https://raw.githubusercontent.com/jhd3197/ServerKit/main/install.sh | bash
Enter fullscreen mode Exit fullscreen mode

Or with Docker:

git clone https://github.com/jhd3197/ServerKit.git
cd ServerKit
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

GitHub: github.com/jhd3197/ServerKit

MIT licensed, no telemetry, no cloud dependency.


What features would make this useful for you? Drop a comment - I read everything.

Top comments (0)