Index

Stand-Alone Installation

Installation Types

This guide covers stand-alone installation—deploying Laravel Mail Platform as a dedicated application on your own server. This gives you complete control and is ideal for production use.

Other installation options:

  • Package Installation — Integrate Laravel Mail as a package within an existing Laravel application. See the Package Installation Guide.
  • Docker — Deploy using Docker containers (see Docker documentation).

System Requirements

Before starting, verify your environment meets the minimum requirements:

Component Minimum Version Notes
PHP 8.3+ 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 operations
  • ctype — Character type checking
  • curl — HTTP requests
  • dom — XML/DOM manipulation
  • fileinfo — File type detection
  • filter — Input filtering
  • gd — Image manipulation (optional)
  • hash — Cryptographic hashing
  • json — JSON encoding/decoding
  • mbstring — Multi-byte string handling
  • openssl — Encryption and SSL/TLS
  • pdo — Database abstraction
  • tokenizer — PHP code tokenization
  • xml — XML parsing
  • zip — 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/your-repo/laravel-mail-platform.git
cd laravel-mail-platform

Or via SSH (if you have SSH keys configured):

git clone git@github.com:your-repo/laravel-mail-platform.git

Step 2: Install PHP Dependencies

Navigate to the project root and install all dependencies using Composer:

cd /var/www/laravel-mail-platform
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/laravel-mail-platform
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://campaigns.example.com

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

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 migrate instead to preserve data.

Step 7: 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/laravel-mail-platform
sudo chmod -R 755 /var/www/laravel-mail-platform
sudo chmod -R 775 /var/www/laravel-mail-platform/storage
sudo chmod -R 775 /var/www/laravel-mail-platform/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/laravel-mail-platform/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/laravel-mail-platform/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/laravel-mail-platform/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/laravel-mail-platform/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/laravel-mail-platform && 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/laravel-mail-platform/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

  1. Log in to Laravel Mail Platform
  2. Go to SettingsEmail Services
  3. Add your first email service (SendGrid, Postmark, etc.)
  4. See Email Services Guide for detailed setup

Set Up Initial Subscribers

  1. Go to Subscribers
  2. Import or manually add subscriber lists
  3. 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/laravel-mail-platform
sudo chmod -R 775 /var/www/laravel-mail-platform/storage
sudo chmod -R 775 /var/www/laravel-mail-platform/bootstrap/cache

Page shows "404 Not Found"

Web server isn't pointing to public directory correctly:

Nginx: Verify root /var/www/laravel-mail-platform/public; Apache: Verify DocumentRoot /var/www/laravel-mail-platform/public

"SQLSTATE[HY000]: General error"

Database migrations didn't run:

php artisan migrate:fresh --seed

Emails Not Sending

  1. Verify queue workers are running: sudo supervisorctl status
  2. Check cron job is set: sudo crontab -l
  3. 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
  • [ ] .env configured with production values
  • [ ] APP_KEY generated 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:

  1. Configure your environment — Set up database, queues, email services
  2. Add email services — Connect SendGrid, Postmark, or other providers
  3. Import subscribers — Add your audience

After Initial Setup:

Production Hardening:


Getting Help

Issues during installation?

Deployment help:

  • Contact your hosting provider
  • Review web server logs: /var/log/nginx/error.log or /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/laravel-mail-platform/ — Application root
  • /var/www/laravel-mail-platform/public/ — Web-accessible files
  • /var/www/laravel-mail-platform/storage/ — Logs, cache, temp files
  • /var/www/laravel-mail-platform/.env — Environment configuration

Important files:

  • .env — Configuration (keep secure!)
  • config/mail.php — Mail configuration
  • storage/logs/laravel.log — Application logs

Common commands:

php artisan migrate              # Run migrations
php artisan cache:clear         # Clear cache
php artisan queue:work          # Run queue worker
php artisan tinker              # Interactive shell
php artisan serve               # Local dev server