Overview
Heimdinger.lol is designed to run on Laravel Octane for high-performance request handling. This guide covers production deployment, server requirements, and configuration.
Server Requirements
Minimum Requirements
PHP : 8.2 or higher
Database : MySQL 8.0+ or MariaDB 10.3+
Memory : 512MB minimum, 2GB+ recommended
Extensions : Required PHP extensions
Required PHP Extensions
php -m | grep -E '(pdo|pdo_mysql|mbstring|xml|ctype|json|bcmath|gd)'
Required extensions:
pdo and pdo_mysql
mbstring
xml and dom
ctype
json
bcmath
gd or imagick (for Intervention Image)
curl
openssl
fileinfo
Octane Server Options
Laravel Octane supports multiple application servers:
Swoole (Recommended)
RoadRunner
FrankenPHP
Swoole is the recommended server for production.# Install Swoole via PECL
pecl install swoole
# Or via package manager (Ubuntu)
apt-get install php8.2-swoole
Verify installation: RoadRunner is a Go-based alternative.# Install RoadRunner binary
composer require spiral/roadrunner
./vendor/bin/rr get-binary
Configure in .env: FrankenPHP uses PHP’s native server.
Environment Configuration
Production Environment File
Create a production .env file based on .env.example:
APP_NAME = Heimerdinger
APP_ENV = production
APP_KEY = base64:GENERATE_WITH_php_artisan_key:generate
APP_DEBUG = false
APP_TIMEZONE = Europe/Amsterdam
APP_URL = https://heimerdinger.lol
# Laravel Octane
OCTANE_SERVER = swoole
OCTANE_HTTPS = false # Let reverse proxy handle HTTPS
# Database
DB_CONNECTION = mysql
DB_HOST = 127.0.0.1
DB_PORT = 3306
DB_DATABASE = heimerdinger_db
DB_USERNAME = heimerdinger
DB_PASSWORD = your_secure_password
# Caching
CACHE_STORE = file
SESSION_DRIVER = database
# Data Sources
BORIS_URL = https://boris.heimerdinger.lol
BORIS_API_KEY = your_boris_api_key
RGAPI_KEY = "RGAPI-your-riot-api-key"
# Cloudflare
CLOUDFLARE_ZONE_ID = "your_zone_id"
CLOUDFLARE_AUTH_BEARER = "your_auth_token"
# Discord Logging
DISCORD_ALERT_WEBHOOK = "https://discord.com/api/webhooks/..."
LOG_CHANNEL = stack
LOG_STACK = single,discord
# Security
HCAPTCHA_SECRET = your_hcaptcha_secret
HCAPTCHA_SITEKEY = your_hcaptcha_sitekey
HONEYPOT_NAME = honeypot
# Features
SALES_ENABLED = true
Never commit your production .env file to version control. Keep it secure and backed up separately.
Generate Application Key
This sets APP_KEY which is used for encryption.
Octane Configuration
The Octane configuration is located at config/octane.php.
Key Configuration Options
Choose your application server: 'server' => env ( 'OCTANE_SERVER' , 'roadrunner' ),
Options: swoole, roadrunner, frankenphp
'https' => env ( 'OCTANE_HTTPS' , false ),
Set to false when using a reverse proxy (nginx/Caddy) that handles SSL.
Auto-reload workers when files change (development only): 'watch' => [
'app' ,
'bootstrap' ,
'config' ,
'database' ,
'routes' ,
'.env' ,
],
'max_execution_time' => 30 ,
Set to 0 for no time limit on worker execution.
Deployment Steps
Clone Repository
git clone https://github.com/rico-vz/HeimerdingerLoL.git
cd HeimerdingerLoL
Install Dependencies
composer install --no-dev --optimize-autoloader
npm install
npm run build
The --no-dev flag excludes development dependencies for smaller footprint.
Configure Environment
cp .env.example .env
php artisan key:generate
Edit .env with your production values.
Run Migrations
php artisan migrate --force
The --force flag is required in production.
Optimize Application
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimize
Set Permissions
chmod -R 775 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
Start Octane Server
php artisan octane:start --workers=4 --task-workers=6 --port=8000
Running Octane in Production
Systemd Service
Create a systemd service for automatic startup and management:
/etc/systemd/system/heimerdinger-octane.service
[Unit]
Description =Heimerdinger.lol Octane Server
After =network.target
[Service]
Type =simple
User =www-data
Group =www-data
WorkingDirectory =/var/www/heimerdinger.lol
ExecStart =/usr/bin/php /var/www/heimerdinger.lol/artisan octane:start -- server =swoole -- workers =4 -- task-workers =6 -- port =8000
Restart =always
RestartSec =3
[Install]
WantedBy =multi-user.target
Enable and start the service:
sudo systemctl enable heimerdinger-octane
sudo systemctl start heimerdinger-octane
sudo systemctl status heimerdinger-octane
Supervisor Configuration (Alternative)
Alternatively, use Supervisor:
/etc/supervisor/conf.d/heimerdinger-octane.conf
[program:heimerdinger-octane]
process_name =%(program_name)s
command =php /var/www/heimerdinger.lol/artisan octane:start -- server =swoole -- workers =4 -- task-workers =6 -- port =8000
autostart =true
autorestart =true
stopasgroup =true
killasgroup =true
user =www-data
numprocs =1
redirect_stderr =true
stdout_logfile =/var/www/heimerdinger.lol/storage/logs/octane.log
stopwaitsecs =60
Reload Supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start heimerdinger-octane
Reverse Proxy Configuration
Nginx
/etc/nginx/sites-available/heimerdinger.lol
server {
listen 80 ;
listen [::]:80;
server_name heimerdinger.lol www.heimerdinger.lol;
return 301 https://$ server_name $ request_uri ;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name heimerdinger.lol www.heimerdinger.lol;
ssl_certificate /etc/letsencrypt/live/heimerdinger.lol/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/heimerdinger.lol/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1 ;
proxy_set_header Upgrade $ http_upgrade ;
proxy_set_header Connection 'upgrade' ;
proxy_set_header Host $ host ;
proxy_set_header X-Real-IP $ remote_addr ;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $ scheme ;
proxy_cache_bypass $ http_upgrade ;
}
location ~ /\.(?!well-known).* {
deny all ;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/heimerdinger.lol /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Caddy
Caddy automatically handles HTTPS:
heimdinger.lol www.heimerdinger.lol {
reverse_proxy localhost:8000
encode gzip
}
Reload Caddy:
sudo systemctl reload caddy
Database Setup
Create Database and User
CREATE DATABASE heimerdinger_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER ' heimerdinger '@ 'localhost' IDENTIFIED BY 'secure_password' ;
GRANT ALL PRIVILEGES ON heimerdinger_db. * TO 'heimerdinger' @ 'localhost' ;
FLUSH PRIVILEGES;
Run Migrations
php artisan migrate --force
Database Backups
Configure automated backups with Spatie Backup:
Schedule daily backups in app/Console/Kernel.php:
$schedule -> command ( 'backup:clean' ) -> daily () -> at ( '01:00' );
$schedule -> command ( 'backup:run' ) -> daily () -> at ( '01:30' );
Opcache Configuration
Enable OPcache for PHP bytecode caching:
/etc/php/8.2/cli/conf.d/10-opcache.ini
opcache.enable =1
opcache.enable_cli =1
opcache.memory_consumption =256
opcache.interned_strings_buffer =16
opcache.max_accelerated_files =10000
opcache.validate_timestamps =0 # Production only
Redis Caching (Optional)
For better cache performance:
sudo apt-get install redis-server php8.2-redis
CACHE_STORE = redis
REDIS_HOST = 127.0.0.1
REDIS_PASSWORD = null
REDIS_PORT = 6379
Application Optimization
php artisan optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache
After making config changes, clear caches and reload Octane: php artisan config:clear
php artisan octane:reload
Monitoring & Logging
Laravel Pulse
Access real-time monitoring at:
https://heimerdinger.lol/pulse
Authentication via HTTP Basic Auth (configured in routes/web.php:86).
Discord Logging
Production errors are logged to Discord via webhook:
DISCORD_ALERT_WEBHOOK = "https://discord.com/api/webhooks/your_webhook"
LOG_CHANNEL = stack
LOG_STACK = single,discord
Log Rotation
Configure logrotate:
/etc/logrotate.d/heimerdinger
/var/www/heimerdinger.lol/storage/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data www-data
sharedscripts
}
Deployment Automation
Deployment Script
Create a deployment script:
#!/bin/bash
set -e
echo "Pulling latest changes..."
git pull origin main
echo "Installing dependencies..."
composer install --no-dev --optimize-autoloader
npm install && npm run build
echo "Running migrations..."
php artisan migrate --force
echo "Optimizing application..."
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimize
echo "Generating sitemap..."
php artisan sitemap:generate
echo "Reloading Octane workers..."
php artisan octane:reload
echo "Purging Cloudflare cache..."
php artisan cloudflare:purge
echo "Deployment complete!"
Make executable:
Health Checks
Octane Health Check
curl http://localhost:8000
Database Connection
Queue Workers Status
php artisan queue:work --once
Troubleshooting
Check logs: tail -f storage/logs/laravel.log
Verify Swoole installation: Check port availability:
Fix storage permissions: sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
Clear all caches: php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan octane:reload
Database Connection Failed
Test connection: php artisan tinker
>>> DB::connection () ->getPdo ();
Verify credentials in .env and MySQL user permissions.
Security Checklist
Next Steps
Artisan Commands Learn about maintenance commands
Data Sources Configure API integrations