Skip to content

Installation & Local Configuration

End-to-end plan to install and configure SaleOS on a developer machine: backend API, React SPA, VitePress docs, Laravel Reverb, email, queues, and related services.

AudienceGo here
Local developmentThis page
Production on Laravel ForgeLaravel Forge Deployment
Go-live checklistProduction Runbook
Realtime / Redis / Web PushNotification System

Repositories

Clone the three sibling repos next to each other (recommended layout):

text
DC-SaaS/
├── SaaS-Backend/    # Laravel 13 API (Herd: saas-backend.test)
├── SaaS-Frontend/   # React 19 + Vite SPA (localhost:5173)
└── SaaS-Docs/       # VitePress docs (docs:dev)
RepoRoleDefault local URL
SaaS-BackendCentral + Tenant APIs, queues, Reverb, schedulerhttp://saas-backend.test
SaaS-FrontendCentral admin + tenant workspace SPAhttp://localhost:5173
SaaS-DocsProduct / developer / ops documentationhttp://localhost:5173 (separate process)

Prerequisites

ToolVersion / notes
PHP8.3+ (project targets 8.4 via Herd)
Composer2.x
MySQL8+ (or MariaDB / PostgreSQL / SQLite for experiments)
Node.js20+ LTS
npm10+
Laravel HerdRecommended on Windows/macOS — serves saas-backend.test with PHP-FPM
RedisOptional locally; required in production for cache/queue/Reverb scale

Optional: Stripe CLI (billing webhooks), Mailpit/Mailhog (SMTP catcher), ngrok (provider webhooks).


1. Backend (SaaS-Backend)

1.1 Install dependencies and bootstrap

bash
cd SaaS-Backend
composer install
cp .env.example .env
php artisan key:generate

Or use the Composer setup script (install + .env + key + migrate):

bash
composer run setup

Link public storage for local uploads:

bash
php artisan storage:link

1.2 Point Herd at the app

With Laravel Herd installed, park or link the project so it resolves as http://saas-backend.test (folder name saas-backend → Herd site). Confirm:

bash
herd sites

Do not rely on php artisan serve for day-to-day work unless Herd is unavailable.

1.3 Core .env (local)

Backend .env.example is production-shaped (api.example.com / app.example.com / reverb.example.com, Redis + Reverb). After cp .env.example .env, override for local:

env
APP_NAME="SaleOS"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://saas-backend.test
FRONTEND_URL=http://localhost:5173
CORS_ALLOWED_ORIGINS=http://localhost:5173

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=saas_backend
DB_USERNAME=root
DB_PASSWORD=

SESSION_DRIVER=database
SESSION_ENCRYPT=false
SESSION_SECURE_COOKIE=false
QUEUE_CONNECTION=database
CACHE_STORE=database
FILESYSTEM_DISK=public
BROADCAST_CONNECTION=reverb

REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080
REVERB_ALLOWED_ORIGINS=http://localhost:5173

PLATFORM_DOMAIN_SUFFIXES=localhost
VariablePurpose
APP_URLAPI public URL (Herd site)
FRONTEND_URLSPA origin for password-reset / invite links and CORS
CORS_ALLOWED_ORIGINSExtra SPA origins (e.g. http://127.0.0.1:5173 for Windows E2E)
PLATFORM_DOMAIN_SUFFIXESPlatform subdomain suffixes (local: localhost)

Local cache/queue on database is fine. Production requires Redis with Reverb — Laravel Forge · Production Runbook.

1.4 Migrate and seed (local / greenfield only)

bash
php artisan migrate
php artisan db:seed --class=Database\\Seeders\\Central\\CentralDatabaseSeeder

Fresh wipe (destroys data):

bash
php artisan migrate:fresh --seed

Never run db:seed / catalog seeders on production. Modules and permissions ship via migrate-only data migrations (Upgrade Guide).

1.5 Default central login

After seeding:

FieldValue
Central URLhttp://localhost:5173/central/login (SPA)
Emailsuperadmin@saas.com
Passwordpassword

Also seeded: tester@saas.com, developer@saas.com, admin@saas.com (same password).

1.6 Optional CRM demo data

bash
php artisan local:seed-demo

See Local Demo Data. Aborts when APP_ENV=production.


2. Frontend (SaaS-Frontend)

2.1 Install and env

bash
cd SaaS-Frontend
npm install
cp .env.example .env

Local Vite .env:

env
VITE_APP_NAME=SaleOS
VITE_API_URL=http://saas-backend.test
VITE_API_MODE=central
VITE_REVERB_APP_KEY=saleos-reverb-key
VITE_REVERB_HOST=localhost
VITE_REVERB_PORT=8080
VITE_REVERB_SCHEME=http
VariablePurpose
VITE_API_URLBackend base URL (no trailing /api)
VITE_API_MODEcentral or tenant default context
VITE_REVERB_*Must match backend REVERB_* / public Echo settings

Production does not bake these into CI artifacts. Forge generates /config.jswindow.env from the site .env at deploy time (frontend build artifacts).

2.2 Run the SPA

bash
npm run dev

Open the URL Vite prints (default http://localhost:5173).

  • Central admin: /central/login
  • Tenant workspace: /login (Workspace slug or domain)

2.3 Playwright (optional)

bash
cp .env.e2e.example .env.e2e
# Align E2E_API_URL / E2E_ADMIN_* with your backend seed
npm run test:e2e

3. Docs (SaaS-Docs)

bash
cd SaaS-Docs
npm ci
npm run docs:dev

Open the printed URL. Production docs deploy from the build-artifacts branch (CI builds VitePress; Forge only activates the release) — Laravel Forge Deployment.

Local production build check:

bash
npm run docs:build
npm run docs:preview

4. Reverb (realtime)

Realtime notifications use Laravel Reverb → Echo in the SPA. Align keys on both repos.

4.1 Backend .env

env
BROADCAST_CONNECTION=reverb

REVERB_APP_ID=saleos
REVERB_APP_KEY=saleos-reverb-key
REVERB_APP_SECRET=saleos-reverb-secret
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080
REVERB_ALLOWED_ORIGINS=http://localhost:5173
REVERB_APP_ACCEPT_CLIENT_EVENTS_FROM=none

Echo private-channel auth uses POST /broadcasting/auth (already in CORS paths).

4.2 Frontend .env

env
VITE_REVERB_APP_KEY=saleos-reverb-key
VITE_REVERB_HOST=localhost
VITE_REVERB_PORT=8080
VITE_REVERB_SCHEME=http

Omit VITE_REVERB_* only if you intentionally disable Echo.

4.3 Start Reverb

In a dedicated terminal:

bash
cd SaaS-Backend
php artisan reverb:start

Production: supervised process behind TLS, SPA origin pinned — Notification System runbook.


5. Email

5.1 Local default (log driver)

Keep MAIL_MAILER=log locally (also the template default until Settings → Mail is configured):

env
MAIL_MAILER=log
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

Messages are written to storage/logs/laravel.log — enough for password-reset link debugging without an SMTP server.

5.2 Local SMTP catcher (optional)

Point Laravel at Mailpit / Mailhog / similar:

env
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_SCHEME=null

Keep FRONTEND_URL=http://localhost:5173 so reset/invite links open the SPA.

5.3 Central / Tenant Settings (preferred for real providers)

Runtime mail is driven by Central and Tenant settings (SMTP, Postmark, Mailgun), not only .env:

  1. Sign in as central superadmin → Settings → Mail
  2. Choose provider, save credentials, Send test
  3. Tenant workspaces inherit Central (mail_mode=system) or use custom credentials

Env fallbacks when DB secrets are empty: POSTMARK_API_KEY, MAILGUN_DOMAIN, MAILGUN_SECRET, etc.

Details: Multi-Provider Email, Email Webhooks, Authentication ops.

5.4 Email queue

Outbound mail / mail notifications use the emails queue. Always process it:

bash
php artisan queue:work --queue=emails,default --sleep=1 --tries=3

Restart workers after changing mail credentials (php artisan queue:restart).


6. Queues, scheduler, and Web Push

6.1 Queue worker (required for mail + notifications)

bash
cd SaaS-Backend
php artisan queue:work --queue=emails,default

Local QUEUE_CONNECTION=database is fine. Production should use Redis.

6.2 Scheduler (local)

Laravel schedule (pruning, CRM due digests, subscription expiry, etc.) needs a one-minute tick:

bash
php artisan schedule:work

Or a cron entry pointing at php artisan schedule:run.

6.3 Web Push (optional locally)

Generate VAPID keys once (do not commit real keys):

bash
php artisan tinker --execute "print_r(Minishlink\WebPush\VAPID::createVapidKeys());"
env
VAPID_SUBJECT=mailto:admin@example.com
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=

VAPID_SUBJECT must be a mailto: or https: URI. Without keys, database + Reverb delivery still work; Web Push is skipped gracefully.


7. Optional integrations

Configure only what you are actively developing.

IntegrationLocal setup
Stripe / CashierSet STRIPE_KEY, STRIPE_SECRET, STRIPE_WEBHOOK_SECRET; forward webhooks with Stripe CLI to /webhooks/stripe (or Cashier path). See Stripe / Cashier.
CreemPrefer Central Payment Gateways UI; env CREEM_* as fallback.
Object storageLocal: FILESYSTEM_DISK=public. Production: S3-compatible AWS_*Object Storage.
Branded domainsSet BRANDED_SERVER_IPV4 (and optional CNAME) before verifying custom hosts.
Meta Lead AdsCentral integrations / META_LEAD_ADS_*Meta App Setup (operator) · Meta Lead Ads (architecture).
Nightwatch / Telescope / SentryDisabled by default in .env.example; enable intentionally.

Run these processes while developing (Herd serves PHP; you still need workers and SPA):

TerminalCommandRepo
1(Herd — no command)Backend site live
2php artisan reverb:startSaaS-Backend
3php artisan queue:work --queue=emails,defaultSaaS-Backend
4php artisan schedule:workSaaS-Backend (optional)
5npm run devSaaS-Frontend
6npm run docs:devSaaS-Docs (when editing docs)

9. Verify the install

  • [ ] GET http://saas-backend.test/up returns 200
  • [ ] Central login works with superadmin@saas.com / password
  • [ ] SPA calls API (VITE_API_URL matches Herd host; no CORS errors)
  • [ ] Password-reset mail appears in log / Mailpit when requested
  • [ ] Queue worker processes a test mail / notification job
  • [ ] Reverb is running; SPA has matching VITE_REVERB_* (notification bell updates live when Echo is enabled)
  • [ ] php artisan local:seed-demo (optional) creates demo workspace demo-crm.localhost
  • [ ] Docs site builds: npm run docs:build in SaaS-Docs

10. Production (Laravel Forge)

Do not treat local Herd + npm run dev as a production recipe. On Forge you run three sites:

SiteBranchWhat Forge runs
API (SaaS-Backend)mainComposer, migrate --force, optimize, queue/Reverb restart
SPA (SaaS-Frontend)build-artifactsActivate release + generate /config.js from site .env
Docs (SaaS-Docs)build-artifactsActivate release only (no Node)

Required in production (not optional like local): Redis cache/queue, supervised queue + Reverb, TLS, real mail (Central Settings), Stripe webhook secrets for active gateways, migrate-only upgrades (never db:seed).

Canonical guide: Laravel Forge Deployment — site settings, .env, deploy scripts, daemons, scheduler, email, and go-live checklist.

Also: Production Runbook · Upgrade Guide

TopicLink
Laravel Forge (production)Laravel Forge Deployment
Local demo CRM dataLocal Demo Data
Platform freezePlatform Freeze
Multi-provider emailDeveloper Guide
Notifications / Reverb / Web PushDeployment
Auth / mail opsAuthentication
Frontend CI artifactsFrontend Build Artifacts
Documentation governanceSame-PR rule

Official documentation for the SaleOS SaaS Platform.