The Problem
Last year I was managing a handful of WordPress sites and a few Python apps for clients. My options were:
cPanel - $45/month per server. For 3 servers, that's $1,620/year just for a control panel.
Coolify - Great for Docker but felt like overkill for WordPress sites. I don't need Kubernetes.
CloudPanel - Nice and lightweight but no Docker support. I need both.
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
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)
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;
# ...
}
}
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
Or with Docker:
git clone https://github.com/jhd3197/ServerKit.git
cd ServerKit
docker compose up -d
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)