T
Tenanto
Documentation / Troubleshooting

Troubleshooting

Troubleshooting Guide

This guide covers common issues and their solutions when working with Tenanto.

Table of Contents


Docker Issues

Containers Won't Start

Symptoms:

Solutions:

  1. Check Docker Desktop is running

    docker info
    # If error, start Docker Desktop application
    
  2. Check for port conflicts

    # Check what's using port 80
    # Linux/macOS
    sudo lsof -i :80
    # Windows (PowerShell as Admin)
    netstat -ano | findstr :80
    
  3. Stop conflicting services

    # Stop Apache/Nginx if running
    sudo systemctl stop apache2
    sudo systemctl stop nginx
    
    # Or change Tenanto ports in docker-compose.yml
    
  4. Reset Docker containers

    docker compose down
    docker compose up -d --force-recreate
    

Container Exits with Code 137

Cause: Out of memory

Solution:

"Permission Denied" Errors

Symptoms:

Solutions:

# Fix permissions (Linux/macOS)
docker compose exec app chown -R www-data:www-data storage bootstrap/cache
docker compose exec app chmod -R 775 storage bootstrap/cache

# Or from host
sudo chown -R $USER:$USER storage bootstrap/cache
chmod -R 775 storage bootstrap/cache

WSL2 Specific Issues

Docker not connecting from WSL:

  1. Enable WSL2 integration in Docker Desktop:

    • Settings > Resources > WSL Integration
    • Enable for your distro
  2. Restart WSL:

    # In PowerShell as Admin
    wsl --shutdown
    

Vite Dev Server / Frontend Hot Reload

Symptom: Landing page loads but has no styles; DevTools console shows net::ERR_CONNECTION_REFUSED for http://localhost:5273/... or a CSP violation blocking localhost:5273.

Cause A — port 5273 is already in use by another project. Docker Compose will silently bind the wrong container when multiple services try to publish the same host port. Check with:

docker ps --format "table {{.Names}}\t{{.Ports}}" | grep 5273

If more than one container is listed, override the host port in your .env:

VITE_HOST_PORT=5274

Then recreate the vite service (no need to touch the others):

docker compose up -d --force-recreate vite

Remember to update server.origin, server.hmr.clientPort in vite.config.js and the CSP allowances in docker/nginx/sites/tenanto.conf if you change the port — they are hard-coded to 5273 by default. Reload nginx with docker exec tenanto_nginx nginx -s reload after editing the CSP.

Cause B — browser cached the page before the Vite service started. Hard refresh with Ctrl+Shift+R (or Cmd+Shift+R on macOS).

Symptom: Vite container keeps restarting, logs show EACCES when running npm ci.

Cause: The named volume tenanto_vite_node_modules is owned by a user from a previous project. Remove and recreate:

docker compose down
docker volume rm tenantodev_tenanto_vite_node_modules 2>/dev/null || true
docker compose up -d

Symptom: Blade/CSS edits don't reload in the browser on WSL2.

Cause: File system events from Windows → WSL2 → container bind mounts are unreliable. Vite already polls (watch.usePolling: true in vite.config.js). If polling is still too slow, lower the interval from 300 to 150 ms in vite.config.js and restart the vite service.


Installation Problems

"Class Not Found" Errors

Solutions:

# Regenerate autoload
docker compose exec app composer dump-autoload

# Clear all caches
docker compose exec app php artisan optimize:clear

# If still failing, reinstall dependencies
docker compose exec app rm -rf vendor
docker compose exec app composer install

"APP_KEY" Missing

Solution:

docker compose exec app php artisan key:generate

NPM Build Fails

Solutions:

  1. Clear npm cache

    docker compose exec app npm cache clean --force
    docker compose exec app rm -rf node_modules
    docker compose exec app npm install
    
  2. Check Node version

    docker compose exec app node -v
    # Should be 20.x or higher
    
  3. Memory issues during build

    # Increase Node memory
    docker compose exec app NODE_OPTIONS="--max-old-space-size=4096" npm run build
    

Composer Memory Exhausted

Solution:

# Increase PHP memory limit
docker compose exec app php -d memory_limit=-1 /usr/bin/composer install

Database Issues

Connection Refused

Symptoms:

Solutions:

  1. Check database is running

    docker compose ps
    # db container should show "Up"
    
  2. Verify .env settings

    # Docker setup
    DB_CONNECTION=pgsql
    DB_HOST=db          # Container name, not localhost!
    DB_PORT=5432
    DB_DATABASE=tenanto
    DB_USERNAME=tenanto
    DB_PASSWORD=secret
    
  3. Wait for database to be ready

    # Database may take a few seconds to start
    docker compose logs db
    # Look for "database system is ready to accept connections"
    
  4. Test connection manually

    docker compose exec db psql -U tenanto -d tenanto -c "SELECT 1"
    

Migration Fails

Symptoms:

Solutions:

  1. Fresh migration (development only)

    docker compose exec app php artisan migrate:fresh --seed
    
  2. Check migration status

    docker compose exec app php artisan migrate:status
    
  3. Rollback and retry

    docker compose exec app php artisan migrate:rollback
    docker compose exec app php artisan migrate
    

"Unique Constraint Violation" on Seeding

Cause: Seeder already ran

Solution:

# Fresh database with seed
docker compose exec app php artisan migrate:fresh --seed

Authentication Problems

Can't Login to Admin Panel

Symptoms:

Solutions:

  1. Verify default credentials

  2. Check user exists and has correct role

    docker compose exec app php artisan tinker
    >>> User::where('email', '[email protected]')->first()
    >>> # Check tenant_id is NULL for system admin
    
  3. Reset password

    docker compose exec app php artisan tinker
    >>> $user = User::where('email', '[email protected]')->first();
    >>> $user->password = bcrypt('newpassword');
    >>> $user->save();
    

Session Not Persisting

Symptoms:

Solutions:

  1. Check session configuration

    SESSION_DRIVER=redis
    SESSION_DOMAIN=.tenanto.local
    
  2. Clear session data

    docker compose exec app php artisan session:table
    docker compose exec app php artisan migrate
    # Or if using Redis
    docker compose exec redis redis-cli FLUSHDB
    
  3. Check CSRF token

    • Ensure @csrf is in all forms
    • Check browser cookies are enabled

API Token Not Working

Symptoms:

Solutions:

  1. Check Authorization header format

    Authorization: Bearer your-token-here
    
  2. Verify token exists

    docker compose exec app php artisan tinker
    >>> PersonalAccessToken::where('token', hash('sha256', 'your-plain-token'))->first()
    
  3. Check token expiration

    # .env - token lifetime in minutes (default: 7 days)
    SANCTUM_TOKEN_EXPIRATION=10080
    

Multi-Tenancy Issues

Tenant Not Found (404)

Symptoms:

Solutions:

  1. Check DNS/hosts file

    # /etc/hosts or C:\Windows\System32\drivers\etc\hosts
    127.0.0.1 acme.tenanto.local
    
  2. Verify tenant exists and is active

    docker compose exec app php artisan tinker
    >>> Tenant::where('slug', 'acme')->first()
    >>> # Check is_active = true
    
  3. Check tenancy mode

    // config/tenancy.php
    'mode' => 'subdomain', // or 'domain' or 'both'
    
  4. Clear tenant cache

    docker compose exec app php artisan cache:clear
    

Data Leaking Between Tenants

CRITICAL SECURITY ISSUE

Immediate Steps:

  1. Verify global scope is applied

    docker compose exec app php artisan tinker
    >>> app()->bound('currentTenant')
    >>> # Should return true when in tenant context
    
  2. Check model uses BelongsToTenant trait

    class YourModel extends Model
    {
        use BelongsToTenant;
    }
    
  3. Run tenant isolation tests

    docker compose exec app php artisan test --filter=TenantIsolation
    
  4. Check for withoutGlobalScopes usage

    • Search codebase for withoutGlobalScopes
    • Should ONLY be used in admin context

Tenant User Can't Access Panel

Solutions:

  1. Check user belongs to tenant

    docker compose exec app php artisan tinker
    >>> $user = User::find(1);
    >>> $user->tenant_id // Should match tenant
    
  2. Check user has required role

    >>> $user->roles->pluck('name')
    >>> # Should include 'owner', 'admin', or 'member'
    
  3. Verify Spatie permission team is set

    • Middleware should set setPermissionsTeamId($tenant->id)

Billing/Stripe Issues

Webhooks Not Received

Symptoms:

Solutions:

  1. Check webhook URL in Stripe Dashboard

    • Should be: https://yourdomain.com/stripe/webhook
  2. Verify webhook secret

    STRIPE_WEBHOOK_SECRET=whsec_xxx
    
  3. Test webhook locally with Stripe CLI

    stripe listen --forward-to localhost/stripe/webhook
    
  4. Check webhook logs

    docker compose exec app tail -f storage/logs/laravel.log | grep -i stripe
    

"No Such Customer" Error

Cause: Tenant doesn't have Stripe customer ID

Solution:

docker compose exec app php artisan tinker
>>> $tenant = Tenant::find(1);
>>> $tenant->createAsStripeCustomer();

Subscription Not Creating

Solutions:

  1. Check Stripe API keys

    STRIPE_KEY=pk_test_xxx
    STRIPE_SECRET=sk_test_xxx
    
  2. Verify price IDs exist in Stripe

    STRIPE_PRICE_BASIC=price_xxx
    
  3. Check Stripe logs

    • Stripe Dashboard > Developers > Logs

Queue/Worker Issues

Jobs Not Processing

Symptoms:

Solutions:

  1. Check queue worker is running

    docker compose ps
    # 'queue' container should be "Up"
    
  2. Check Redis connection

    docker compose exec redis redis-cli PING
    # Should return "PONG"
    
  3. View failed jobs

    docker compose exec app php artisan queue:failed
    
  4. Retry failed jobs

    docker compose exec app php artisan queue:retry all
    
  5. Restart queue worker

    docker compose restart queue
    

Jobs Failing Silently

Solution: Check logs

docker compose exec app tail -f storage/logs/laravel.log
docker compose logs queue

Horizon Dashboard Shows "Inactive"

Solutions:

  1. Restart Horizon

    docker compose exec app php artisan horizon:terminate
    docker compose restart queue
    
  2. Check Horizon configuration

    docker compose exec app php artisan horizon:status
    

Performance Issues

Slow Page Loads

Diagnosis:

# Enable query logging
docker compose exec app php artisan tinker
>>> DB::enableQueryLog();
>>> // Navigate to slow page
>>> DB::getQueryLog();

Common Causes & Solutions:

  1. N+1 Queries

    • Use eager loading: ->with(['relation'])
    • Use ->withCount() for counts
  2. Missing indexes

    • Check EXPLAIN on slow queries
    • Add indexes for WHERE/ORDER BY columns
  3. Cache not enabled

    CACHE_STORE=redis
    

High Memory Usage

Solutions:

  1. Use chunking for large datasets

    Model::chunk(100, function ($records) {
        // Process
    });
    
  2. Clear caches regularly

    docker compose exec app php artisan cache:clear
    

Redis Memory Full

Solution:

docker compose exec redis redis-cli INFO memory
docker compose exec redis redis-cli FLUSHDB

API Issues

429 Too Many Requests

Cause: Rate limit exceeded

Solutions:

  1. Wait and retry - Default limits:

    • Auth endpoints: 10/minute
    • General API: 60/minute
    • Read operations: 120/minute
  2. For testing, increase limits in app/Providers/AppServiceProvider.php

CORS Errors

Symptoms:

Solutions:

  1. Configure allowed origins

    CORS_ALLOWED_ORIGINS=https://yourfrontend.com
    
  2. Check config/cors.php

    'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '')),
    

500 Internal Server Error

Diagnosis:

# Check Laravel logs
docker compose exec app tail -100 storage/logs/laravel.log

# Check PHP errors
docker compose logs app

Filament Panel Issues

Resources Not Showing

Solutions:

  1. Check user has permission

    docker compose exec app php artisan tinker
    >>> $user->can('view_projects')
    
  2. Clear Filament cache

    docker compose exec app php artisan filament:cache-components
    
  3. Check resource is registered

    • Verify resource is in correct Panel Provider

Form Validation Not Working

Solution: Clear views

docker compose exec app php artisan view:clear

Widgets Not Loading

Solutions:

  1. Check Livewire is working

    docker compose exec app php artisan livewire:discover
    
  2. Check browser console for JavaScript errors

  3. Clear all caches

    docker compose exec app php artisan optimize:clear
    

Getting More Help

If your issue isn't covered here:

  1. Check the logs first

    docker compose exec app tail -f storage/logs/laravel.log
    
  2. Search existing documentation

  3. Contact support

    • Email: your configured SUPPORT_EMAIL address
    • Include: PHP version, error logs, steps to reproduce

Quick Reference Commands

# Clear all caches
docker compose exec app php artisan optimize:clear

# Restart everything
docker compose down && docker compose up -d

# Check service status
docker compose ps

# View logs
docker compose logs -f app

# Database fresh start (DESTROYS DATA)
docker compose exec app php artisan migrate:fresh --seed

# Run tests
docker compose exec app php artisan test

# Check queue status
docker compose exec app php artisan queue:failed