Files
ADconsle/docs/installation.md
kzbkowskiandClaude Sonnet 5 2b970226fc
CI / PHP 8.4 (push) Failing after 1m5s
ci: require PHP 8.4, test 8.4 only
composer.lock already pins packages that need PHP >= 8.4.1 (symfony/* v8,
nesbot/carbon 3, laravel/pint), so `composer install` on the 8.2 / 8.3 CI
legs has been failing since v1.0.0. Bump composer.json to "php": "^8.4",
regenerate the lock platform block, drop 8.2 / 8.3 from the ci.yml matrix,
and update the "PHP 8.2+" references in the docs. The Docker image was
already php:8.4-apache.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKT9p3bfP8RZesExdYCS52
2026-09-10 09:20:00 +02:00

142 lines
3.5 KiB
Markdown

# 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
<VirtualHost *:443>
ServerName adconsole.example.com
DocumentRoot /var/www/adconsole/public
<Directory /var/www/adconsole/public>
AllowOverride All
Require all granted
</Directory>
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
</VirtualHost>
```
`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.