Files
ServerKit/serverkit
T
Juan Denis c1d60f112f Add ServerKit CLI, install script, and deployment improvements
Introduces a comprehensive Bash CLI tool (`serverkit`) for managing ServerKit services, users, and database operations. Adds a quick-install script (`install.sh`) for Ubuntu, a sample environment file (`.env.example`), and a Python CLI backend (`backend/cli.py`) for administrative tasks. Updates Docker Compose for production readiness, enhances deployment documentation, and adds Click to backend requirements. Also updates references to the correct GitHub repository.
2026-01-17 12:13:22 -05:00

474 lines
11 KiB
Bash

#!/bin/bash
#
# ServerKit CLI - Management tool for ServerKit
# 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' # No Color
# Configuration
INSTALL_DIR="${SERVERKIT_DIR:-/opt/serverkit}"
CONTAINER_NAME="serverkit-backend"
COMPOSE_FILE="docker-compose.yml"
# 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_docker() {
if ! command -v docker &> /dev/null; then
print_error "Docker is not installed"
exit 1
fi
if ! docker info &> /dev/null; then
print_error "Docker is not running or you don't have permission"
exit 1
fi
}
check_installed() {
if [ ! -f "$INSTALL_DIR/$COMPOSE_FILE" ]; then
print_error "ServerKit is not installed in $INSTALL_DIR"
print_info "Run: ./serverkit install"
exit 1
fi
}
run_cli() {
docker exec -it $CONTAINER_NAME python cli.py "$@"
}
# Commands
cmd_help() {
print_header
echo ""
echo "Usage: serverkit <command> [options]"
echo ""
echo "Service Commands:"
echo " install Install ServerKit"
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 Update to latest version"
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 " backup-db Backup the database"
echo " restore-db Restore database from backup"
echo ""
echo "Utility Commands:"
echo " generate-keys Generate secure keys for .env"
echo " shell Open a shell in the backend container"
echo " config Edit configuration"
echo ""
echo "Examples:"
echo " serverkit install"
echo " serverkit reset-password"
echo " serverkit logs backend"
echo ""
}
cmd_install() {
print_header
echo ""
print_info "Installing ServerKit..."
check_docker
# Check if already installed
if [ -d "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/$COMPOSE_FILE" ]; then
print_warning "ServerKit is already installed in $INSTALL_DIR"
read -p "Reinstall? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 0
fi
fi
# Create install directory
sudo mkdir -p "$INSTALL_DIR"
# Clone or copy files
if [ -d ".git" ]; then
print_info "Copying files to $INSTALL_DIR..."
sudo cp -r . "$INSTALL_DIR/"
else
print_info "Cloning repository..."
sudo git clone https://github.com/jhd3197/serverkit.git "$INSTALL_DIR"
fi
cd "$INSTALL_DIR"
# Generate .env if not exists
if [ ! -f ".env" ]; then
print_info "Generating configuration..."
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))" 2>/dev/null || openssl rand -hex 32)
JWT_SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))" 2>/dev/null || openssl rand -hex 32)
cat > .env << EOF
# ServerKit Configuration
# Generated on $(date)
# Security Keys (auto-generated)
SECRET_KEY=$SECRET_KEY
JWT_SECRET_KEY=$JWT_SECRET_KEY
# Database
DATABASE_URL=sqlite:///serverkit.db
# CORS Origins (your domain)
CORS_ORIGINS=http://localhost
# Ports
PORT=80
SSL_PORT=443
# Environment
FLASK_ENV=production
EOF
print_success "Configuration file created"
fi
# Create SSL directory
mkdir -p nginx/ssl
# Generate self-signed cert for initial setup
if [ ! -f "nginx/ssl/fullchain.pem" ]; then
print_info "Generating self-signed SSL certificate..."
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout nginx/ssl/privkey.pem \
-out nginx/ssl/fullchain.pem \
-subj "/CN=localhost" 2>/dev/null
print_warning "Self-signed certificate created. Replace with real certificate for production."
fi
# Build and start
print_info "Building containers..."
docker compose build
print_info "Starting services..."
docker compose up -d
# Wait for services
print_info "Waiting for services to be ready..."
sleep 10
# Check status
if docker compose ps | grep -q "running"; then
echo ""
print_success "ServerKit installed successfully!"
echo ""
echo "Next steps:"
echo " 1. Open http://localhost in your browser"
echo " 2. Create your admin account: serverkit create-admin"
echo " 3. Configure SSL certificate for production"
echo ""
else
print_error "Installation failed. Check logs with: serverkit logs"
exit 1
fi
}
cmd_start() {
check_installed
cd "$INSTALL_DIR"
print_info "Starting ServerKit..."
docker compose up -d
print_success "ServerKit started"
}
cmd_stop() {
check_installed
cd "$INSTALL_DIR"
print_info "Stopping ServerKit..."
docker compose down
print_success "ServerKit stopped"
}
cmd_restart() {
check_installed
cd "$INSTALL_DIR"
print_info "Restarting ServerKit..."
docker compose restart
print_success "ServerKit restarted"
}
cmd_status() {
check_installed
cd "$INSTALL_DIR"
print_header
echo ""
docker compose ps
echo ""
# Health check
if curl -s http://localhost/api/v1/health > /dev/null 2>&1; then
print_success "API is healthy"
else
print_warning "API health check failed"
fi
}
cmd_logs() {
check_installed
cd "$INSTALL_DIR"
service="${1:-}"
if [ -n "$service" ]; then
docker compose logs -f "$service"
else
docker compose logs -f
fi
}
cmd_update() {
check_installed
cd "$INSTALL_DIR"
print_info "Updating ServerKit..."
# Pull latest changes
if [ -d ".git" ]; then
git pull
fi
# Rebuild and restart
docker compose build
docker compose up -d
print_success "ServerKit updated"
}
cmd_uninstall() {
print_header
echo ""
print_warning "This will remove ServerKit and all data!"
read -p "Are you sure? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [ -d "$INSTALL_DIR" ]; then
cd "$INSTALL_DIR"
docker compose down -v 2>/dev/null || true
cd /
sudo rm -rf "$INSTALL_DIR"
fi
print_success "ServerKit uninstalled"
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_backup_db() {
check_installed
cd "$INSTALL_DIR"
BACKUP_FILE="backup/serverkit-$(date +%Y%m%d-%H%M%S).db"
mkdir -p backup
docker cp $CONTAINER_NAME:/app/instance/serverkit.db "$BACKUP_FILE"
print_success "Database backed up to $BACKUP_FILE"
}
cmd_restore_db() {
check_installed
cd "$INSTALL_DIR"
if [ -z "$1" ]; then
echo "Available backups:"
ls -la backup/*.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
docker cp "$BACKUP_FILE" $CONTAINER_NAME:/app/instance/serverkit.db
docker compose restart backend
print_success "Database restored"
fi
}
cmd_generate_keys() {
check_docker
print_header
echo ""
echo "Add these to your .env file:"
echo ""
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))" 2>/dev/null || openssl rand -hex 32)
JWT_SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))" 2>/dev/null || openssl rand -hex 32)
echo "SECRET_KEY=$SECRET_KEY"
echo "JWT_SECRET_KEY=$JWT_SECRET_KEY"
echo ""
}
cmd_shell() {
check_installed
docker exec -it $CONTAINER_NAME /bin/bash
}
cmd_config() {
check_installed
${EDITOR:-nano} "$INSTALL_DIR/.env"
print_info "Restart ServerKit to apply changes: serverkit restart"
}
# Main
case "${1:-help}" in
help|--help|-h)
cmd_help
;;
install)
cmd_install
;;
start)
cmd_start
;;
stop)
cmd_stop
;;
restart)
cmd_restart
;;
status)
cmd_status
;;
logs)
cmd_logs "$2"
;;
update)
cmd_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
;;
backup-db)
cmd_backup_db
;;
restore-db)
cmd_restore_db "$2"
;;
generate-keys)
cmd_generate_keys
;;
shell)
cmd_shell
;;
config)
cmd_config
;;
*)
print_error "Unknown command: $1"
echo "Run 'serverkit help' for usage"
exit 1
;;
esac