# Custom Domain Setup Guide for Multi-Tenant System

**Version:** 1.0  
**Last Updated:** 2025-11-08  
**For:** Multi-Tenant Laravel Application with Stancl/Tenancy

---

## 📚 Table of Contents

1. [Overview](#overview)
2. [Prerequisites](#prerequisites)
3. [Domain Configuration Types](#domain-configuration-types)
4. [DNS Setup](#dns-setup)
5. [Web Server Configuration](#web-server-configuration)
6. [SSL Certificate Setup](#ssl-certificate-setup)
7. [Application Configuration](#application-configuration)
8. [Tenant Domain Setup](#tenant-domain-setup)
9. [Testing](#testing)
10. [Troubleshooting](#troubleshooting)
11. [Production Checklist](#production-checklist)

---

## Overview

This guide explains how to set up **taskcodigital.com** (or any custom domain) for your multi-tenant Laravel application.

### What You'll Achieve

After completing this guide, you'll have:
- ✅ Main domain: `taskcodigital.com` → Central application
- ✅ Wildcard subdomains: `*.taskcodigital.com` → Tenant applications
- ✅ Custom tenant domains: `client.com` → Specific tenant
- ✅ SSL/HTTPS for all domains
- ✅ Automatic tenant identification

### Example Setup

```
taskcodigital.com                    → Central app (tenant creation, admin)
acme.taskcodigital.com              → Tenant: ACME Corp
demo.taskcodigital.com              → Tenant: Demo Company
client-custom-domain.com            → Tenant: Custom domain client
```

---

## Prerequisites

Before starting, ensure you have:

- ✅ Domain name purchased (e.g., taskcodigital.com)
- ✅ Access to domain DNS settings
- ✅ Server with public IP address
- ✅ Root/sudo access to server
- ✅ Laravel application installed
- ✅ Web server (Apache or Nginx) installed
- ✅ PHP 8.1+ and MySQL installed

### Server Information You'll Need

- **Server IP:** Your server's public IP (e.g., 123.45.67.89)
- **Domain registrar:** Where you bought the domain (GoDaddy, Namecheap, etc.)
- **Web server:** Apache or Nginx
- **Application path:** `/var/www/sajjad.site/erp-starterkit`

---

## Domain Configuration Types

### 1. Central Domain (Main Domain)

**Purpose:** Admin panel, tenant creation, central routes

**Domain:** `taskcodigital.com`  
**Points to:** Central application  
**Routes:** Defined in `routes/web.php` (central routes)

### 2. Wildcard Subdomains

**Purpose:** Automatic tenant subdomains

**Domain:** `*.taskcodigital.com`  
**Examples:** 
- `acme.taskcodigital.com`
- `demo.taskcodigital.com`
- `client123.taskcodigital.com`

**Points to:** Tenant applications (auto-identified)  
**Routes:** Defined in `routes/tenant.php`

### 3. Custom Tenant Domains

**Purpose:** Branded domains for premium tenants

**Examples:** 
- `acmecorp.com` → Points to ACME tenant
- `democompany.io` → Points to Demo tenant

**Configuration:** Requires DNS + CNAME/A record + domain table entry

---

## DNS Setup

### Step 1: Access Your Domain DNS Settings

Login to your domain registrar (GoDaddy, Namecheap, Cloudflare, etc.)

### Step 2: Configure DNS Records

Add the following DNS records:

#### A. Main Domain Record

| Type | Name | Value | TTL |
|------|------|-------|-----|
| A | @ | `YOUR_SERVER_IP` | 3600 |

**Example:**
```
Type: A
Name: @
Value: 123.45.67.89
TTL: 3600 (1 hour)
```

This makes `taskcodigital.com` point to your server.

#### B. WWW Subdomain (Optional)

| Type | Name | Value | TTL |
|------|------|-------|-----|
| CNAME | www | taskcodigital.com | 3600 |

**Or use A record:**
```
Type: A
Name: www
Value: 123.45.67.89
TTL: 3600
```

#### C. Wildcard Subdomain Record

| Type | Name | Value | TTL |
|------|------|-------|-----|
| A | * | `YOUR_SERVER_IP` | 3600 |

**Example:**
```
Type: A
Name: *
Value: 123.45.67.89
TTL: 3600
```

This makes `*.taskcodigital.com` (all subdomains) point to your server.

### Step 3: Verify DNS Propagation

```bash
# Check main domain
nslookup taskcodigital.com

# Check wildcard subdomain
nslookup test.taskcodigital.com

# Or use dig
dig taskcodigital.com
dig acme.taskcodigital.com
```

**Expected output:**
```
Name:    taskcodigital.com
Address: 123.45.67.89
```

**Note:** DNS propagation can take 5 minutes to 48 hours. Usually 15-30 minutes.

### DNS Configuration Screenshots

**Example for Cloudflare:**
```
A     @     123.45.67.89     Auto     DNS only
A     *     123.45.67.89     Auto     DNS only
```

**Example for GoDaddy:**
```
Type    Name    Value            TTL
A       @       123.45.67.89     1 Hour
A       *       123.45.67.89     1 Hour
```

---

## Web Server Configuration

Choose your web server:

### Option 1: Apache Configuration

#### Step 1: Enable Required Modules

```bash
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
sudo systemctl restart apache2
```

#### Step 2: Create VirtualHost Configuration

Create file: `/etc/apache2/sites-available/taskcodigital.conf`

```apache
<VirtualHost *:80>
    ServerName taskcodigital.com
    ServerAlias *.taskcodigital.com
    
    DocumentRoot /var/www/sajjad.site/erp-starterkit/public
    
    <Directory /var/www/sajjad.site/erp-starterkit/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/taskcodigital-error.log
    CustomLog ${APACHE_LOG_DIR}/taskcodigital-access.log combined
</VirtualHost>
```

#### Step 3: Enable Site and Restart

```bash
# Enable the site
sudo a2ensite taskcodigital.conf

# Test configuration
sudo apache2ctl configtest

# Restart Apache
sudo systemctl restart apache2
```

---

### Option 2: Nginx Configuration

#### Step 1: Create Server Block

Create file: `/etc/nginx/sites-available/taskcodigital`

```nginx
server {
    listen 80;
    listen [::]:80;
    
    server_name taskcodigital.com *.taskcodigital.com;
    root /var/www/sajjad.site/erp-starterkit/public;
    
    index index.php index.html;
    
    charset utf-8;
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # Main location
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    # PHP handling
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }
    
    # Deny access to hidden files
    location ~ /\.(?!well-known).* {
        deny all;
    }
    
    # Deny access to sensitive files
    location ~ /\.(env|git|svn) {
        deny all;
        return 404;
    }
    
    # Static file handling
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
    }
    
    # Logs
    access_log /var/log/nginx/taskcodigital-access.log;
    error_log /var/log/nginx/taskcodigital-error.log;
}
```

#### Step 2: Enable Site and Restart

```bash
# Create symlink
sudo ln -s /etc/nginx/sites-available/taskcodigital /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx
```

---

## SSL Certificate Setup

### Option 1: Let's Encrypt (Free, Recommended)

#### For Apache

```bash
# Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-apache -y

# Get certificate (interactive)
sudo certbot --apache -d taskcodigital.com -d www.taskcodigital.com

# Get wildcard certificate (requires DNS validation)
sudo certbot --apache -d taskcodigital.com -d *.taskcodigital.com --preferred-challenges dns

# Follow instructions to add DNS TXT record
```

#### For Nginx

```bash
# Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx -y

# Get certificate
sudo certbot --nginx -d taskcodigital.com -d www.taskcodigital.com

# Get wildcard certificate
sudo certbot --nginx -d taskcodigital.com -d *.taskcodigital.com --preferred-challenges dns
```

#### Auto-renewal Setup

```bash
# Test renewal
sudo certbot renew --dry-run

# Certbot automatically creates a cron job
# Verify: 
sudo systemctl status certbot.timer

# Or manually add to crontab
0 0,12 * * * certbot renew --quiet
```

### Option 2: Custom SSL Certificate

If you have a purchased SSL certificate:

#### For Apache

```apache
<VirtualHost *:443>
    ServerName taskcodigital.com
    ServerAlias *.taskcodigital.com
    
    DocumentRoot /var/www/sajjad.site/erp-starterkit/public
    
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/taskcodigital.crt
    SSLCertificateKeyFile /etc/ssl/private/taskcodigital.key
    SSLCertificateChainFile /etc/ssl/certs/taskcodigital-chain.crt
    
    <Directory /var/www/sajjad.site/erp-starterkit/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```

#### For Nginx

```nginx
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    server_name taskcodigital.com *.taskcodigital.com;
    
    ssl_certificate /etc/ssl/certs/taskcodigital.crt;
    ssl_certificate_key /etc/ssl/private/taskcodigital.key;
    ssl_trusted_certificate /etc/ssl/certs/taskcodigital-chain.crt;
    
    # SSL settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # ... rest of configuration
}
```

---

## Application Configuration

### Step 1: Update Environment File

Edit `.env`:

```env
APP_URL=https://taskcodigital.com
APP_ENV=production
APP_DEBUG=false

# Session domain (for subdomains)
SESSION_DOMAIN=.taskcodigital.com

# Database
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=taskco_central
DB_USERNAME=your_username
DB_PASSWORD=your_password

# Tenancy
TENANCY_DATABASE_PREFIX=taskco-
```

### Step 2: Update Tenancy Configuration

Edit `config/tenancy.php`:

```php
return [
    'tenant_model' => \App\Models\Tenant::class,
    'id_generator' => \Stancl\Tenancy\UUIDGenerator::class,

    'central_domains' => [
        'taskcodigital.com',
        'www.taskcodigital.com',
        // Keep localhost for local development
        '127.0.0.1',
        'localhost',
    ],

    'database' => [
        'prefix' => env('TENANCY_DATABASE_PREFIX', 'taskco-'),
        'suffix' => '',
        
        'central_connection' => env('DB_CONNECTION', 'mysql'),
        
        'template_tenant_connection' => null,
        
        'managers' => [
            'mysql' => \Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager::class,
        ],
    ],

    // ... other settings
];
```

### Step 3: Update Session Configuration

Edit `config/session.php`:

```php
return [
    'domain' => env('SESSION_DOMAIN', null),
    'secure' => env('SESSION_SECURE_COOKIE', true),
    'same_site' => 'lax',
    
    // ... other settings
];
```

### Step 4: Clear and Cache Configuration

```bash
# Clear all caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

# Cache for production
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

### Step 5: Set File Permissions

```bash
# Set ownership
sudo chown -R www-data:www-data /var/www/sajjad.site/erp-starterkit

# Set permissions
sudo chmod -R 755 /var/www/sajjad.site/erp-starterkit
sudo chmod -R 775 /var/www/sajjad.site/erp-starterkit/storage
sudo chmod -R 775 /var/www/sajjad.site/erp-starterkit/bootstrap/cache
```

---

## Tenant Domain Setup

### Method 1: Using API (Recommended)

Create a tenant with subdomain:

```bash
curl -X POST https://taskcodigital.com/create-tenant \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "acme",
    "company_name": "ACME Corporation",
    "email": "admin@acme.com",
    "domain": "acme.taskcodigital.com"
  }'
```

### Method 2: Using Tinker

```bash
php artisan tinker
```

```php
// Create tenant
$tenant = \App\Models\Tenant::create([
    'id' => 'acme',
    'company_name' => 'ACME Corporation',
    'email' => 'admin@acme.com'
]);

// Create subdomain
$tenant->domains()->create([
    'domain' => 'acme.taskcodigital.com',
    'is_primary' => true,
    'is_custom' => false,
    'status' => 'active'
]);

// Setup tenant database
Artisan::call('tenant:full-setup', ['tenant' => 'acme']);
```

### Method 3: Adding Custom Domain for Tenant

For a tenant to use their own domain (e.g., `acmecorp.com`):

#### Step 1: Configure DNS (Customer's side)

Customer needs to add:

```
Type: CNAME
Name: @
Value: taskcodigital.com
TTL: 3600
```

Or:

```
Type: A
Name: @
Value: YOUR_SERVER_IP (123.45.67.89)
TTL: 3600
```

#### Step 2: Add Domain to Tenant

```php
$tenant = \App\Models\Tenant::find('acme');

$domain = $tenant->domains()->create([
    'domain' => 'acmecorp.com',
    'is_primary' => false,
    'is_custom' => true,
    'status' => 'pending'
]);

// Add SSL config
$domain->sslConfig()->create([
    'ssl_enabled' => false,
    'ssl_provider' => 'Let\'s Encrypt'
]);

// Add DNS records
$domain->dnsRecords()->create([
    'dns_status' => 'pending'
]);

// Add redirect settings
$domain->redirectSettings()->create([
    'force_https' => true,
    'redirect_enabled' => false
]);
```

#### Step 3: Get SSL for Custom Domain

```bash
sudo certbot --nginx -d acmecorp.com -d www.acmecorp.com
```

#### Step 4: Verify and Activate

```php
// After DNS propagation
$domain->update(['status' => 'active']);

$domain->dnsRecords()->update([
    'dns_status' => 'verified',
    'dns_verified_at' => now()
]);

$domain->sslConfig()->update([
    'ssl_enabled' => true,
    'ssl_expires_at' => now()->addDays(90)
]);
```

---

## Testing

### 1. Test Central Domain

```bash
# HTTP
curl http://taskcodigital.com

# HTTPS
curl https://taskcodigital.com

# Should show central application
```

### 2. Test Tenant Subdomain

```bash
# Create test tenant first
curl -X POST https://taskcodigital.com/create-tenant \
  -H "Content-Type: application/json" \
  -d '{"tenant_id": "test", "company_name": "Test Company"}'

# Test access
curl https://test.taskcodigital.com

# Should show tenant application
```

### 3. Test Wildcard SSL

```bash
# Check SSL certificate
openssl s_client -connect acme.taskcodigital.com:443 -servername acme.taskcodigital.com

# Should show valid certificate for *.taskcodigital.com
```

### 4. Test Tenant Identification

```bash
# Access tenant in browser
https://acme.taskcodigital.com

# Check if tenant is identified
# Should show tenant-specific content
```

### 5. Verify Database Connection

```bash
php artisan tinker
```

```php
// Test tenant identification
tenancy()->initialize('acme');

// Check current tenant
echo tenant('id'); // Should show: acme

// Check database
echo \DB::connection()->getDatabaseName(); // Should show: taskco-acme

// Count users in tenant database
echo \App\Models\User::count();
```

---

## Troubleshooting

### Issue 1: Domain Not Resolving

**Symptoms:** Cannot access domain

**Solutions:**

```bash
# 1. Check DNS propagation
nslookup taskcodigital.com

# 2. Flush DNS cache (local)
# Windows
ipconfig /flushdns

# Mac
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

# Linux
sudo systemd-resolve --flush-caches

# 3. Wait for DNS propagation (up to 48 hours)
```

### Issue 2: SSL Certificate Error

**Symptoms:** "Your connection is not private" or "NET::ERR_CERT_AUTHORITY_INVALID"

**Solutions:**

```bash
# 1. Renew certificate
sudo certbot renew

# 2. Check certificate
sudo certbot certificates

# 3. Force HTTPS redirect (Apache)
# Add to .htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# 4. For Nginx, add redirect in server block
server {
    listen 80;
    server_name taskcodigital.com *.taskcodigital.com;
    return 301 https://$host$request_uri;
}
```

### Issue 3: Tenant Not Found

**Symptoms:** "Tenant could not be identified on domain"

**Solutions:**

```bash
# 1. Verify domain exists in database
php artisan tinker
```

```php
\App\Models\Domain::where('domain', 'acme.taskcodigital.com')->first();
```

```bash
# 2. If missing, create it
$tenant = \App\Models\Tenant::find('acme');
$tenant->domains()->create([
    'domain' => 'acme.taskcodigital.com',
    'is_primary' => true
]);

# 3. Clear cache
php artisan cache:clear
php artisan config:clear
```

### Issue 4: Mixed Content (HTTP/HTTPS)

**Symptoms:** Assets not loading on HTTPS

**Solutions:**

```php
// Add to AppServiceProvider boot() method
if ($this->app->environment('production')) {
    \URL::forceScheme('https');
}
```

### Issue 5: Session Not Working Across Subdomains

**Symptoms:** Logout when switching subdomains

**Solutions:**

```env
# Update .env
SESSION_DOMAIN=.taskcodigital.com
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=lax
```

```bash
php artisan config:clear
php artisan cache:clear
```

### Issue 6: 403 Forbidden

**Symptoms:** Permission denied

**Solutions:**

```bash
# Fix permissions
sudo chown -R www-data:www-data /var/www/sajjad.site/erp-starterkit
sudo chmod -R 755 /var/www/sajjad.site/erp-starterkit
sudo chmod -R 775 /var/www/sajjad.site/erp-starterkit/storage

# Restart web server
sudo systemctl restart apache2  # or nginx
```

### Issue 7: 500 Internal Server Error

**Symptoms:** White screen or 500 error

**Solutions:**

```bash
# 1. Check Laravel logs
tail -f /var/www/sajjad.site/erp-starterkit/storage/logs/laravel.log

# 2. Check web server logs
# Apache
sudo tail -f /var/log/apache2/taskcodigital-error.log

# Nginx
sudo tail -f /var/log/nginx/taskcodigital-error.log

# 3. Enable debug mode temporarily
APP_DEBUG=true  # In .env (ONLY for debugging, disable after)

# 4. Clear caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
```

---

## Production Checklist

### Security

- [ ] SSL certificate installed and working
- [ ] Force HTTPS enabled
- [ ] `APP_DEBUG=false` in production
- [ ] Strong database passwords set
- [ ] `.env` file secured (chmod 600)
- [ ] Security headers configured
- [ ] CSRF protection enabled
- [ ] XSS protection enabled
- [ ] SQL injection protection (using Eloquent ORM)

### Performance

- [ ] Configuration cached (`php artisan config:cache`)
- [ ] Routes cached (`php artisan route:cache`)
- [ ] Views cached (`php artisan view:cache`)
- [ ] OPcache enabled in PHP
- [ ] Database queries optimized
- [ ] Static assets minified
- [ ] CDN configured (optional)
- [ ] Redis/Memcached for caching (optional)

### Backup

- [ ] Database backup scheduled
- [ ] File backup scheduled
- [ ] Backup tested and verified
- [ ] Backup retention policy defined

### Monitoring

- [ ] Server monitoring setup (CPU, RAM, Disk)
- [ ] Application monitoring (Uptime, Performance)
- [ ] Error tracking (Sentry, Bugsnag)
- [ ] Log rotation configured
- [ ] Email notifications for errors

### DNS & Domain

- [ ] DNS records verified
- [ ] TTL optimized (lower for testing, higher for production)
- [ ] Domain auto-renewal enabled
- [ ] SSL auto-renewal configured
- [ ] Wildcard certificate working

### Application

- [ ] Central domains configured
- [ ] Session domain set correctly
- [ ] Email service configured
- [ ] Queue worker running (if using queues)
- [ ] Cron jobs configured
- [ ] Timezone set correctly

---

## Quick Reference Commands

### DNS Verification

```bash
# Check main domain
nslookup taskcodigital.com

# Check subdomain
nslookup acme.taskcodigital.com

# Detailed DNS check
dig taskcodigital.com
dig acme.taskcodigital.com

# Check from different DNS servers
nslookup taskcodigital.com 8.8.8.8  # Google DNS
```

### SSL Commands

```bash
# Get certificate
sudo certbot --nginx -d taskcodigital.com -d *.taskcodigital.com

# Renew certificates
sudo certbot renew

# List certificates
sudo certbot certificates

# Test renewal
sudo certbot renew --dry-run
```

### Laravel Commands

```bash
# Clear all caches
php artisan optimize:clear

# Cache for production
php artisan optimize

# Check routes
php artisan route:list

# List tenants
php artisan tenants:list

# Migrate tenants
php artisan tenants:migrate

# Seed tenants
php artisan tenants:seed
```

### Web Server Commands

```bash
# Apache
sudo systemctl restart apache2
sudo apache2ctl configtest
sudo tail -f /var/log/apache2/error.log

# Nginx
sudo systemctl restart nginx
sudo nginx -t
sudo tail -f /var/log/nginx/error.log
```

---

## Example: Complete Setup for taskcodigital.com

Here's a complete walkthrough for setting up `taskcodigital.com`:

### Step 1: DNS Configuration

Login to your domain registrar and add:

```
Type: A,    Name: @,    Value: 123.45.67.89
Type: A,    Name: *,    Value: 123.45.67.89
```

### Step 2: Nginx Configuration

```bash
sudo nano /etc/nginx/sites-available/taskcodigital
```

```nginx
server {
    listen 80;
    server_name taskcodigital.com *.taskcodigital.com;
    root /var/www/sajjad.site/erp-starterkit/public;
    index index.php;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```

```bash
sudo ln -s /etc/nginx/sites-available/taskcodigital /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```

### Step 3: SSL Certificate

```bash
sudo certbot --nginx -d taskcodigital.com -d *.taskcodigital.com --preferred-challenges dns
```

### Step 4: Application Configuration

```bash
nano /var/www/sajjad.site/erp-starterkit/.env
```

```env
APP_URL=https://taskcodigital.com
SESSION_DOMAIN=.taskcodigital.com
```

Edit `config/tenancy.php`:

```php
'central_domains' => [
    'taskcodigital.com',
    'www.taskcodigital.com',
],
```

```bash
php artisan config:cache
php artisan route:cache
```

### Step 5: Create First Tenant

```bash
curl -X POST https://taskcodigital.com/create-tenant \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "demo",
    "company_name": "Demo Company",
    "email": "admin@demo.com"
  }'
```

### Step 6: Access Tenant

Visit: `https://demo.taskcodigital.com`

Login with: `admin@example.com` / `password`

---

## Support & Resources

### Documentation

- Laravel Documentation: https://laravel.com/docs
- Stancl/Tenancy: https://tenancyforlaravel.com
- Let's Encrypt: https://letsencrypt.org

### Tools

- DNS Checker: https://dnschecker.org
- SSL Checker: https://www.sslshopper.com/ssl-checker.html
- HTTP Headers Checker: https://securityheaders.com

### Need Help?

If you encounter issues not covered in this guide, check:

1. Laravel logs: `storage/logs/laravel.log`
2. Web server logs: `/var/log/nginx/` or `/var/log/apache2/`
3. Application debug mode (temporarily enable `APP_DEBUG=true`)

---

**Last Updated:** 2025-11-08  
**Version:** 1.0
