{"id":47984872,"url":"https://github.com/shukiv/jabali-panel","last_synced_at":"2026-04-04T11:26:43.721Z","repository":{"id":335957102,"uuid":"1131825433","full_name":"shukiv/jabali-panel","owner":"shukiv","description":"Modern web hosting control panel built with Laravel \u0026 Filament. Manage domains, DNS, files, WordPress, MySQL \u0026 PHP - all in one beautiful interface.","archived":false,"fork":false,"pushed_at":"2026-04-02T03:53:57.000Z","size":6190,"stargazers_count":20,"open_issues_count":5,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-04-02T10:56:13.313Z","etag":null,"topics":["hosting","mail","panel","server","vps"],"latest_commit_sha":null,"homepage":"https://jabali-panel.com/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shukiv.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-10T19:09:36.000Z","updated_at":"2026-04-02T03:54:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/shukiv/jabali-panel","commit_stats":null,"previous_names":["shukiv/jabali-panel"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/shukiv/jabali-panel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shukiv%2Fjabali-panel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shukiv%2Fjabali-panel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shukiv%2Fjabali-panel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shukiv%2Fjabali-panel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shukiv","download_url":"https://codeload.github.com/shukiv/jabali-panel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shukiv%2Fjabali-panel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31397699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hosting","mail","panel","server","vps"],"created_at":"2026-04-04T11:26:43.574Z","updated_at":"2026-04-04T11:26:43.699Z","avatar_url":"https://github.com/shukiv.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/images/jabali_logo.svg\" alt=\"Jabali Panel\" width=\"140\"\u003e\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eJabali Panel\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/PHP-8.4-777BB4?logo=php\u0026logoColor=white\" alt=\"PHP 8.4\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Laravel-12-FF2D20?logo=laravel\u0026logoColor=white\" alt=\"Laravel 12\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Filament-5-FDAE4B?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTEyIDJMMiAyMmgyMEwxMiAyeiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=\u0026logoColor=white\" alt=\"Filament 5\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Livewire-4-FB70A9?logo=livewire\u0026logoColor=white\" alt=\"Livewire 4\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Tailwind-4-06B6D4?logo=tailwindcss\u0026logoColor=white\" alt=\"Tailwind 4\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/License-GPL--3.0-blue\" alt=\"GPL-3.0\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Debian-13-A81D33?logo=debian\u0026logoColor=white\" alt=\"Debian 13\"\u003e\n\u003c/p\u003e\n\nA modern web hosting control panel for WordPress and general PHP hosting. Jabali focuses on clean multi-tenant isolation, safe automation, and a consistent admin/user experience. It ships with a privileged agent for root-level tasks, built-in mail and DNS management, migrations from common panels, and an integrated security daemon (jabali-security) for real-time threat detection and automated response. The UI is designed to be fast, predictable, and easy to operate on a single server.\n\nVersion: see `VERSION` (release candidate)\n\nThis is a release candidate. Expect rapid iteration and breaking changes until 1.0.\n\n## Demo and Website\n\n- Website: https://jabali-panel.com/\n- Demo: https://jabali-panel.com/demo/\n\n## Installation\n\nGitHub install:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/shukiv/jabali-panel/main/install.sh | sudo bash\n```\n\nOptional flags:\n\n- `JABALI_MINIMAL=1` for core-only install\n- `JABALI_FULL=1` to force all optional components\n- `--debug` to show full command output instead of spinner\n\nIf Jabali is already installed, the script will detect it and offer to re-install (uninstall + fresh install). Your `.env` and credentials are backed up to `/root/.jabali_reinstall_backup_\u003ctimestamp\u003e/` before wiping.\n\nUninstall:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/shukiv/jabali-panel/main/install.sh | sudo bash -s -- uninstall\n```\n\nForce uninstall (no confirmation prompts, keeps home directories):\n\n```\ncurl -fsSL https://raw.githubusercontent.com/shukiv/jabali-panel/main/install.sh | sudo bash -s -- uninstall --force\n```\n\nAfter install:\n\n- Admin panel: `https://your-host:8443/jabali-admin`\n- User panel: `https://your-host:8443/jabali-panel`\n- Webmail: `https://your-host/webmail`\n\nThe panel runs on port 8443 via FrankenPHP, independent of nginx. If nginx goes down, the panel stays accessible so users can log in and diagnose problems.\n\n## Container Deployment\n\nJabali can run as a single container with all services managed by supervisord (MariaDB, Redis, Nginx, PHP-FPM, jabali-agent, queue-worker, cron, PowerDNS, Stalwart Mail Server). The `Containerfile` uses a multi-stage build based on `debian:bookworm-slim`.\n\n### Quick Start (Docker Hub)\n\n```bash\ndocker pull shukivaknin/jabali-panel:latest\n\ndocker run -d --name jabali \\\n  --hostname panel.example.com \\\n  -p 80:80 -p 443:443 -p 8443:8443 \\\n  -p 25:25 -p 587:587 -p 993:993 -p 110:110 \\\n  -p 53:53/tcp -p 53:53/udp \\\n  -v jabali-mysql:/var/lib/mysql \\\n  -v jabali-storage:/var/www/jabali/storage \\\n  -v jabali-mail:/var/mail \\\n  -v jabali-home:/home \\\n  -v jabali-letsencrypt:/etc/letsencrypt \\\n  -e APP_URL=https://panel.example.com \\\n  -e SERVER_HOSTNAME=panel.example.com \\\n  --cap-add NET_BIND_SERVICE \\\n  --cap-add NET_RAW \\\n  shukivaknin/jabali-panel:latest\n```\n\nThe entrypoint handles first-run initialization (database setup, key generation, migrations, self-signed SSL). Persistent data is stored in the named volumes listed above.\n\nAfter the container starts, create an admin user:\n\n```bash\ndocker exec -it jabali php /var/www/jabali/artisan tinker --execute=\"\n\\$u = new App\\Models\\User();\n\\$u-\u003ename = 'Admin';\n\\$u-\u003eusername = 'admin';\n\\$u-\u003eemail = 'admin@example.com';\n\\$u-\u003epassword = bcrypt('changeme');\n\\$u-\u003eis_admin = true;\n\\$u-\u003esave();\n\"\n```\n\nThen open `https://panel.example.com:8443/jabali-admin` to log in.\n\n### Build from Source\n\nRequires `auth.json` for Filament packages:\n\n```bash\npodman build --secret id=composer_auth,src=auth.json -t jabali-panel:latest .\n```\n\n## Highlights\n\n- Per-user Linux accounts and PHP-FPM isolation\n- SSH shell access via nspawn containers with auto-start and 5-minute idle timeout\n- Root agent for SSL, mail, backups, and migrations\n- Health monitor with auto-restarts and alerts\n- cPanel and WHM migrations with step-by-step logs\n- IMAP sync for migrating mail from external servers\n- Stalwart Mail Server with webmail SSO (Bulwark JMAP client)\n- Shared mailbox folders via Stalwart Mail Server\n- `mail.domain.ext` auto-redirects to webmail\n- One-time login tokens (CLI + dashboard UI) with IP binding\n- PowerDNS with REST API and native DNSSEC\n- Restic backups with deduplication, encryption, and SFTP/S3 support\n- First-time backup setup wizard with encryption password and remote destinations\n- WordPress management (install, updates, and SSO)\n- Integrated security suite (jabali-security) with real-time threat detection\n- Encrypted diagnostic log sharing with ticket tracking\n- Per-user page cache directories (moved from global nginx cache)\n- Passphrase password generator (optional, 3 random words)\n- GoAccess real-time statistics with WebSocket updates\n- Domain bandwidth tracking synced daily from nginx logs\n- 80+ CLI commands with full panel parity (noun:verb pattern)\n- Audit logs and admin notifications\n\n## Feature Map\n\n### Admin Panel\n\n- Dashboard with stats, health, and recent activity\n- User management with suspension and quotas\n- Service manager for systemd services\n- PHP version and pool management\n- DNS zones, templates, and DNSSEC\n- SSL issuance and renewals\n- IP address assignments\n- Backups and restores (local + remote) with first-time setup wizard\n- Migrations (cPanel restore, WHM downloads, IMAP sync)\n- Security (jabali-security daemon with real-time monitoring)\n- One-time login link generator for support access (IP-bound tokens)\n- Diagnostic report (encrypted sharing to support via paste service)\n- Database tuning and query analysis\n- Email queue management with delivery logs\n- Audit logs and notifications\n\n### User Panel\n\n- Domains, redirects, and Nginx config\n- DNS records editor\n- Mail domains, mailboxes, forwarders, shared folders, and per-domain disclaimers\n- IMAP sync (single and bulk mail migration)\n- Webmail SSO (Bulwark, Next.js JMAP client)\n- WordPress manager (install, SSO)\n- File manager plus SFTP/SSH keys\n- SSH shell access via nspawn containers with 5-minute idle timeout\n- Databases (MySQL and PostgreSQL in tabbed view)\n- PHP settings per account\n- SSL management\n- Cron jobs\n- Backups and restore\n- Logs, statistics, and bandwidth usage\n- Support access link generator (one-time IP-bound tokens)\n- Protected directories\n\n### Platform\n\n- Root-level agent for privileged operations\n- Queue-backed jobs for long-running tasks\n- Health monitor with auto-restarts and alerts\n- Redis ACL isolation for WordPress caching\n- Multi-language UI\n\n## Architecture\n\n- Control plane: Laravel 12 app with Filament v5 and Livewire v4\n- Panel web server: FrankenPHP on port 8443 (independent of nginx)\n- Data plane: root agent handling privileged operations via Unix socket\n- Job queue: async tasks and migration steps\n- Webmail: Bulwark (Next.js JMAP client) at `/opt/bulwark`, served at `/webmail/` via nginx proxy to port 3000\n- SSH shell: jabali-isolator (Python, separate repo) managing nspawn containers for SSH access isolation\n- Security: jabali-security daemon (separate repo) with real-time threat detection and automated response\n- Logging: panel and agent logs for troubleshooting\n- Server metrics: live /proc filesystem reads\n\nService stack (single-node default):\n\n- FrankenPHP (panel on port 8443, self-signed or Let's Encrypt SSL)\n- Nginx (user domain sites, phpMyAdmin, webmail proxy, Bulwark proxy)\n- PHP-FPM (user site pools)\n- MariaDB (user databases)\n- Stalwart Mail Server (SMTP, IMAP, JMAP, ManageSieve)\n- PowerDNS (DNS with REST API, MySQL backend)\n- Restic (encrypted, deduplicated backups)\n- Redis\n- GoAccess (real-time web analytics in daemon mode with WebSocket)\n- jabali-isolator (nspawn container management for SSH shell isolation)\n- jabali-security (real-time threat detection, brute-force protection, WAF)\n- Bulwark (Next.js JMAP webmail client on port 3000)\n\n## Requirements\n\n- Fresh Debian 13 install (no pre-existing web or mail stack)\n- A domain for panel and mail (with glue records if hosting DNS)\n- PTR (reverse DNS) for mail hostname\n- Open ports: 22, 80, 443, 8443, 25, 465, 587, 993, 995, 53\n\n## Security Hardening\n\nSee [SECURITY.md](SECURITY.md) for the full security policy, architecture, and audit history.\n\n### Environment Variables\n\n| Variable | Purpose | Default |\n|----------|---------|---------|\n| `TRUSTED_PROXIES` | Comma-separated proxy IPs/CIDRs (or `*` to trust all upstream proxies) | (unset) |\n| `JABALI_INTERNAL_API_TOKEN` | Shared token for internal API calls from non-localhost | (unset) |\n| `JABALI_IMPORT_INSECURE_TLS` | Disable TLS certificate verification for WHM/cPanel migration API calls | `false` |\n| `SESSION_ENCRYPT` | Encrypt session data at rest | `false` |\n| `SESSION_SECURE_COOKIE` | Send session cookies only over HTTPS | `false` |\n| `PANEL_PORT` | HTTPS port for the FrankenPHP panel server | `8443` |\n| `PANEL_HOSTNAME` | Hostname for the panel (used in APP_URL) | (auto-detected) |\n| `PANEL_TLS_CERT` | Path to the panel TLS certificate | `/etc/ssl/jabali/panel.crt` |\n| `PANEL_TLS_KEY` | Path to the panel TLS private key | `/etc/ssl/jabali/panel.key` |\n\n### Key Security Features\n\n- Shell arguments escaped with `escapeshellarg()` to prevent OS command injection\n- Admin impersonation uses one-time IP-bound tokens; stop action requires POST + CSRF\n- DKIM private keys encrypted at rest via Laravel's `encrypted` cast\n- Migration API calls verify TLS certificates by default (opt-out with `JABALI_IMPORT_INSECURE_TLS`)\n- Webmail SSO tokens stored in restricted directory with `0600` permissions and 5-minute expiry\n- Admin backup downloads restricted to allowed directory prefixes\n- WordPress page-cache API uses SHA-256 verification of `AUTH_KEY`\n- CSP, HSTS, and other security headers on all panel responses\n- Git deployment webhooks support signed payloads via `X-Jabali-Signature` / `X-Hub-Signature-256` (HMAC-SHA256)\n\n## Updates\n\nUpdate the panel (code, dependencies, database migrations, and infrastructure):\n\n```\njabali update\n```\n\nThis pulls the latest code from GitHub, runs composer/npm, applies database migrations, rebuilds caches, upgrades infrastructure (PHP config, nginx config, systemd services), and updates jabali-security if installed. Safe to run on a live server — the panel enters maintenance mode during the update.\n\nForce a full update even if already on the latest version:\n\n```\njabali update --force\n```\n\n## CLI\n\nThe `jabali` command uses a noun:verb pattern. All commands support `--json` for machine-readable output and `--yes` to skip confirmations. Aliases: `wordpress` -\u003e `wp`, `database` -\u003e `db`, `email` -\u003e `mail`.\n\n```\njabali user     list|create|delete|show|password|suspend|unsuspend|admin\njabali domain   list|create|delete|show|enable|disable\njabali db       list|create|delete|users|user-create|user-delete|tune\njabali mail     list|create|delete|password|quota|queue|queue-retry|queue-delete|log\njabali ssl      list|status|check|issue|renew|panel|panel-issue\njabali dns      list|records|add|delete-record|sync\njabali backup   list|create|delete|info|restore|password\njabali cron     list|create|delete|toggle|run\njabali php      list|install|uninstall|default\njabali service  list|status|start|stop|restart|enable|disable\njabali system   info|status|disk|memory|hostname|kill\njabali wp       list|install|delete|update|scan|import\njabali agent    ping|status|restart|log\njabali cpanel   analyze|restore|fix-permissions\njabali login    token [--user=] [--ttl=15] [--panel=]\njabali logs     share [--raw] [--ttl=86400]\njabali update   [--force]\n```\n\nSee [docs/cli-reference.md](docs/cli-reference.md) for full signatures and examples.\n\n## Development\n\n```\ncomposer dev\nphp artisan test --compact\n./vendor/bin/pint\n```\n\n### Versioning\n\nThe version string in the `VERSION` file must be kept in sync between the panel codebase and the installer (`install.sh`). When the installer clones the repository during a fresh install, it reads `VERSION` to display the installed version. If you bump the version in one place but not the other, the panel footer and installer output will show different versions.\n\nAlways update `VERSION` in a single commit that includes both the panel changes and any corresponding `install.sh` changes.\n\n## License\n\nGPL-3.0 — see [LICENSE](LICENSE) for details.\n\n## Mail Subdomain\n\nVisiting `mail.domain.ext` in a browser automatically redirects to webmail (Bulwark). Autoconfig and autodiscover paths are excluded so mail client auto-discovery continues to work.\n\n## Documentation\n\nSee the [docs/](docs/) directory for detailed guides:\n\n- [Architecture](docs/architecture.md) — panel, agent, service stack, isolation\n- [CLI Reference](docs/cli-reference.md) — all 80+ commands with signatures\n- [Mail](docs/mail.md) — Stalwart, mailboxes, webmail SSO, DKIM\n- [SSL](docs/ssl.md) — auto SSL, panel cert, certbot, rate limits\n- [DNS](docs/dns.md) — PowerDNS, DNSSEC, CLI commands\n- [Backups](docs/backups.md) — Restic, remote destinations, selective restore\n- [Security](docs/security.md) — jabali-security, WAF, nspawn isolation\n- [One-Time Login](docs/one-time-login.md) — shareable login tokens\n- [Diagnostic Logs](docs/diagnostic-logs.md) — encrypted log sharing\n- [ADRs](docs/adr/) — architecture decision records\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshukiv%2Fjabali-panel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshukiv%2Fjabali-panel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshukiv%2Fjabali-panel/lists"}