Introduce fallback audit logging and enrich audit tooling; add builtin extension discovery/install; and update default launcher ports and related docs/config. Key changes: - New middleware app.middleware.audit registers an after-request fallback that records authenticated mutating API requests when routes don't emit explicit audit logs. - Audit model/action constants extended and AuditService enhanced (request context handling, redaction for sensitive settings, optional commit flag, sets g.audit_logged, emits events). - Routes/services updated to create explicit audit entries for marketplace and plugin operations (create/update/publish/install/uninstall/enable/disable) and SSO/settings flows switched to use AuditService. - Added tests for audit logging behavior and redaction (backend/tests/test_audit_log.py). - Plugin service: added BUILTIN_EXTENSIONS_DIR, list_builtin_extensions and install_builtin_extension; plugin API endpoints to list/install builtin extensions. - Contribution system extended to support layouts and route layout metadata; frontend wiring updated to surface standalone/custom layouts and extension routes. - Launcher port defaults changed (backend -> 47927, frontend -> 41921). Updated backend .env.example, config CORS defaults, Dockerfiles and docker-compose to use SERVERKIT_BACKEND_PORT, and many docs/README files and frontend envs to reflect new ports. - Minor frontend cleanups and new builtin extension example (serverkit-git) plus associated manifest and frontend re-export. These changes improve observability/security for mutating APIs, enable opt-in builtin plugins, and align local dev/run ports with the launcher defaults.
5.6 KiB
AGENTS.md
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
Project Overview
ServerKit is a server control panel for managing web applications, databases, Docker containers, and security on VPS/dedicated servers. Flask backend (Python 3.11+), React frontend (Vite + SCSS), SQLite/PostgreSQL database, real-time updates via Socket.IO.
Development Commands
# Backend (launcher default port 47927, hot-reload)
cd backend && python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
python run.py
# Frontend (launcher default port 41921, Vite HMR)
cd frontend && npm install && npm run dev
# Both at once (Linux/WSL)
./dev.sh
# Frontend lint
cd frontend && npm run lint
# Frontend production build
cd frontend && npm run build
# Backend tests
cd backend && pytest
cd backend && pytest --cov=app
# Docker
docker compose -f docker-compose.dev.yml up --build
Default dev credentials: admin / admin
Architecture
Backend (backend/)
Flask app factory in app/__init__.py using create_app(). Three-layer architecture:
app/api/— Flask Blueprints, one file per feature (36 files). All routes prefixed/api/v1/. JWT-protected via@jwt_required().app/services/— Business logic (48 files). Services are stateless modules called by API routes. Heavy lifting (shell commands, Docker API, file operations) happens here.app/models/— SQLAlchemy ORM models (15 files). Tables auto-created on startup viadb.create_all().
Other backend components:
app/sockets.py— Socket.IO event handlers for real-time metrics, logs, terminalapp/agent_gateway.py— Multi-server agent communicationapp/middleware/security.py— Security headers middlewareconfig.py— Environment-based config (development/production/testing)run.py— Entry point
Frontend (frontend/src/)
React 18 SPA with client-side routing:
pages/— Route-level components (~29 files). Each maps to a route inApp.jsx.components/— Reusable UI components shared across pages.contexts/— React Context providers:AuthContext(JWT auth + token refresh),ThemeContext,ToastContext,ResourceTierContext(feature gating).services/api.js— CentralizedApiServiceclass handling all HTTP requests, token management, and auto-refresh.hooks/— Custom React hooks for reusable logic.styles/— SCSS stylesheets with design system variables. Main entry ismain.scss. Page-specific styles instyles/pages/.layouts/—DashboardLayoutwraps authenticated pages (sidebar + header).
Route guards: PrivateRoute (auth check), PublicRoute (redirect if logged in), SetupRoute (redirect to /setup if not configured).
Request Flow
Browser → Nginx (:80/:443) → proxy_pass to Docker containers (:8001-8999) for managed apps, or to Flask (:5000) for the panel API. The 404 handler in Flask serves index.html for SPA client-side routing; API routes return JSON errors.
Production Build
The Dockerfile is multi-stage: Node 20 builds frontend, Python 3.11 serves everything via Gunicorn with GeventWebSocket workers. Built frontend is served from Flask's static folder.
Platform & Distro Awareness
ServerKit deploys on Linux (bare metal, VPS, or Docker). Development may happen on Windows/macOS.
- Service layer is Linux-only — nginx, systemctl, apt/dnf, PHP-FPM, etc. are inherently Linux. No need to abstract these for Windows.
- Platform-agnostic code (config management, storage, API layer) should guard Unix-only calls like
os.chmodwithif os.name != 'nt'so the dev server can run locally on any OS. - Distro differences matter — use
backend/app/utils/system.pyhelpers (get_package_manager,is_package_installed,install_package) instead of callingapt/dpkg/dnfdirectly. Not all targets are Debian-based.
Code Style
Python
- PEP 8, type hints where helpful
- Service functions are standalone (no classes unless stateful)
- Consistent JSON error responses:
{'error': 'message'}, status_code
React/JavaScript
- Functional components with hooks only
- PascalCase for components (
Sidebar.jsx), camelCase for everything else - SCSS for styling — use existing design system variables (
$bg-card,$primary-color,$spacing-md, etc.) and BEM-like naming (.block__element--modifier) - Context API for global state; props drilling is fine for 2-3 levels
- No inline styles; no Tailwind/CSS-in-JS
Diffs & Commits
- One logical change per commit
- Minimal, focused diffs — don't silently refactor surrounding code
- Branch naming:
feature/,fix/,docs/,refactor/prefixes
Adding a New Feature (Full Stack)
- Model: Add SQLAlchemy model in
backend/app/models/ - Service: Add business logic in
backend/app/services/ - API: Create Blueprint in
backend/app/api/, register it inapp/__init__.pywithurl_prefix='/api/v1/<feature>' - Frontend API: Add methods to
ApiServiceinfrontend/src/services/api.js - Page: Create page component in
frontend/src/pages/, add route inApp.jsx - Styles: Add SCSS file in
frontend/src/styles/pages/, import inmain.scss
Key Environment Variables
| Variable | Purpose |
|---|---|
SECRET_KEY |
Flask session signing |
JWT_SECRET_KEY |
JWT token signing |
DATABASE_URL |
DB connection string (sqlite:///... or PostgreSQL) |
CORS_ORIGINS |
Comma-separated allowed origins |
FLASK_ENV |
development or production |