Installation

This guide walks you through a clean install, safe upgrades, and a clean removal. It includes prerequisites, command examples, and post-install checks so you can validate services, firewall, and DNS before going live. It walks through the core settings, common workflows, and the checks to run after changes so you can confirm everything is working. Use it when setting up, updating, or troubleshooting installation.

System requirements

  • Fresh Debian 13 install (no pre-existing web or mail stack)
  • Root access on the server
  • A domain for the panel and mail (with glue records if you host DNS)
  • PTR (reverse DNS) for the mail hostname
  • Open ports: 22, 80, 443, 25, 465, 587, 993, 995, 53

GitHub install

Run the installer from GitHub:

curl -fsSL https://raw.githubusercontent.com/shukiv/jabali-panel/main/install.sh | sudo bash

Optional flags:

  • JABALI_MINIMAL=1 for core-only install
  • JABALI_FULL=1 to force all optional components
  • --debug for verbose output

The installer clones the panel to /var/www/jabali and configures services, nginx, SSL, and required system packages.

Upgrades

From the panel directory:

cd /var/www/jabali
php artisan jabali:upgrade

Check for updates only:

php artisan jabali:upgrade --check

Container deployment

Jabali can run as a single container with all 13 services managed by supervisord (MariaDB, Redis, Nginx, PHP-FPM, jabali-agent, queue-worker, cron, BIND9, OpenDKIM, Rspamd, Postfix, Dovecot, fail2ban).

Quick Start (Docker Hub)

docker pull shukivaknin/jabali-panel:latest
docker run -d --name jabali
--hostname panel.example.com
-p 80:80 -p 443:443
-p 25:25 -p 587:587 -p 993:993 -p 110:110
-p 53:53/tcp -p 53:53/udp
-v jabali-mysql:/var/lib/mysql
-v jabali-storage:/var/www/jabali/storage
-v jabali-mail:/var/mail
-v jabali-home:/home
-v jabali-letsencrypt:/etc/letsencrypt
-e APP_URL=https://panel.example.com
-e SERVER_HOSTNAME=panel.example.com
--cap-add NET_BIND_SERVICE
--cap-add NET_RAW
shukivaknin/jabali-panel:latest

The entrypoint handles first-run initialization (database setup, key generation, migrations, self-signed SSL). Persistent data is stored in the named volumes listed above.

After the container starts, create an admin user:

docker exec -it jabali php /var/www/jabali/artisan tinker --execute="
$u = new AppModelsUser();
$u->name = 'Admin';
$u->username = 'admin';
$u->email = 'admin@example.com';
$u->password = bcrypt('changeme');
$u->is_admin = true;
$u->save();
"

Then open https://panel.example.com/jabali-admin to log in.

Build from source

Requires auth.json for Filament packages:

podman build --secret id=composer_auth,src=auth.json -t jabali-panel:latest .

Uninstall

Before uninstalling, take backups of panel data and user content.

Stop and disable services:

sudo systemctl stop jabali-agent jabali-queue jabali-health-monitor
sudo systemctl disable jabali-agent jabali-queue jabali-health-monitor

Remove packages (keep configs) or purge (remove configs):

sudo apt remove jabali-panel jabali-deps
# or
sudo apt purge jabali-panel jabali-deps

Optional cleanup (removes panel files and configs):

sudo rm -rf /var/www/jabali
sudo rm -rf /etc/jabali
sudo rm -rf /etc/nginx/jabali
sudo rm -rf /etc/ssl/jabali
sudo rm -f /root/.jabali_db_credentials
sudo rm -f /root/jabali_credentials.txt

If you want to remove the panel database and user:

sudo mysql -e "DROP DATABASE IF EXISTS jabali;"
sudo mysql -e "DROP USER IF EXISTS jabali@localhost;"

Post-install URLs

  • Admin panel: https://your-host/jabali-admin
  • User panel: https://your-host/jabali-panel
  • Webmail: https://your-host/webmail

Troubleshooting

  • If the panel does not load, confirm nginx is running and ports 80/443 are open.
  • Check service status with systemctl status jabali-agent jabali-queue jabali-health-monitor.
  • Review logs in storage/logs and system journal output.