Skip to content
Getting Started

Environment Configuration

Configure the three .env files that control Docker services, the Laravel backend, and the Nuxt frontend.

SaaS4Builders uses three .env files, each controlling a different part of the stack. The make install command creates these files automatically from their .example templates, but you will need to customize them — especially for Stripe billing and OAuth providers.


Three Configuration Files

FileScopeRead By
.env (root)Docker Compose variables: ports, database credentials, Reverb, VAPIDDocker Compose, passed to containers
backend/.envLaravel application configurationPHP container (Laravel config())
frontend/.envNuxt runtime configurationNode container (Nuxt useRuntimeConfig())
The root .env is read by Docker Compose to configure containers and pass environment variables into them. The backend/.env and frontend/.env are read by the Laravel and Nuxt applications running inside those containers.

Root .env — Docker and Infrastructure

This file controls the Docker Compose setup. It sets ports, database credentials, and variables that are passed into containers.

Ports

VariableDefaultService
NGINX_PORT8000Backend API (Nginx reverse proxy)
NUXT_PORT3000Frontend (Nuxt dev server)
DB_PORT5432PostgreSQL
REDIS_PORT6379Redis
MAILPIT_UI_PORT8025Mailpit email testing UI
MAILPIT_SMTP_PORT1025Mailpit SMTP server
REVERB_PORT8080Reverb WebSocket server
HMR_PORT24679Nuxt hot module replacement

Change these if you have port conflicts with other services on your machine.

Database Credentials

VariableDefaultDescription
DB_DATABASEsaasPostgreSQL database name
DB_USERNAMEsaasPostgreSQL user
DB_PASSWORDsecretPostgreSQL password
COMPOSE_PROJECT_NAMEsaas-boilerplateDocker Compose project prefix for container names

These credentials are used by both the PostgreSQL container (to create the database) and the backend .env (to connect to it).

Broadcasting / Reverb

VariableDefaultDescription
REVERB_APP_KEYsaas-reverb-keyReverb application key
REVERB_APP_SECRETsaas-reverb-secretReverb application secret
REVERB_APP_IDsaas-localReverb application ID
REVERB_HOSTreverbInternal Docker hostname for Reverb
REVERB_HOST_PUBLIClocalhostPublic hostname for WebSocket connections
REVERB_PORT8080Reverb WebSocket port
REVERB_SCHEMEhttpWebSocket protocol (http for dev, https for production)

Web Push Notifications (VAPID)

VariableDefaultDescription
VAPID_SUBJECThttps://your-app.comURL or mailto: identifying the push sender
VAPID_PUBLIC_KEY(empty)Public VAPID key
VAPID_PRIVATE_KEY(empty)Private VAPID key

Generate VAPID keys with:

make vapid

This generates the keys inside the PHP container, writes them to backend/.env, then syncs them to the root .env and frontend/.env on the host.

OptionUsageDescription
--forcemake vapid ARGS=--forceOverwrite existing VAPID keys
--showmake vapid ARGS=--showDisplay keys without writing to any file

Nuxt Studio

VariableDefaultDescription
STUDIO_GITHUB_TOKEN(empty)GitHub PAT for content commits
STUDIO_REPOSITORY_PROVIDERgithubGit provider (github or gitlab)
STUDIO_REPOSITORY_OWNER(empty)Repository owner/org
STUDIO_REPOSITORY_NAME(empty)Repository name
STUDIO_REPOSITORY_BRANCHmainBranch for content commits

These are only needed if you use Nuxt Studio for visual content editing.


Backend .env — Laravel Application

This is the standard Laravel .env file with project-specific additions for billing, multi-tenancy, and OAuth.

Application

VariableDefaultDescription
APP_NAMESaaS4BuildersApplication name (used in emails, notifications)
APP_ENVlocalEnvironment: local, testing, production
APP_KEY(generated)Encryption key (auto-generated by make install)
APP_DEBUGtrueShow debug info (false in production)
APP_TIMEZONEUTCApplication timezone
APP_URLhttp://localhost:8000Backend API URL
FRONTEND_URLhttp://localhost:3000Frontend URL (used for CORS, redirects, emails)
In production, set APP_ENV=production, APP_DEBUG=false, and both URLs to your actual domains. See the Deployment Guide for the full production checklist.

Localization

VariableDefaultDescription
APP_LOCALEenDefault locale
APP_FALLBACK_LOCALEenFallback when translation is missing
APP_SUPPORTED_LOCALESen,fr,es,itComma-separated list of supported locales
APP_SUPPORT_EMAILsupport@example.comSupport email shown in notifications

Database

VariableDefaultDescription
DB_CONNECTIONpgsqlDatabase driver (PostgreSQL)
DB_HOSTpostgresHostname (Docker service name)
DB_PORT5432Port
DB_DATABASEsaasDatabase name
DB_USERNAMEsaasUsername
DB_PASSWORDsecretPassword
The DB_HOST is postgres (the Docker service name), not localhost. Inside the Docker network, containers reach each other by service name.

Cache and Sessions

VariableDefaultDescription
SESSION_DRIVERredisSession storage backend
SESSION_LIFETIME120Session lifetime in minutes
CACHE_STOREredisCache backend
CACHE_PREFIXsaas_Cache key prefix (prevents collisions)

Queue

VariableDefaultDescription
QUEUE_CONNECTIONredisQueue backend

The queue worker runs in a separate Docker container (saas-queue). Jobs dispatched by the application are stored in Redis and processed asynchronously.

Redis

VariableDefaultDescription
REDIS_CLIENTphpredisRedis PHP extension
REDIS_HOSTredisHostname (Docker service name)
REDIS_PASSWORDnullPassword (none in development)
REDIS_PORT6379Port

Mail

VariableDefaultDescription
MAIL_MAILERsmtpMail driver
MAIL_HOSTmailpitSMTP host (Mailpit in development)
MAIL_PORT1025SMTP port
MAIL_USERNAMEnullSMTP username
MAIL_PASSWORDnullSMTP password
MAIL_ENCRYPTIONnullEncryption (tls for production)
MAIL_FROM_ADDRESShello@saas.localDefault sender email
MAIL_FROM_NAME${APP_NAME}Default sender name

In development, all emails are captured by Mailpit and visible at http://localhost:8025. No emails are actually sent.

For production, replace Mailpit with a real mail provider (Mailgun, Postmark, Amazon SES, or custom SMTP).

Sanctum (Authentication)

VariableDefaultDescription
SANCTUM_STATEFUL_DOMAINSlocalhost:3000,127.0.0.1:3000Domains allowed for cookie-based auth
Critical for production: This must exactly match your frontend domain (including port if non-standard). Example: app.yourdomain.com. If this is wrong, authentication will silently fail.

Stripe and Billing

VariableDefaultDescription
STRIPE_KEY(empty)Stripe publishable key (pk_test_... or pk_live_...)
STRIPE_SECRET(empty)Stripe secret key (sk_test_... or sk_live_...)
STRIPE_WEBHOOK_SECRET(empty)Webhook signing secret (whsec_...)
STRIPE_TAX_ENABLEDfalseEnable Stripe Tax for automatic tax calculation
TAX_PROVIDERstripe_taxTax calculation provider
BILLING_MODEstripe_managedBilling mode (only stripe_managed in V1)
BILLING_DEFAULT_CURRENCYUSDDefault currency for new subscriptions
BILLING_FALLBACK_CURRENCYEURFallback currency

To enable billing flows, you need Stripe test keys:

  1. Create a Stripe account.
  2. Go to Developers → API Keys in test mode.
  3. Copy the publishable key and secret key.
  4. For webhooks, use the Stripe CLI to forward events locally:
stripe listen --forward-to http://localhost:8000/api/v1/stripe/webhook

The CLI will print a webhook signing secret (whsec_...) — add it to STRIPE_WEBHOOK_SECRET.

OAuth Providers

VariableDefaultDescription
OAUTH_PROVIDERS(empty)Comma-separated list of enabled providers (e.g., google,github)
GOOGLE_CLIENT_ID(empty)Google OAuth client ID
GOOGLE_CLIENT_SECRET(empty)Google OAuth client secret
GOOGLE_REDIRECT_URI${APP_URL}/api/v1/auth/oauth/google/callbackGoogle OAuth callback URL
GITHUB_CLIENT_ID(empty)GitHub OAuth client ID
GITHUB_CLIENT_SECRET(empty)GitHub OAuth client secret
GITHUB_REDIRECT_URI${APP_URL}/api/v1/auth/oauth/github/callbackGitHub OAuth callback URL

OAuth is optional. Leave OAUTH_PROVIDERS empty to disable social login entirely. To enable a provider, add its name to the list and fill in the credentials.

Broadcasting / Reverb

VariableDefaultDescription
BROADCAST_CONNECTIONreverbBroadcasting driver
REVERB_APP_IDsaas-localMust match root .env
REVERB_APP_KEYsaas-reverb-keyMust match root .env
REVERB_APP_SECRETsaas-reverb-secretMust match root .env
REVERB_HOSTreverbInternal Docker hostname
REVERB_PORT8080Reverb port
REVERB_SCHEMEhttpProtocol
REVERB_SERVER_HOST0.0.0.0Bind address for the Reverb server
REVERB_SERVER_PORT8080Server listen port

Logging

VariableDefaultDescription
LOG_CHANNELstackLog channel
LOG_STACKsingleStack channels
LOG_DEPRECATIONS_CHANNELnullDeprecation log channel
LOG_LEVELdebugMinimum log level (warning or error for production)

Frontend .env — Nuxt Application

The frontend .env configures the Nuxt application's runtime behavior.

Localization

VariableDefaultDescription
NUXT_PUBLIC_LOCALEenDefault locale
NUXT_PUBLIC_FALLBACK_LOCALEenFallback locale

API

VariableDefaultDescription
NUXT_PUBLIC_API_BASE_URLhttp://localhost:8000Backend API URL for client-side requests
In the Docker setup, the Node container receives two API URLs from docker-compose.yml: NUXT_API_BASE_URL=http://nginx:80 for server-side rendering and NUXT_PUBLIC_API_BASE_URL=http://localhost:8000 for client-side requests. These Docker-level variables override what's in frontend/.env.

Authentication

VariableDefaultDescription
NUXT_PUBLIC_AUTH_MODEcookieAuth mode: cookie (Sanctum SPA) or token (Bearer tokens)

The default cookie mode uses Sanctum's cookie-based SPA authentication. This is recommended for the built-in frontend. Use token mode if you are building a separate client application.

Multi-Tenancy

VariableDefaultDescription
NUXT_PUBLIC_TENANCY_MODEheaderHow the current tenant is communicated to the API
NUXT_PUBLIC_TENANCY_HEADER_NAMEX-Tenant-IDHeader name (when mode is header)
NUXT_PUBLIC_TENANCY_PATH_PARAMtenantIdURL parameter name (when mode is path)
NUXT_PUBLIC_TENANCY_BASE_DOMAINlocalhostBase domain (when mode is subdomain)

The default header mode sends the tenant ID in an X-Tenant-ID HTTP header with every API request. Other modes (path, subdomain) are available for different URL strategies.

Nuxt Studio

VariableDefaultDescription
STUDIO_REPOSITORY_PROVIDERgithubGit provider
STUDIO_REPOSITORY_OWNER(empty)Repository owner
STUDIO_REPOSITORY_NAME(empty)Repository name
STUDIO_REPOSITORY_BRANCHmainContent branch
STUDIO_GITHUB_TOKEN(empty)GitHub PAT for commits

These are only needed for Nuxt Studio integration. Studio uses the application's existing Sanctum authentication — no separate OAuth setup is required.


Variable Relationships

Some variables must stay in sync across files:

SettingRoot .envBackend .envFrontend .env
Database credentialsDB_DATABASE, DB_USERNAME, DB_PASSWORDSame values (different host: postgres)
Reverb configREVERB_APP_KEY, REVERB_APP_SECRET, etc.Same valuesReceives via docker-compose.yml
VAPID keysVAPID_PUBLIC_KEY, VAPID_PRIVATE_KEYSame valuesReceives public key via docker-compose.yml

The make install command copies the same .example templates, so values are consistent by default. If you change a shared variable, update it in all relevant files.


What's Next