Files
ServerKit/serverkit
T
Juan Denis fc02f40636 Add tracking for install, update, and uninstall events
Added calls to serverkit.ai to track successful installation, update, and uninstall events with the current version. This helps monitor usage and improve support.
2026-01-28 22:31:46 -05:00

1055 lines
27 KiB
Bash

#!/bin/bash
#
# ServerKit CLI - Management tool for ServerKit
#
# Architecture:
# - Backend: systemd service (runs directly on host)
# - Frontend: Docker container (nginx)
#
# Usage: serverkit <command> [options]
#
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Configuration
INSTALL_DIR="${SERVERKIT_DIR:-/opt/serverkit}"
VENV_DIR="$INSTALL_DIR/venv"
BACKEND_SERVICE="serverkit"
FRONTEND_CONTAINER="serverkit-frontend"
# Helper functions
print_header() {
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} ServerKit CLI${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
print_success() { echo -e "${GREEN}✓ $1${NC}"; }
print_error() { echo -e "${RED}✗ $1${NC}"; }
print_warning() { echo -e "${YELLOW}! $1${NC}"; }
print_info() { echo -e "${BLUE}→ $1${NC}"; }
check_root() {
if [ "$EUID" -ne 0 ]; then
print_error "This command requires root privileges. Run with sudo."
exit 1
fi
}
check_installed() {
if [ ! -d "$INSTALL_DIR" ]; then
print_error "ServerKit is not installed in $INSTALL_DIR"
print_info "Run the install script first"
exit 1
fi
}
run_cli() {
# Run CLI commands directly on host using the virtual environment
cd "$INSTALL_DIR/backend"
source "$VENV_DIR/bin/activate"
python cli.py "$@"
}
# Version management
VERSION_FILE="$INSTALL_DIR/VERSION"
REMOTE_VERSION_URL="https://raw.githubusercontent.com/jhd3197/serverkit/main/VERSION"
get_local_version() {
if [ -f "$VERSION_FILE" ]; then
cat "$VERSION_FILE" | tr -d '\n\r '
else
echo "unknown"
fi
}
get_remote_version() {
curl -sf "$REMOTE_VERSION_URL" 2>/dev/null | tr -d '\n\r ' || echo "unknown"
}
compare_versions() {
# Returns: 0 if equal, 1 if v1 > v2, 2 if v1 < v2
local v1="$1"
local v2="$2"
if [ "$v1" = "$v2" ]; then
return 0
fi
# Compare version components
local v1_major=$(echo "$v1" | cut -d. -f1)
local v1_minor=$(echo "$v1" | cut -d. -f2)
local v1_patch=$(echo "$v1" | cut -d. -f3)
local v2_major=$(echo "$v2" | cut -d. -f1)
local v2_minor=$(echo "$v2" | cut -d. -f2)
local v2_patch=$(echo "$v2" | cut -d. -f3)
if [ "$v1_major" -gt "$v2_major" ] 2>/dev/null; then return 1; fi
if [ "$v1_major" -lt "$v2_major" ] 2>/dev/null; then return 2; fi
if [ "$v1_minor" -gt "$v2_minor" ] 2>/dev/null; then return 1; fi
if [ "$v1_minor" -lt "$v2_minor" ] 2>/dev/null; then return 2; fi
if [ "$v1_patch" -gt "$v2_patch" ] 2>/dev/null; then return 1; fi
if [ "$v1_patch" -lt "$v2_patch" ] 2>/dev/null; then return 2; fi
return 0
}
cmd_version() {
local version=$(get_local_version)
echo "ServerKit version $version"
}
cmd_check_update() {
print_info "Checking for updates..."
local local_version=$(get_local_version)
local remote_version=$(get_remote_version)
echo ""
echo " Installed version: $local_version"
echo " Latest version: $remote_version"
echo ""
if [ "$remote_version" = "unknown" ]; then
print_warning "Could not check remote version (network error?)"
return 1
fi
set +e # Temporarily disable exit on error
compare_versions "$local_version" "$remote_version"
local result=$?
set -e # Re-enable exit on error
if [ $result -eq 2 ]; then
print_success "Update available! Run 'sudo serverkit update' to upgrade."
return 0
elif [ $result -eq 0 ]; then
print_success "You are running the latest version."
return 0
else
print_info "You are running a newer version than released."
return 0
fi
}
# Commands
cmd_help() {
print_header
echo ""
echo "Usage: serverkit <command> [options]"
echo ""
echo "Service Commands:"
echo " start Start all services"
echo " stop Stop all services"
echo " restart Restart all services"
echo " status Show service status"
echo " logs [service] View logs (backend, frontend, or all)"
echo " update [options] Update ServerKit"
echo " --branch <name> Switch to specific branch (e.g., dev)"
echo " --force Skip version check"
echo " branch Show current branch"
echo " uninstall Uninstall ServerKit"
echo ""
echo "User Management:"
echo " create-admin Create a new admin user"
echo " reset-password Reset a user's password"
echo " unlock-user Unlock a locked user account"
echo " list-users List all users"
echo " make-admin Promote user to admin"
echo " deactivate-user Deactivate a user account"
echo " activate-user Activate a user account"
echo ""
echo "Database Commands:"
echo " init-db Initialize the database"
echo " migrate-db Apply database migrations"
echo " backup-db Backup the database"
echo " restore-db Restore database from backup"
echo ""
echo "Cleanup Commands:"
echo " cleanup-apps Delete all apps and containers"
echo " factory-reset Complete reset (delete everything)"
echo ""
echo "App Management:"
echo " create-app Show how to create apps (via web UI)"
echo " list-apps [--all] List deployed apps (--all shows Docker containers)"
echo " start-app Start an app"
echo " stop-app Stop an app"
echo " app-logs View app logs"
echo ""
echo "Site Management:"
echo " setup-proxy Setup host nginx as reverse proxy (run once)"
echo " add-site Add a new site/domain"
echo " list-sites List all configured sites"
echo " remove-site Remove a site"
echo ""
echo "Version Commands:"
echo " version Show current version"
echo " check-update Check if updates are available"
echo ""
echo "Utility Commands:"
echo " generate-keys Generate secure keys for .env"
echo " config Edit configuration"
echo ""
echo "Examples:"
echo " sudo serverkit start"
echo " sudo serverkit create-admin"
echo " sudo serverkit add-site test.mysite.com 3000"
echo " serverkit logs backend"
echo ""
}
cmd_start() {
check_root
check_installed
print_info "Starting ServerKit..."
# Start backend (systemd)
systemctl start $BACKEND_SERVICE
# Start frontend (Docker)
cd "$INSTALL_DIR"
docker compose up -d
sleep 3
print_success "ServerKit started"
cmd_status_brief
}
cmd_stop() {
check_root
check_installed
print_info "Stopping ServerKit..."
# Stop backend (systemd)
systemctl stop $BACKEND_SERVICE || true
# Stop frontend (Docker)
cd "$INSTALL_DIR"
docker compose down || true
print_success "ServerKit stopped"
}
cmd_restart() {
check_root
check_installed
print_info "Restarting ServerKit..."
# Restart backend (systemd)
systemctl restart $BACKEND_SERVICE
# Restart frontend (Docker)
cd "$INSTALL_DIR"
docker compose restart
sleep 3
print_success "ServerKit restarted"
cmd_status_brief
}
cmd_status_brief() {
# Quick status check
echo ""
# Backend status
if systemctl is-active --quiet $BACKEND_SERVICE; then
print_success "Backend: running"
else
print_error "Backend: stopped"
fi
# Frontend status
if docker ps --format '{{.Names}}' | grep -q $FRONTEND_CONTAINER; then
print_success "Frontend: running"
else
print_error "Frontend: stopped"
fi
# API health
if curl -s http://127.0.0.1:5000/api/v1/system/health > /dev/null 2>&1; then
print_success "API: healthy"
else
print_warning "API: not responding"
fi
}
cmd_status() {
check_installed
print_header
echo ""
echo "Backend Service (systemd):"
echo "─────────────────────────────"
systemctl status $BACKEND_SERVICE --no-pager -l 2>/dev/null || print_warning "Backend service not found"
echo ""
echo "Frontend Container (Docker):"
echo "─────────────────────────────"
cd "$INSTALL_DIR"
docker compose ps 2>/dev/null || print_warning "Frontend container not found"
echo ""
cmd_status_brief
}
cmd_logs() {
check_installed
service="${1:-all}"
case "$service" in
backend)
journalctl -u $BACKEND_SERVICE -f
;;
frontend)
cd "$INSTALL_DIR"
docker compose logs -f
;;
all|*)
print_info "Showing backend logs (Ctrl+C to switch to frontend)..."
echo ""
# Show both in split view isn't easy in bash, so show backend first
journalctl -u $BACKEND_SERVICE -n 50 --no-pager
echo ""
print_info "Showing frontend logs..."
echo ""
cd "$INSTALL_DIR"
docker compose logs --tail=50
echo ""
print_info "For live logs, use: serverkit logs backend OR serverkit logs frontend"
;;
esac
}
cmd_branch() {
check_installed
cd "$INSTALL_DIR"
local current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
local current_commit=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
echo ""
echo " Current branch: $current_branch"
echo " Current commit: $current_commit"
echo " Version: $(get_local_version)"
echo ""
# Show available remote branches
print_info "Available branches:"
git branch -r 2>/dev/null | grep -v HEAD | sed 's/origin\// /' | head -10
echo ""
}
cmd_update() {
local force_update=false
local target_branch=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--force|-f)
force_update=true
shift
;;
--branch|-b)
target_branch="$2"
shift 2
;;
*)
shift
;;
esac
done
check_root
check_installed
print_header
echo ""
cd "$INSTALL_DIR"
# Get current branch
local current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
# If no branch specified, use current branch (or main if detached)
if [ -z "$target_branch" ]; then
target_branch="$current_branch"
if [ "$target_branch" = "HEAD" ]; then
target_branch="main"
fi
fi
# Get versions
CURRENT_VERSION=$(get_local_version)
# For non-main branches, skip version comparison
if [ "$target_branch" != "main" ]; then
force_update=true
print_warning "Updating to branch: $target_branch (dev mode)"
echo ""
else
REMOTE_VERSION=$(get_remote_version)
echo " Installed version: $CURRENT_VERSION"
echo " Latest version: $REMOTE_VERSION"
echo ""
fi
# Check if update is needed (skip if --force or non-main branch)
if [ "$force_update" = false ] && [ "$REMOTE_VERSION" != "unknown" ]; then
set +e # Temporarily disable exit on error
compare_versions "$CURRENT_VERSION" "$REMOTE_VERSION"
local result=$?
set -e # Re-enable exit on error
if [ $result -eq 0 ]; then
print_success "Already running the latest version."
echo ""
read -p "Force update anyway? [y/N] " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 0
fi
fi
fi
print_info "Updating ServerKit to branch: $target_branch..."
# Stop services
print_info "Stopping services..."
systemctl stop $BACKEND_SERVICE || true
docker compose down || true
# Fetch all branches and pull changes
print_info "Fetching latest changes..."
git fetch origin --prune
# Checkout target branch
print_info "Switching to branch: $target_branch..."
git checkout "$target_branch" 2>/dev/null || git checkout -b "$target_branch" "origin/$target_branch"
git reset --hard "origin/$target_branch"
# Restore executable permissions
chmod +x "$INSTALL_DIR/serverkit"
chmod +x "$INSTALL_DIR/scripts/"*.sh 2>/dev/null || true
# Get new version from VERSION file
NEW_VERSION=$(get_local_version)
NEW_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# Update Python dependencies
print_info "Updating Python dependencies..."
source "$VENV_DIR/bin/activate"
pip install -r "$INSTALL_DIR/backend/requirements.txt" --quiet
# Sync app templates
print_info "Syncing app templates..."
mkdir -p /etc/serverkit/templates
cp -r "$INSTALL_DIR/backend/templates/"*.yaml /etc/serverkit/templates/ 2>/dev/null || true
cp -r "$INSTALL_DIR/backend/templates/"*.yml /etc/serverkit/templates/ 2>/dev/null || true
# Clean up Docker to prevent networking issues
print_info "Cleaning up Docker..."
docker network prune -f 2>/dev/null || true
docker system prune -f 2>/dev/null || true
# Rebuild frontend (no cache to ensure fresh build)
print_info "Rebuilding frontend..."
docker compose build --no-cache
# Reload systemd in case service file changed
systemctl daemon-reload
# Restart services
print_info "Starting services..."
systemctl start $BACKEND_SERVICE
docker compose up -d
sleep 5
# Track successful update
curl -s "https://serverkit.ai/track/update?v=${NEW_VERSION}" >/dev/null 2>&1 || true
echo ""
print_success "ServerKit updated!"
echo " Branch: $target_branch"
echo " Commit: $NEW_COMMIT"
echo " Version: $NEW_VERSION"
echo ""
if [ "$target_branch" != "main" ]; then
print_warning "Running on '$target_branch' branch. Use 'serverkit update --branch main' to return to stable."
fi
cmd_status_brief
}
cmd_uninstall() {
check_root
print_header
echo ""
print_warning "This will remove ServerKit and all data!"
echo ""
echo "The following will be removed:"
echo " - ServerKit backend service (systemd)"
echo " - Frontend Docker container and images"
echo " - Installation directory ($INSTALL_DIR)"
echo " - Configuration (/etc/serverkit)"
echo " - App data (/var/serverkit)"
echo " - Logs (/var/log/serverkit)"
echo " - Nginx site configs for ServerKit"
echo " - CLI symlink (/usr/local/bin/serverkit)"
echo ""
read -p "Are you sure? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Track uninstall before removing files
UNINSTALL_VERSION=$(get_local_version)
curl -s "https://serverkit.ai/track/uninstall?v=${UNINSTALL_VERSION}" >/dev/null 2>&1 || true
print_info "Stopping services..."
systemctl stop $BACKEND_SERVICE 2>/dev/null || true
systemctl disable $BACKEND_SERVICE 2>/dev/null || true
cd "$INSTALL_DIR" 2>/dev/null && docker compose down -v 2>/dev/null || true
# Move to safe directory before deleting install dir
cd /tmp 2>/dev/null || cd / || true
print_info "Removing files..."
rm -f /etc/systemd/system/serverkit.service
rm -f /usr/local/bin/serverkit
rm -rf "$INSTALL_DIR"
rm -rf /var/log/serverkit
rm -rf /var/lib/serverkit
# Remove ServerKit config and app data
rm -rf /etc/serverkit
rm -rf /var/serverkit
# Remove nginx site configs installed by ServerKit
print_info "Removing nginx configs..."
rm -f /etc/nginx/sites-enabled/serverkit.conf
rm -f /etc/nginx/sites-available/serverkit.conf
rm -f /etc/nginx/sites-available/example.conf.template
# Reload nginx if it's still running (don't stop it — user may use it for other sites)
if systemctl is-active --quiet nginx 2>/dev/null; then
systemctl reload nginx 2>/dev/null || true
fi
systemctl daemon-reload
print_success "ServerKit uninstalled"
echo ""
echo "Note: System packages (Docker, Node.js, nginx, Python) were NOT removed."
echo "Remove them manually if no longer needed."
echo ""
echo "To reinstall, run:"
echo " cd ~ && curl -fsSL https://serverkit.ai/install.sh | sudo bash"
fi
}
cmd_create_admin() {
check_installed
print_info "Creating admin user..."
run_cli create-admin
}
cmd_reset_password() {
check_installed
print_info "Resetting password..."
run_cli reset-password
}
cmd_unlock_user() {
check_installed
run_cli unlock-user
}
cmd_list_users() {
check_installed
run_cli list-users
}
cmd_make_admin() {
check_installed
run_cli make-admin
}
cmd_deactivate_user() {
check_installed
run_cli deactivate-user
}
cmd_activate_user() {
check_installed
run_cli activate-user
}
cmd_init_db() {
check_installed
run_cli init-db
}
cmd_migrate_db() {
check_installed
run_cli migrate-db
}
cmd_cleanup_apps() {
check_root
check_installed
DELETE_VOLUMES=""
KEEP_DB=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--delete-volumes|-v)
DELETE_VOLUMES="--delete-volumes"
shift
;;
--keep-db|-k)
KEEP_DB="--keep-db"
shift
;;
*)
shift
;;
esac
done
run_cli cleanup-apps $DELETE_VOLUMES $KEEP_DB
}
cmd_factory_reset() {
check_root
check_installed
run_cli factory-reset
}
cmd_backup_db() {
check_installed
BACKUP_DIR="$INSTALL_DIR/backups"
BACKUP_FILE="$BACKUP_DIR/serverkit-$(date +%Y%m%d-%H%M%S).db"
DB_FILE="$INSTALL_DIR/backend/instance/serverkit.db"
mkdir -p "$BACKUP_DIR"
if [ -f "$DB_FILE" ]; then
cp "$DB_FILE" "$BACKUP_FILE"
print_success "Database backed up to $BACKUP_FILE"
else
print_error "Database file not found: $DB_FILE"
exit 1
fi
}
cmd_restore_db() {
check_root
check_installed
BACKUP_DIR="$INSTALL_DIR/backups"
DB_FILE="$INSTALL_DIR/backend/instance/serverkit.db"
if [ -z "$1" ]; then
echo "Available backups:"
ls -la "$BACKUP_DIR"/*.db 2>/dev/null || echo "No backups found"
echo ""
read -p "Enter backup file path: " BACKUP_FILE
else
BACKUP_FILE="$1"
fi
if [ ! -f "$BACKUP_FILE" ]; then
print_error "Backup file not found: $BACKUP_FILE"
exit 1
fi
print_warning "This will overwrite the current database!"
read -p "Continue? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Stop backend before restore
systemctl stop $BACKEND_SERVICE
cp "$BACKUP_FILE" "$DB_FILE"
# Restart backend
systemctl start $BACKEND_SERVICE
print_success "Database restored"
fi
}
cmd_generate_keys() {
print_header
echo ""
echo "Add these to your .env file:"
echo ""
SECRET_KEY=$(openssl rand -hex 32)
JWT_SECRET_KEY=$(openssl rand -hex 32)
echo "SECRET_KEY=$SECRET_KEY"
echo "JWT_SECRET_KEY=$JWT_SECRET_KEY"
echo ""
}
cmd_config() {
check_installed
${EDITOR:-nano} "$INSTALL_DIR/.env"
print_info "Restart ServerKit to apply changes: sudo serverkit restart"
}
cmd_setup_proxy() {
check_root
check_installed
print_info "Setting up host nginx as reverse proxy..."
if [ -f "$INSTALL_DIR/scripts/setup-nginx-proxy.sh" ]; then
chmod +x "$INSTALL_DIR/scripts/setup-nginx-proxy.sh"
"$INSTALL_DIR/scripts/setup-nginx-proxy.sh"
else
print_error "Setup script not found. Run 'serverkit update' first."
exit 1
fi
}
cmd_create_app() {
print_header
echo ""
echo "To create a new app, use the ServerKit web interface:"
echo ""
echo " 1. Open ServerKit in your browser"
echo " 2. Go to Templates in the sidebar"
echo " 3. Choose from 60+ available templates:"
echo " - PHP Application (custom PHP projects)"
echo " - Python Application (Flask, FastAPI, Django)"
echo " - Node.js Application (Express, Next.js)"
echo " - WordPress, Ghost, Nextcloud, and many more"
echo " 4. Click Install and configure your app"
echo ""
echo "The web interface provides:"
echo " ✓ One-click installation"
echo " ✓ Automatic port assignment"
echo " ✓ Configuration UI"
echo " ✓ Update management"
echo ""
}
cmd_list_apps() {
check_installed
# Pass --all flag if provided
if [ "$1" = "--all" ] || [ "$1" = "-a" ]; then
run_cli list-apps --all
else
run_cli list-apps
fi
}
cmd_start_app() {
check_root
NAME="$1"
if [ -z "$NAME" ]; then
echo "Usage: serverkit start-app <name>"
cmd_list_apps
exit 1
fi
APP_DIR="/var/www/$NAME"
if [ ! -d "$APP_DIR" ]; then
print_error "App not found: $NAME"
exit 1
fi
print_info "Starting $NAME..."
cd "$APP_DIR"
docker compose up -d
print_success "$NAME started"
}
cmd_stop_app() {
check_root
NAME="$1"
if [ -z "$NAME" ]; then
echo "Usage: serverkit stop-app <name>"
cmd_list_apps
exit 1
fi
APP_DIR="/var/www/$NAME"
if [ ! -d "$APP_DIR" ]; then
print_error "App not found: $NAME"
exit 1
fi
print_info "Stopping $NAME..."
cd "$APP_DIR"
docker compose down
print_success "$NAME stopped"
}
cmd_app_logs() {
NAME="$1"
if [ -z "$NAME" ]; then
echo "Usage: serverkit app-logs <name>"
cmd_list_apps
exit 1
fi
APP_DIR="/var/www/$NAME"
if [ ! -d "$APP_DIR" ]; then
print_error "App not found: $NAME"
exit 1
fi
cd "$APP_DIR"
docker compose logs -f
}
cmd_add_site() {
check_root
DOMAIN="$1"
PORT="${2:-3000}"
if [ -z "$DOMAIN" ]; then
echo "Usage: serverkit add-site <domain> [port]"
echo ""
echo "Examples:"
echo " serverkit add-site test.builditdesign.com"
echo " serverkit add-site myapp.builditdesign.com 3000"
exit 1
fi
SITE_FILE="/etc/nginx/sites-available/${DOMAIN}.conf"
if [ -f "$SITE_FILE" ]; then
print_warning "Site config already exists: $SITE_FILE"
read -p "Overwrite? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 0
fi
fi
print_info "Creating site config for $DOMAIN..."
cat > "$SITE_FILE" << EOF
# Site: $DOMAIN
# Created: $(date)
server {
listen 80;
server_name $DOMAIN;
location / {
proxy_pass http://127.0.0.1:$PORT;
proxy_http_version 1.1;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
}
}
EOF
# Enable the site
ln -sf "$SITE_FILE" /etc/nginx/sites-enabled/
# Test and reload nginx
if nginx -t 2>/dev/null; then
systemctl reload nginx
print_success "Site added: $DOMAIN → localhost:$PORT"
echo ""
echo "Next steps:"
echo " 1. Add DNS record in Cloudflare:"
echo " Type: A, Name: ${DOMAIN%%.*}, Content: $(curl -s ifconfig.me)"
echo " 2. Start your app on port $PORT"
echo ""
else
print_error "Nginx config error. Check: $SITE_FILE"
rm -f "/etc/nginx/sites-enabled/${DOMAIN}.conf"
exit 1
fi
}
cmd_list_sites() {
print_header
echo ""
echo "Configured Sites:"
echo "─────────────────────────────────────────"
if [ -d /etc/nginx/sites-enabled ]; then
for site in /etc/nginx/sites-enabled/*.conf; do
if [ -f "$site" ]; then
DOMAIN=$(grep -m1 "server_name" "$site" | awk '{print $2}' | tr -d ';')
PORT=$(grep -m1 "proxy_pass" "$site" | grep -oP ':\K[0-9]+' || echo "static")
ENABLED="✓"
printf " %s %-35s → port %s\n" "$ENABLED" "$DOMAIN" "$PORT"
fi
done
else
echo " No sites configured. Run 'serverkit setup-proxy' first."
fi
echo ""
}
cmd_remove_site() {
check_root
DOMAIN="$1"
if [ -z "$DOMAIN" ]; then
echo "Usage: serverkit remove-site <domain>"
cmd_list_sites
exit 1
fi
SITE_FILE="/etc/nginx/sites-available/${DOMAIN}.conf"
ENABLED_FILE="/etc/nginx/sites-enabled/${DOMAIN}.conf"
if [ ! -f "$SITE_FILE" ]; then
print_error "Site not found: $DOMAIN"
exit 1
fi
print_warning "This will remove the site config for $DOMAIN"
read -p "Continue? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -f "$ENABLED_FILE"
rm -f "$SITE_FILE"
systemctl reload nginx
print_success "Site removed: $DOMAIN"
fi
}
# Main
case "${1:-help}" in
help|--help|-h)
cmd_help
;;
start)
cmd_start
;;
stop)
cmd_stop
;;
restart)
cmd_restart
;;
status)
cmd_status
;;
logs)
cmd_logs "$2"
;;
update)
shift
cmd_update "$@"
;;
branch)
cmd_branch
;;
version|--version|-v)
cmd_version
;;
check-update)
cmd_check_update
;;
uninstall)
cmd_uninstall
;;
create-admin)
cmd_create_admin
;;
reset-password)
cmd_reset_password
;;
unlock-user)
cmd_unlock_user
;;
list-users)
cmd_list_users
;;
make-admin)
cmd_make_admin
;;
deactivate-user)
cmd_deactivate_user
;;
activate-user)
cmd_activate_user
;;
init-db)
cmd_init_db
;;
migrate-db)
cmd_migrate_db
;;
cleanup-apps)
shift
cmd_cleanup_apps "$@"
;;
factory-reset)
cmd_factory_reset
;;
backup-db)
cmd_backup_db
;;
restore-db)
cmd_restore_db "$2"
;;
generate-keys)
cmd_generate_keys
;;
config)
cmd_config
;;
setup-proxy)
cmd_setup_proxy
;;
create-app)
cmd_create_app "$2" "$3" "$4"
;;
list-apps)
cmd_list_apps "$2"
;;
start-app)
cmd_start_app "$2"
;;
stop-app)
cmd_stop_app "$2"
;;
app-logs)
cmd_app_logs "$2"
;;
add-site)
cmd_add_site "$2" "$3"
;;
list-sites)
cmd_list_sites
;;
remove-site)
cmd_remove_site "$2"
;;
*)
print_error "Unknown command: $1"
echo "Run 'serverkit help' for usage"
exit 1
;;
esac