Docker & VPS Deployment

Three deployment options: Docker Compose (recommended), VPS manual setup, or shared hosting (cPanel). Choose the one that fits your infrastructure.

Option 1: Docker Compose (Recommended)

The fastest way to deploy MailTrixy. Requires Docker and Docker Compose installed on your server.

Step 1: Clone & Configure

# Upload or clone MailTrixy to your server
cd /opt
unzip mailtrixy.zip -d mailtrixy
cd mailtrixy

# Copy environment file
cp .env.example .env

# Generate application key
php artisan key:generate

Step 2: Create docker-compose.yml

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    volumes:
      - .:/var/www/html
      - ./storage:/var/www/html/storage
    depends_on:
      - mysql
    environment:
      - APP_ENV=production
      - APP_DEBUG=false
    networks:
      - mailtrixy

  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - .:/var/www/html
      - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./docker/ssl:/etc/nginx/ssl
    depends_on:
      - app
    networks:
      - mailtrixy

  mysql:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - mailtrixy

  scheduler:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    command: php artisan schedule:work
    volumes:
      - .:/var/www/html
    depends_on:
      - mysql
    networks:
      - mailtrixy

volumes:
  mysql_data:

networks:
  mailtrixy:
    driver: bridge

Step 3: Create Dockerfile

FROM php:8.2-fpm

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git curl zip unzip libpng-dev libjpeg-dev libfreetype6-dev \
    libonig-dev libxml2-dev libzip-dev libicu-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip intl

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www/html

# Copy application
COPY . .

# Install dependencies
RUN composer install --no-dev --optimize-autoloader

# Set permissions
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache

EXPOSE 9000
CMD ["php-fpm"]

Step 4: Create Nginx Config

# Create docker/nginx.conf
server {
    listen 80;
    server_name your-domain.com;
    root /var/www/html/public;
    index index.php;

    client_max_body_size 50M;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Step 5: Deploy

# Build and start containers
docker-compose up -d --build

# Run migrations and seed
docker-compose exec app php artisan migrate --seed

# Generate app key (if not done)
docker-compose exec app php artisan key:generate

# Create storage link
docker-compose exec app php artisan storage:link

# Build frontend assets
docker-compose exec app npm install && npm run build

# Clear caches
docker-compose exec app php artisan config:cache
docker-compose exec app php artisan route:cache
docker-compose exec app php artisan view:cache

Your MailTrixy instance is now running at http://your-domain.com

Option 2: VPS Manual Setup (Ubuntu 22.04)

Step 1: Install System Packages

sudo apt update && sudo apt upgrade -y

# PHP 8.2 + extensions
sudo add-apt-repository ppa:ondrej/php -y
sudo apt install -y php8.2-fpm php8.2-cli php8.2-mysql php8.2-mbstring \
    php8.2-xml php8.2-bcmath php8.2-zip php8.2-gd php8.2-curl \
    php8.2-intl php8.2-imap

# MySQL 8
sudo apt install -y mysql-server

# Nginx
sudo apt install -y nginx

# Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Node.js 20 (for building frontend)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

Step 2: Configure MySQL

sudo mysql -u root
CREATE DATABASE mailtrixy CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mailtrixy'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON mailtrixy.* TO 'mailtrixy'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 3: Deploy Application

# Upload MailTrixy to /var/www
cd /var/www
unzip mailtrixy.zip -d mailtrixy
cd mailtrixy

# Set permissions
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache

# Install dependencies
composer install --no-dev --optimize-autoloader
npm install && npm run build

# Configure environment
cp .env.example .env
php artisan key:generate
# Edit .env with your database credentials, APP_URL, etc.
nano .env

# Run migrations
php artisan migrate --seed
php artisan storage:link

Step 4: Configure Nginx

sudo nano /etc/nginx/sites-available/mailtrixy

server {
    listen 80;
    server_name your-domain.com;
    root /var/www/mailtrixy/public;
    index index.php;

    client_max_body_size 50M;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

# Enable site
sudo ln -s /etc/nginx/sites-available/mailtrixy /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Step 5: Setup Cron

sudo crontab -u www-data -e

# Add this line:
* * * * * cd /var/www/mailtrixy && php artisan schedule:run >> /dev/null 2>&1

Step 6: SSL with Let's Encrypt

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
# Follow the prompts to complete SSL setup

Option 3: Shared Hosting (cPanel)

  1. Upload the MailTrixy ZIP to your hosting via File Manager or FTP
  2. Extract to a directory (e.g., /home/user/mailtrixy)
  3. Set document root to /home/user/mailtrixy/public in cPanel → Domains
  4. Create MySQL database via cPanel → MySQL Databases
  5. Edit .env via File Manager — set DB credentials, APP_URL
  6. Run setup via SSH or the web installer:
    cd ~/mailtrixy
    php artisan key:generate
    php artisan migrate --seed
    php artisan storage:link
  7. Setup cron in cPanel → Cron Jobs (run every minute):
    cd /home/user/mailtrixy && php artisan schedule:run >> /dev/null 2>&1
Note: MailTrixy works on shared hosting without Redis. It uses database queues and the scheduler processes all background jobs automatically via the single cron job above.

Environment Variables Reference

VariableDescriptionExample
APP_URLYour domain URLhttps://mail.yourdomain.com
APP_ENVEnvironment modeproduction
APP_DEBUGDebug mode (disable in production!)false
DB_HOSTMySQL host127.0.0.1 or mysql (Docker)
DB_DATABASEDatabase namemailtrixy
DB_USERNAMEDatabase usermailtrixy
DB_PASSWORDDatabase passwordyour_secure_password
MAIL_MAILERMail driversmtp or log
QUEUE_CONNECTIONQueue driverdatabase
GOOGLE_CLIENT_IDGmail OAuth client IDFrom Google Cloud Console
GOOGLE_CLIENT_SECRETGmail OAuth secretFrom Google Cloud Console
MICROSOFT_CLIENT_IDOutlook OAuth client IDFrom Azure Portal
MICROSOFT_CLIENT_SECRETOutlook OAuth secretFrom Azure Portal
STRIPE_KEYStripe publishable keypk_live_...
STRIPE_SECRETStripe secret keysk_live_...
STRIPE_WEBHOOK_SECRETStripe webhook signing secretwhsec_...

Troubleshooting

500 Internal Server Error

  • Check storage/logs/laravel.log for the actual error
  • Ensure storage/ and bootstrap/cache/ are writable: chmod -R 775 storage bootstrap/cache
  • Run php artisan config:clear && php artisan cache:clear

Database Connection Refused

  • Verify .env DB credentials match your MySQL setup
  • Docker: use DB_HOST=mysql (service name), not 127.0.0.1
  • Check MySQL is running: sudo systemctl status mysql

Styles/CSS Not Loading

  • Run npm run build to compile assets
  • Run php artisan storage:link
  • Ensure APP_URL matches your actual domain

Emails Not Syncing

  • Ensure the cron job is running: check storage/logs/laravel.log for [Scheduler] entries
  • For Gmail: use an App Password, not your regular password
  • Run manually: php artisan mailtrixy:sync-emails --force

Queue Jobs Not Processing

  • The scheduler handles queue processing automatically via queue:work --stop-when-empty
  • Check pending jobs: php artisan tinker --execute="echo DB::table('jobs')->count();"
  • Check failed jobs: php artisan queue:failed