Configuration
Overview
Laravel Mail Platform stores all configuration in a .env file located in your project root. This file contains database connections, encryption keys, queue settings, and email service credentials.
Important: The
.envfile is sensitive and should never be committed to version control. It contains passwords and API keys. Add it to your.gitignorefile.
Initial Setup
Step 1: Create Your .env File
By default, Laravel Mail Platform does not include a .env file. You'll need to create one:
- Locate the
.env.examplefile in your project root - Make a copy and rename it to
.env - Update the values as needed for your environment
Tip: Run the included setup command to automate most of this. If you do it manually, follow the steps below.
Step 2: Generate an Encryption Key
Laravel Mail Platform encrypts sensitive data like user sessions. An encryption key must exist before the application runs.
If you haven't already generated one, run:
php artisan key:generate
This creates a unique APP_KEY in your .env file.
Warning: Regenerating the key will invalidate all active sessions and make any previously encrypted data inaccessible. Only regenerate if absolutely necessary. If you lose your key, you'll need to reset user sessions.
Step 3: Publish Vendor Files
Publish configuration, views, language files, and assets from the platform:
php artisan vendor:publish --provider="Laravel Mail Platform\\Base\\Laravel Mail LaravelMailServiceProvider"
Essential Configuration
Application URL
Set the base URL where your Laravel Mail Platform installation is hosted. This is used to generate links in emails (unsubscribe links, registration emails, etc.).
APP_URL=https://campaigns.example.com
Replace campaigns.example.com with your actual domain. Include the protocol (https:// or http://).
Important: If this is incorrect, users won't be able to unsubscribe, and email links will break.
Database Connection
Laravel Mail Platform stores all campaigns, subscribers, and analytics in a database. You must configure your database connection before running migrations.
Step 1: Choose Your Database Type
Set DB_CONNECTION to your database provider:
DB_CONNECTION=mysql # for MySQL/MariaDB
DB_CONNECTION=pgsql # for PostgreSQL
Step 2: Configure Connection Details
Add your database host, port, name, and credentials:
DB_HOST=127.0.0.1 # Database server address (127.0.0.1 for local)
DB_PORT=3306 # Database port (3306 for MySQL, 5432 for PostgreSQL)
DB_DATABASE=laravel_mail # Database name
DB_USERNAME=root # Database user
DB_PASSWORD=your_password # Database password
Common scenarios:
- Local development:
DB_HOST=127.0.0.1,DB_PORT=3306 - Remote server:
DB_HOST=db.example.com, use appropriate port - Docker:
DB_HOST=mysql(or your service name), port as exposed
Step 3: Run Database Migrations
Migrations set up the database schema automatically. Run this command once after configuring the connection:
php artisan migrate:fresh --seed
This creates all necessary tables and seeds initial data.
Important: Do not manually modify the database schema. Any changes Laravel Mail Platform needs should be handled through migrations. Manually altering the database can break the application.
Caution:
migrate:freshwill reset your database. On existing installations, usephp artisan migrateinstead to preserve data.
Background Jobs & Queue Processing
Laravel Mail Platform uses a queue system to send emails asynchronously. Without proper queue configuration, campaigns will not send.
Choose a Queue Driver
Set QUEUE_CONNECTION in your .env file to one of three options:
QUEUE_CONNECTION=sync # Synchronous (simple, not recommended for production)
QUEUE_CONNECTION=database # Asynchronous via database (good for small/medium lists)
QUEUE_CONNECTION=redis # Asynchronous via Redis (recommended for large lists)
Queue Option Comparison
| Option | Best For | Setup Complexity | Performance | Notes |
|---|---|---|---|---|
| Sync | Development, testing | None | ⭐ | Users wait for each email to send. Not scalable. |
| Database | Small to medium lists | Low | ⭐⭐⭐ | Uses existing database. Can impact DB performance under heavy load. |
| Redis | Medium to large lists | Medium | ⭐⭐⭐⭐⭐ | Fastest option. Requires separate Redis service. |
Setting Up Sync Queue (Development Only)
Synchronous queues process jobs immediately as they're requested. The user must wait for completion before continuing.
QUEUE_CONNECTION=sync
No additional setup needed, but only suitable for small test campaigns.
Setting Up Database Queue
Database queues run asynchronously, allowing users to continue working while emails send in the background.
Step 1: Set the driver
QUEUE_CONNECTION=database
Step 2: Create the jobs table
php artisan queue:table
php artisan migrate
Step 3: Run a queue worker
In a separate terminal, run:
php artisan queue:work --queue=message-dispatch
php artisan queue:work --queue=webhook-process
Keep these workers running in the background (in production, use a process manager like Supervisor).
Setting Up Redis Queue
Redis is the recommended solution for production. It's fast, scalable, and can handle very large volumes.
Requirements:
- Redis server installed and running on your infrastructure
- PHP Redis extension
Step 1: Install Redis on your server (example for Ubuntu)
sudo apt-get install redis-server
sudo systemctl start redis-server
Step 2: Configure Redis connection
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1 # Redis server address
REDIS_PASSWORD=null # Leave as null if no password (or set a password)
REDIS_PORT=6379 # Redis port
Step 3: Start processing queues with Laravel Horizon
Laravel Horizon provides an easy way to manage Redis queues with automatic autoscaling.
First, publish Horizon's assets:
php artisan horizon:publish
Then start Horizon:
php artisan horizon
Keep Horizon running in the background (use Supervisor in production for auto-restart on failure).
Horizon Autoscaling
By default, Horizon automatically scales between 2–10 processes for webhooks and 2–20 for message dispatch. To customize these limits, edit config/horizon.php:
'supervisor-2' => [
'minProcesses' => 2,
'maxProcesses' => 10,
],
'supervisor-3' => [
'minProcesses' => 2,
'maxProcesses' => 20,
],
Scheduled Tasks (Cron Jobs)
Laravel Mail Platform relies on background tasks that must run every minute. Create a cron job on your server:
* * * * * cd /path/to/your/project && php artisan schedule:run >> /dev/null 2>&1
Replace /path/to/your/project with your actual project path.
Important: Without this cron job, scheduled campaigns won't send, and background tasks won't run.
For more details, see the Laravel documentation on Task Scheduling.
User Management & Registration
Enabling User Registration
To allow users to register or invite team members, set:
LARAVEL_MAIL_REGISTER=true
Enabling Password Resets
By default, users can reset their passwords. To disable this:
LARAVEL_MAIL_PASSWORD_RESET=false
Configure the Email Service
Laravel Mail Platform must be able to send registration, invitation, and password reset emails. This requires a separate email service configuration (different from the email services configured within workspaces).
Note: This is for Laravel Mail Platform's internal emails only—not for campaign emails.
Set MAIL_MAILER to your chosen provider and add the required configuration below.
SMTP or Sendmail
For standard SMTP providers (Gmail, Office 365, custom servers) or sendmail:
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME=Laravel Mail Platform
Common SMTP settings:
- Gmail:
smtp.gmail.com:587with app password - Office 365:
smtp.office365.com:587with TLS - Custom server: Use your server's SMTP credentials
Amazon SES
For AWS Simple Email Service:
MAIL_MAILER=ses
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_DEFAULT_REGION=us-east-1
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME=Laravel Mail Platform
Mailgun
For Mailgun:
MAIL_MAILER=mailgun
MAILGUN_DOMAIN=mg.example.com
MAILGUN_SECRET=your-mailgun-api-key
MAILGUN_ENDPOINT=api.mailgun.net
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME=Laravel Mail Platform
Postmark
For Postmark:
MAIL_MAILER=postmark
POSTMARK_TOKEN=your-postmark-token
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME=Laravel Mail Platform
Important Notes About .env
Blank Values
If you set a configuration key in .env but leave it blank, it will be treated as blank (not ignored). If you don't want to configure a key, remove the entire line rather than leaving it empty.
# Bad: This will be treated as blank
MAIL_PASSWORD=
# Good: Just remove it
Environment-Specific Overrides
For different environments (local, staging, production), create separate .env files or use symbolic linking. Never commit .env to version control—use .env.example as a template instead.
Deployment Checklist
- [ ]
.envfile created and configured - [ ]
APP_KEYgenerated (php artisan key:generate) - [ ]
APP_URLset to your domain - [ ] Database connection configured and tested
- [ ] Migrations run (
php artisan migrate) - [ ] Queue driver configured (sync for dev, redis for production)
- [ ] Queue workers running (or Horizon for Redis)
- [ ] Cron job configured for
schedule:run - [ ] User management email service configured (if needed)
- [ ]
.envadded to.gitignore
Troubleshooting
Campaigns won't send:
- Verify queue workers are running:
php artisan queue:work --queue=message-dispatch - Check that cron job is configured and executing:
* * * * * cd ... && php artisan schedule:run - Confirm
QUEUE_CONNECTIONmatches your setup
Can't register or reset password:
- Ensure
LARAVEL_MAIL_REGISTER=trueandMAIL_MAILERis configured - Test email credentials independently
- Check Laravel logs in
storage/logs/
Database connection errors:
- Verify
DB_HOST,DB_PORT,DB_USERNAME, andDB_PASSWORDare correct - Ensure the database user has permission to access the specified database
- Test connection:
php artisan tinkerthenDB::connection()->getPdo()
Permission denied errors:
- Verify the web server has write access to
storage/andbootstrap/cache/ - Run:
chmod -R 775 storage bootstrap/cache