# Installation (bare metal / VM) For the containerised path see [deployment.md](deployment.md); this page covers a classic PHP host. ## 1. Prerequisites - PHP **8.4+** with extensions: `ldap`, `pdo_mysql` (or `pdo_pgsql` / `pdo_sqlite`), `mbstring`, `curl`, `zip`, `openssl`, `fileinfo`, `ctype`, `json` - Composer 2 - A web server (Apache with `mod_rewrite`, or nginx + PHP-FPM) - A database server — MariaDB 10.6+ / MySQL 8 recommended - Outbound access to a domain controller on **636/tcp** (LDAPS) or **389/tcp** (STARTTLS) Check the LDAP extension: ```sh php -m | grep -i ldap ``` ## 2. Get the code ```sh git clone https://gitea.kzbikowski.pl/kzbkowski/ADconsle.git /var/www/adconsole cd /var/www/adconsole composer install --no-dev --optimize-autoloader ``` ## 3. Environment ```sh cp .env.example .env php artisan key:generate ``` Edit `.env` — at minimum: - `APP_URL` — the exact public URL (scheme + host, no trailing slash) - `APP_ENV=production`, `APP_DEBUG=false` - `DB_*` — database connection - `LDAP_HOSTS`, `LDAP_USERNAME`, `LDAP_PASSWORD`, `LDAP_BASE_DN` - `LDAP_SSL=true` (or `LDAP_TLS=true`), `LDAP_TLS_VERIFY` - `LDAP_DEFAULT_USER_OU` / `_COMPUTER_OU` / `_GROUPS_OU`, `AD_DOMAIN_LABEL` - `AD_LOGIN_GROUP` — the AD group whose members may sign in Every key is explained in [configuration.md](configuration.md). ## 4. Database Create the schema (sessions, cache, queue, `panel_settings`, `panel_attributes`, `panel_audit`): ```sh php artisan migrate --force ``` ## 5. Caches & storage ```sh php artisan storage:link php artisan config:cache php artisan route:cache php artisan view:cache ``` Make `storage/` and `bootstrap/cache/` writable by the web-server user: ```sh chown -R www-data:www-data storage bootstrap/cache find storage bootstrap/cache -type d -exec chmod 775 {} \; ``` Re-run the three `*:cache` commands (or `php artisan optimize`) after **any** `.env` change. ## 6. Web server **Document root must be `public/`.** Never expose the project root. ### Apache ```apache ServerName adconsole.example.com DocumentRoot /var/www/adconsole/public AllowOverride All Require all granted SSLEngine on SSLCertificateFile /etc/ssl/certs/adconsole.pem SSLCertificateKeyFile /etc/ssl/private/adconsole.key ErrorLog ${APACHE_LOG_DIR}/adconsole-error.log CustomLog ${APACHE_LOG_DIR}/adconsole-access.log combined ``` `a2enmod rewrite ssl && systemctl reload apache2`. Laravel ships the matching `public/.htaccess`. ### nginx + PHP-FPM ```nginx server { listen 443 ssl; server_name adconsole.example.com; root /var/www/adconsole/public; index index.php; ssl_certificate /etc/ssl/certs/adconsole.pem; ssl_certificate_key /etc/ssl/private/adconsole.key; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/run/php/php8.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } } ``` ## 7. First login Open `APP_URL`, pick a language, sign in with an AD account that belongs to `AD_LOGIN_GROUP`. If it rejects you, see [troubleshooting.md](troubleshooting.md#i-cannot-log-in). ## 8. Scheduler / queue (optional) ADconsole has no cron jobs or queued work today, so no `schedule:run` or `queue:work` is required. `QUEUE_CONNECTION=database` is a safe default if you add async work later.