Installation
Documentation
Quick Start with Docker (Recommended)
The fastest way to get Laravel Mail Platform running is via Docker. This bundles PHP 8.4, RoadRunner (Octane), MySQL, Redis, and Mailpit into a ready-to-use environment.
- Clone the repository:
git clone ... - Start the environment:
make rebuild - Access:
https://localhost:13000
Installation Types
Laravel Mail Platform supports multiple deployment strategies:
- Docker (Recommended) β Automated containerized setup using RoadRunner for high performance.
- Stand-Alone β Traditional PHP/Nginx deployment on your own server.
- Package β Integration into an existing Laravel app.
System Requirements
Before starting, verify your environment meets the minimum requirements:
| Component | Minimum Version | Notes |
|---|---|---|
| PHP | 8.4+ | Modern version with required extensions |
| Git | Any recent version | For cloning the repository |
| Composer | 2.0+ | PHP dependency manager |
| MySQL | 5.7+ | Most common database choice |
| PostgreSQL | 9.4+ | Alternative to MySQL |
| SQLite | 3.33+ | Good for development/testing |
| Web Server | Apache or Nginx | Required to serve the application |
PHP Extensions
Laravel Mail Platform requires these PHP extensions (most come standard):
bcmathβ Mathematical operationsctypeβ Character type checkingcurlβ HTTP requestsdomβ XML/DOM manipulationfileinfoβ File type detectionfilterβ Input filteringgdβ Image manipulation (optional)hashβ Cryptographic hashingjsonβ JSON encoding/decodingmbstringβ Multi-byte string handlingopensslβ Encryption and SSL/TLSpdoβ Database abstractiontokenizerβ PHP code tokenizationxmlβ XML parsingzipβ ZIP file handling (optional)
Check installed extensions:
php -m
Install missing extensions (Ubuntu/Debian):
sudo apt-get install php8.3-bcmath php8.3-curl php8.3-dom php8.3-fileinfo \
php8.3-filter php8.3-gd php8.3-hash php8.3-json php8.3-mbstring \
php8.3-openssl php8.3-pdo php8.3-tokenizer php8.3-xml php8.3-zip
Disk Space
Allocate adequate disk space for:
- Application code: ~200 MB
- Database: Depends on volume (start with 5 GB)
- Logs and temporary files: 1 GB
- Total minimum: 10 GB
Pre-Installation Checklist
Before you begin, prepare:
- [ ] Server with PHP 8.3+ and required extensions
- [ ] Git installed and SSH keys configured (if cloning via SSH)
- [ ] Database server installed and running
- [ ] Empty database created for Laravel Mail Platform
- [ ] Database user with full permissions on that database
- [ ] Web server (Apache or Nginx) installed
- [ ] Domain name pointing to your server (for production)
- [ ] SSL certificate ready (Let's Encrypt is free)
- [ ] 30 minutes for complete setup
Installation Steps
Step 1: Clone the Repository
Clone Laravel Mail Platform from your repository:
cd /var/www
git clone https://github.com/laravelcompany/app.laravelmail.com.git
cd app.laravelmail.com
Or via SSH (if you have SSH keys configured):
git clone git@github.com:laravelcompany/app.laravelmail.com.git
Step 2: Install PHP Dependencies
Navigate to the project root and install all dependencies using Composer:
cd /var/www/app.laravelmail.com
composer install
This may take a few minutes. Composer will:
- Download Laravel Mail Platform core
- Install all required Laravel packages
- Install supporting libraries
- Verify compatibility
If you encounter permission errors:
sudo chown -R $USER:$USER /var/www/app.laravelmail.com
composer install
If you have memory issues:
COMPOSER_MEMORY_LIMIT=-1 composer install
Step 3: Create Environment Configuration
Copy the example environment file and update it for your setup:
cp .env.example .env
Edit .env and set at minimum:
APP_KEY(generate in next step)APP_URL(your domain)DB_CONNECTION(mysql, pgsql, or sqlite)DB_HOST,DB_PORT,DB_USERNAME,DB_PASSWORD,DB_DATABASE
APP_NAME="Laravel Mail Platform"
APP_URL=https://localhost:13000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_mail
DB_USERNAME=laravel_user
DB_PASSWORD=your_secure_password
# Enable HTTPS for Octane/Roadrunner (Development)
OCTANE_HTTPS=true
Note: For local development on port 13000, the application uses self-signed certificates. You will need to accept the security warning in your browser when visiting
https://localhost:13000.
See the Configuration Guide for complete .env setup.
Step 4: Generate Encryption Key
Generate a unique encryption key for your installation:
php artisan key:generate
This creates APP_KEY in your .env file. This key is criticalβlosing it means re-entering all email service credentials.
Backup your key:
grep APP_KEY .env
Store this value securely separate from your server.
Step 5: Create Database and User
For MySQL:
# Connect to MySQL
mysql -u root -p
# Create database
CREATE DATABASE laravel_mail CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# Create user
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'your_secure_password';
# Grant permissions
GRANT ALL PRIVILEGES ON laravel_mail.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;
# Exit
EXIT;
For PostgreSQL:
sudo -u postgres psql
CREATE DATABASE laravel_mail;
CREATE USER laravel_user WITH PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE laravel_mail TO laravel_user;
ALTER ROLE laravel_user SET client_encoding TO 'utf8';
ALTER ROLE laravel_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE laravel_user SET default_transaction_deferrable TO on;
ALTER ROLE laravel_user SET default_transaction_read_only TO off;
\q
Test the connection:
php artisan tinker
DB::connection()->getPdo()
If successful, you'll see connection details. If it fails, check your .env credentials.
Step 6: Run Database Migrations
Set up the database schema:
php artisan migrate:fresh --seed
This creates all necessary tables and seeds initial data.
On existing installations: Use
php artisan migrateto preserve schema, or the smart refresh command below to preserve data.
Step 7: Smart Database Refresh (Development)
If you need to refresh your database schema (re-run migrations and seeds) but want to preserve your existing data (subscribers, campaigns, etc.), use the db:smart-refresh command:
php artisan db:smart-refresh
This command will:
- Backup your data to JSON.
- Wipe and re-seed the database (
migrate:fresh --seed). - Restore your data, merging it with the fresh seeds.
Step 8: Set File Permissions
Ensure the web server can write to necessary directories:
# Find your web server user
ps aux | grep -E '(apache|nginx)' | grep -v root | head -1
# Set permissions (replace www-data if needed)
sudo chown -R www-data:www-data /var/www/app.laravelmail.com
sudo chmod -R 755 /var/www/app.laravelmail.com
sudo chmod -R 775 /var/www/app.laravelmail.com/storage
sudo chmod -R 775 /var/www/app.laravelmail.com/bootstrap/cache
Step 8: Configure Web Server
Configure your web server to serve Laravel Mail Platform from the public directory.
Nginx Configuration
Create /etc/nginx/sites-available/campaigns:
server {
listen 80;
server_name campaigns.example.com;
root /var/www/app.laravelmail.com/public;
index index.php index.html index.htm;
# Redirect all HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name campaigns.example.com;
root /var/www/app.laravelmail.com/public;
index index.php index.html index.htm;
# SSL certificates (use Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/campaigns.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/campaigns.example.com/privkey.pem;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/campaigns /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Apache Configuration
Enable required modules:
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
Create /etc/apache2/sites-available/campaigns.conf:
<VirtualHost *:80>
ServerName campaigns.example.com
Redirect permanent / https://campaigns.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName campaigns.example.com
DocumentRoot /var/www/app.laravelmail.com/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/campaigns.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/campaigns.example.com/privkey.pem
# Security headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
<Directory /var/www/app.laravelmail.com/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
</IfModule>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/campaigns-error.log
CustomLog ${APACHE_LOG_DIR}/campaigns-access.log combined
</VirtualHost>
Enable the site:
sudo a2ensite campaigns.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
Step 9: Set Up SSL Certificate
Use Let's Encrypt for free SSL (recommended):
sudo apt-get install certbot python3-certbot-nginx
# or for Apache:
sudo apt-get install certbot python3-certbot-apache
# Generate certificate
sudo certbot certonly --standalone -d campaigns.example.com
# Auto-renewal (runs daily)
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
Step 10: Configure Cron Jobs (Required)
Laravel Mail Platform uses background tasks. Create a cron job:
sudo crontab -e
Add this line:
* * * * * cd /var/www/app.laravelmail.com && php artisan schedule:run >> /dev/null 2>&1
This runs every minute and processes scheduled tasks like campaign sends and queue workers.
Step 11: Start Queue Workers
Email sending uses a queue system. In production, run queue workers:
# Option 1: Manual (test only)
php artisan queue:work --queue=message-dispatch
# Option 2: Via Supervisor (production recommended)
sudo nano /etc/supervisor/conf.d/laravel-mail.conf
Add to supervisor config:
[program:laravel-mail-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app.laravelmail.com/artisan queue:work --queue=message-dispatch --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/laravel-mail-queue.log
Then:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-mail-queue:*
Step 12: Verify Installation
Test that everything is working:
# Check key is set
grep APP_KEY .env | grep -v "^#"
# Verify database connection
php artisan tinker
DB::connection()->getPdo()
# Check queue workers
php artisan queue:failed # Should return no failures
# Verify cron is set
sudo crontab -l | grep artisan
Visit your domain in a browser:
https://campaigns.example.com
You should see the login page or setup screen.
Post-Installation Setup
Create Admin User
Run the setup command or create a user manually:
php artisan tinker
Then in Tinker:
App\Models\User::create([
'name' => 'Admin User',
'email' => 'admin@example.com',
'password' => Hash::make('secure-password'),
'email_verified_at' => now(),
]);
Or via setup command (if available):
php artisan setup
Configure Email Services
- Log in to Laravel Mail Platform
- Go to Settings β Email Services
- Add your first email service (SendGrid, Postmark, etc.)
- See Email Services Guide for detailed setup
Set Up Initial Subscribers
- Go to Subscribers
- Import or manually add subscriber lists
- Optionally organize with tags
Troubleshooting Installation
"Composer: command not found"
Composer isn't installed. Download it:
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
"PHP version does not satisfy requirement"
You have PHP < 8.3. Install PHP 8.3+:
Ubuntu/Debian:
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php8.3-cli php8.3-fpm
CentOS/RHEL:
sudo yum install php83-php-cli php83-php-fpm
Database Connection Errors
# Verify credentials in .env
cat .env | grep DB_
# Test MySQL connection
mysql -h DB_HOST -u DB_USERNAME -p DB_DATABASE
# Test PostgreSQL connection
psql -h DB_HOST -U DB_USERNAME -d DB_DATABASE
"Permission denied" or "Cannot write to storage"
Fix file permissions:
sudo chown -R www-data:www-data /var/www/app.laravelmail.com
sudo chmod -R 775 /var/www/app.laravelmail.com/storage
sudo chmod -R 775 /var/www/app.laravelmail.com/bootstrap/cache
Page shows "404 Not Found"
Web server isn't pointing to public directory correctly:
Nginx: Verify root /var/www/app.laravelmail.com/public;
Apache: Verify DocumentRoot /var/www/app.laravelmail.com/public
"SQLSTATE[HY000]: General error"
Database migrations didn't run:
php artisan migrate:fresh --seed
Emails Not Sending
- Verify queue workers are running:
sudo supervisorctl status - Check cron job is set:
sudo crontab -l - Review logs:
tail -f storage/logs/laravel.log
"504 Bad Gateway"
PHP-FPM not running:
sudo systemctl status php8.3-fpm
sudo systemctl restart php8.3-fpm
Production Deployment Checklist
Before going live, complete:
- [ ] PHP 8.3+ with all required extensions installed
- [ ] Database created with proper user permissions
- [ ]
.envconfigured with production values - [ ]
APP_KEYgenerated and backed up securely - [ ] Web server (Nginx or Apache) configured
- [ ] SSL certificate installed and auto-renewal enabled
- [ ] Cron job configured for
schedule:run - [ ] Queue workers running via Supervisor
- [ ] File permissions set correctly
- [ ] Database migrations completed
- [ ] Admin user created
- [ ] Backups configured (database and files)
- [ ] Monitoring set up (check logs, queue health)
- [ ] Domain DNS pointed to server
Next Steps
Immediate:
- Configure your environment β Set up database, queues, email services
- Add email services β Connect SendGrid, Postmark, or other providers
- Import subscribers β Add your audience
After Initial Setup:
- Create your first campaign
- Set up monitoring and logging
- Configure automated backups
Production Hardening:
- Enable two-factor authentication for admin users
- Set up IP whitelisting for admin panel
- Configure rate limiting
- Enable detailed logging
Getting Help
Issues during installation?
- Check Troubleshooting Guide
- Review Configuration Guide
- Check Laravel documentation
Deployment help:
- Contact your hosting provider
- Review web server logs:
/var/log/nginx/error.logor/var/log/apache2/error.log - Check application logs:
storage/logs/laravel.log
System Architecture Diagram
βββββββββββββββββββββββββββββββββββββββββββ
β Web Browser / Client β
ββββββββββββββββββββββ¬βββββββββββββββββββββ
β HTTPS
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Nginx/Apache Web Server β
β (Serves public/ directory) β
ββββββββββββββββββββββ¬βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Laravel Mail Platform Application β
β (Routes requests, processes logic) β
ββββββββββββββββββββββ¬βββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β β
βΌ βΌ
ββββββββββββββ ββββββββββββββββ
β Database β β Queue Worker β
β (MySQL/PG) β β (Supervisor) β
ββββββββββββββ ββββββββββββββββ
β
βΌ
ββββββββββββββββββ
β Email Services β
β (SendGrid, SES)β
ββββββββββββββββββ
Quick Reference
Key directories:
/var/www/app.laravelmail.com/β Application root/var/www/app.laravelmail.com/public/β Web-accessible files/var/www/app.laravelmail.com/storage/β Logs, cache, temp files/var/www/app.laravelmail.com/.envβ Environment configuration
Important files:
.envβ Configuration (keep secure!)config/mail.phpβ Mail configurationstorage/logs/laravel.logβ Application logs
Common commands:
php artisan migrate # Run migrations
php artisan db:smart-refresh # Refresh DB preserving data
php artisan cache:clear # Clear cache
php artisan queue:work # Run queue worker (if not using Docker)
php artisan tinker # Interactive shell
make rebuild # Rebuild Docker containers (Recommended)
make down # Stop Docker containers
make shell # Enter application container shell