Advanced Configuration
This article covers configuration scenarios beyond the standard installer defaults: local development with SQLite, Redis for production performance, background queue workers, running behind an Nginx reverse proxy, and more.
1. SQLite for Development
For local development, SQLite eliminates the need for a running MySQL instance.
# .env
DB_CONNECTION=sqlite
Create the SQLite file:
cd /opt/opterius-mail
touch database/database.sqlite
php artisan migrate
SQLite is not suitable for production (it does not support concurrent writes at scale), but it is ideal for quickly spinning up a local instance to work on templates or plugins.
2. Redis for Sessions and Cache
For production installations with many concurrent users, file-based sessions and cache can become a bottleneck. Redis provides fast, shared, in-memory storage.
# .env
CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD= # Leave empty if Redis is on localhost without auth
REDIS_DB=0
REDIS_CACHE_DB=1
Install the Redis PHP extension if not already present:
sudo apt install php8.2-redis
sudo systemctl reload php8.2-fpm
Install Redis server:
sudo apt install redis-server
sudo systemctl enable --now redis-server
Benefits of Redis sessions:
- Sessions persist across PHP-FPM restarts.
- Sessions are shared instantly if you run multiple web workers.
- SSO token nonces (single-use tokens) are stored in cache — Redis ensures they are shared across all processes reliably.
3. Queue Workers for Async Operations
By default, QUEUE_CONNECTION=sync runs all queued jobs inline — no separate process is needed. For operations that are slow or should not block the HTTP response (bulk DKIM key generation, large autoresponder batches, Rspamd training submissions), use a real queue.
# .env
QUEUE_CONNECTION=database # or redis
If using the database driver, create the jobs table:
php artisan queue:table
php artisan migrate
Starting a Queue Worker
php artisan queue:work --sleep=3 --tries=3
In production, manage the worker with Supervisor:
# /etc/supervisor/conf.d/opterius-mail-worker.conf
[program:opterius-mail-worker]
command=php /opt/opterius-mail/artisan queue:work --sleep=3 --tries=3 --max-time=3600
directory=/opt/opterius-mail
user=www-data
numprocs=2
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/opterius-mail-worker.log
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start opterius-mail-worker:*
After deploying code updates, restart workers to pick up new code:
php artisan queue:restart
4. Multiple IMAP Servers
Opterius Mail is designed for a single IMAP server per installation. One .env file, one IMAP host, one set of credentials. If you need to serve users from two different mail servers, run two separate Opterius Mail instances on different ports:
| Instance | Port | IMAP host | Purpose |
|---|---|---|---|
| Instance A | 8090 | 127.0.0.1 (local Dovecot) |
Primary mail server |
| Instance B | 8091 | imap.legacy.company.com |
Legacy system during migration |
Each instance has its own .env, database, and Nginx virtualhost. The installations are completely independent.
5. Reverse Proxy Behind Nginx
To serve Opterius Mail at a subdirectory (e.g., https://mail.example.com/webmail) or to terminate TLS at Nginx:
# /etc/nginx/sites-available/mail.example.com
server {
listen 443 ssl;
server_name mail.example.com;
ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8090;
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;
# Required for file uploads (attachments)
proxy_read_timeout 300;
client_max_body_size 50M;
}
}
Set APP_URL in .env to the public HTTPS URL:
APP_URL=https://mail.example.com
Laravel uses APP_URL and the X-Forwarded-Proto header to correctly generate HTTPS links and detect secure connections. Without X-Forwarded-Proto, redirects will use http:// even though the user is on HTTPS.
6. Changing the Default Port
The default port is 8090. To change it:
- Update the Nginx server block to listen on the new port.
- Update
APP_URLin.env:
APP_URL=http://your-server:9000
- If Opterius Panel is integrated, update the
mail_urlin the Panel agent config to the new URL. - Update the firewall to allow the new port.
- Reload Nginx and clear config cache.
7. Log Level and Log Channels
For troubleshooting IMAP issues, authentication problems, or plugin errors:
# .env
LOG_LEVEL=debug
LOG_CHANNEL=stack
debug logs every IMAP command and response, every DB query, and all exception traces. This produces very large log files quickly — switch back to error once troubleshooting is complete.
View logs:
tail -f /opt/opterius-mail/storage/logs/laravel.log
Log rotation for the Laravel log is handled by the application itself (daily rotation, 14 days of archives). No external logrotate config is needed.
8. Session Lifetime
The default session lifetime is 120 minutes (2 hours) of inactivity.
SESSION_LIFETIME=480 # 8 hours
For corporate deployments where users keep webmail open all day, a longer session (480–1440 minutes) prevents frustrating logouts. For shared or public machines, reduce the lifetime (30–60 minutes).
The session expires after SESSION_LIFETIME minutes of inactivity (no HTTP requests), not after a fixed time from login.
9. Attachment Upload Size
The maximum attachment size is controlled at two levels:
Nginx:
client_max_body_size 50M;
PHP (/etc/php/8.2/fpm/php.ini):
upload_max_filesize = 50M
post_max_size = 55M
Restart PHP-FPM after changing php.ini:
sudo systemctl reload php8.2-fpm
The default Opterius Panel install sets these to 50M. Adjust both values to match your desired limit.