Skip to content

Architecture

AidiPanel is a server control panel for Ubuntu/Debian. It provisions a complete web stack and a small web panel to manage it. The design goals are a small footprint, fast responses, and isolation between sites.

Components

LayerSoftwareRole
Web serverNginx (mainline)Serves sites, terminates TLS, runs FastCGI Cache
RuntimePHP-FPMOne pool per site; default version 8.5
DatabaseMariaDB / MySQLApplication data
CacheRedisObject cache and session storage
TLSCertbot (Let's Encrypt)Certificates with auto-renewal
FirewallUFW + Fail2banNetwork and brute-force protection
PanelPHP web appWeb UI on port 8443
CLIaidipanelManage the stack from SSH

Request Flow

Browser
   |
   v
Nginx + FastCGI Cache -- hit --> cached response (served from disk)
   |
  miss
   v
PHP-FPM (per-site pool, runs as the site user)
   |
   v
MariaDB / MySQL + Redis

Page caching is handled inside Nginx via FastCGI Cache, so there is no separate caching daemon. Caching is off by default per site and enabled explicitly.

Per-Site Isolation

Each site is provisioned with:

  • a dedicated Linux user with no login shell (/usr/sbin/nologin) and a locked password;
  • a web root at /home/<site-user>/htdocs/<domain>;
  • its own PHP-FPM pool that runs as the site user.

Nginx (www-data) reads each site's static files through group membership; the web root is setgid so files created by PHP keep the right group. Other site users are not in that group and cannot read the files. If one site's PHP is exploited, the process runs only as that site's user — this is per-user process and file isolation, not container-level sandboxing.

A /home/<site-user>/.aidipanel-managed marker (owned root:root) records which user/domain AidiPanel manages. Destructive operations (purge-delete) validate this marker before touching anything, so they can never remove an unmanaged account or directory.

PHP Version Policy

/etc/aidipanel/php.conf is the single source of truth:

sh
PHP_DEFAULT_VERSION="8.5"
PHP_AVAILABLE_VERSIONS="8.2 8.3 8.4 8.5"

Only the default version is installed at provisioning time. Other supported versions are installed on-demand (aidipanel php:install --version <ver>), which keeps installs lean. The CLI sources this file; the panel reads it to list versions and checks the filesystem for install state.

Privileged Operations

The web panel runs as the dedicated aidipanel system user and cannot perform privileged actions directly. Nginx remains www-data and can only connect to the panel FPM socket. The panel invokes a single wrapper, aidipanel-web-run, through a narrowly scoped sudoers rule:

aidipanel ALL=(root) NOPASSWD: /usr/local/sbin/aidipanel-web-run *

The wrapper hard-codes an allowlist of permitted subcommands (defense in depth: the wrapper allowlist and the CLI's own validation). Arguments are passed as separate argv values, never interpolated into a shell string.

Panel Runtime

The panel runs under its own dedicated PHP-FPM service, aidipanel-fpm, on a private socket (/run/aidipanel-fpm.sock), isolated from the site PHP-FPM services so that reloading site pools never affects the panel.

Directory Map

PathPurpose
/opt/aidipanel/Panel application + storage
/etc/aidipanel/php.confPHP version policy
/home/<site-user>/htdocs/<domain>Site web root
/etc/nginx/sites-available/Vhost configs
/var/cache/nginx/fastcgi/FastCGI cache files
/usr/local/bin/aidipanelCLI
/usr/local/sbin/aidipanel-web-runPrivileged wrapper