Loading...

This is taking longer than expected.

Back to the help centre

The environment file

Every variable read from .env, its default, and which ones to set before the first boot.

Everything that changes between machines lives in .env. Anything that belongs to the product itself is a committed value in config/. This guide walks the whole file, group by group, so you can see in one place what the application reads. The variables that belong to a feature are named here too, with a link to the guide that explains the feature.

Set these before the first boot

.env.example is a copy of a server configuration, with placeholders where the secrets go. Before the first request, decide these:

Variable Why it cannot wait
APP_KEY php artisan key:generate writes it; without it nothing encrypts
APP_NAME names the site, the emails, the PWA and the session cookie
APP_URL every absolute link, the PWA scope and the SMTP hello domain come from it
DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD the migration needs them
FILESYSTEM_DISK ships as s3 with fake AWS keys; set public until you have a bucket
MAIL_MAILER ships as failover, which needs Mailgun or SES credentials; set log locally
MAIL_FROM_ADDRESS the sender of every email; the example value is not yours
SESSION_DRIVER keep database: the device list in the account reads the sessions table

Everything else has a default that lets the application boot. The placeholders left in .env.example for AWS_*, TELNYX_*, STRIPE_* and AUTH_VALIDATION_PROVIDER are harmless until the feature that reads them is turned on; delete them or replace them when you get there.

Values with spaces need quotes: APP_NAME="Your Project". A variable that is present but empty is read as an empty string, not as absent, so remove a line rather than blanking it when you want the default back.

Application

Read by config/app.php.

Variable Default Purpose
APP_NAME Laravel Shown in the interface, the emails, the manifest; also seeds the default cookie, cache and Redis prefixes
APP_ENV production local on your machine. php artisan env prints what the application believes
APP_KEY none Encryption key, written by key:generate
APP_PREVIOUS_KEYS empty Comma-separated older keys, so values encrypted with them still decrypt after a rotation
APP_DEBUG false Detailed error pages and the Debugbar. Never true in production; it also loosens the session cookie, see below
APP_URL http://localhost Root URL for links built outside a request, the public disk URL, the PWA scope and VAPID_SUBJECT
ASSET_URL none Serve compiled assets from another host or CDN
APP_LOCALE es Language before anyone chooses one; also the lang of the PWA manifest. Must be a key of languages in config/app.php. The fallback locale is committed as es
APP_MAINTENANCE_DRIVER file file or cache; cache lets several servers share maintenance mode
APP_MAINTENANCE_STORE database Cache store used when the driver is cache
APP_PWA false Turns on the service worker and the manifest. See Web push and the PWA
COUNTRY_CODE_FALLBACK US Country assumed when the IP cannot be resolved, such as on 127.0.0.1. See Detect the visitor's country

Database

Read by config/database.php. DB_CONNECTION picks one of sqlite, mysql, mariadb, pgsql or sqlsrv; the other variables are shared by all of them. The queue's failed_jobs and job_batches tables use the same connection.

Variable Default Purpose
DB_CONNECTION mysql Which connection block is the default
DB_URL none A single connection URL that replaces host, port, database, username and password
DB_HOST 127.0.0.1 (localhost for SQL Server) Server address
DB_PORT 3306 MySQL and MariaDB, 5432 PostgreSQL, 1433 SQL Server Server port
DB_DATABASE laravel; for SQLite database/database.sqlite Database name, or the SQLite file path
DB_USERNAME root Database user
DB_PASSWORD empty Database password
DB_SOCKET empty Unix socket for MySQL and MariaDB instead of host and port
DB_CHARSET utf8mb4 MySQL and MariaDB, utf8 others Connection charset
DB_COLLATION utf8mb4_unicode_ci Collation for MySQL and MariaDB
DB_FOREIGN_KEYS true Enforce foreign keys on SQLite
MYSQL_ATTR_SSL_CA none Path to a CA certificate for TLS to MySQL or MariaDB
DB_ENCRYPT, DB_TRUST_SERVER_CERTIFICATE none Listed in the SQL Server block but commented out; nothing reads them until you uncomment those lines

Mail

Read by config/mail.php, with the provider credentials in config/services.php. The kit sends verification codes, password resets, notifications and billing emails, so a working mailer is not optional once real people sign up. How each transport is set up end to end, SMS included, is in Email and SMS delivery.

MAIL_MAILER chooses the transport. The mailers defined are smtp, ses, mailgun, postmark, resend, sendmail, log, array, failover and roundrobin. The two composite ones are committed in config/mail.php:

  • failover tries mailgun, then ses, and waits 60 seconds before retrying a transport that failed. It is the value shipped in .env.example.
  • roundrobin alternates between ses and postmark.

Verification emails have one more safety net: after the default mailer fails, the code is sent again through each mailer in mail_fallbacks in config/auth.php, which ships as ['mailgun'].

Variable Default Purpose
MAIL_MAILER smtp in config, failover in .env.example Transport to use
MAIL_FROM_ADDRESS [email protected] Sender address of every email
MAIL_FROM_NAME APP_NAME Sender name
MAIL_SCHEME none smtp or smtps for the SMTP transport
MAIL_URL none A single SMTP URL that replaces host, port, username and password
MAIL_HOST 127.0.0.1 SMTP server
MAIL_PORT 2525 SMTP port
MAIL_USERNAME none SMTP user
MAIL_PASSWORD none SMTP password
MAIL_EHLO_DOMAIN host of APP_URL Domain announced in the SMTP EHLO
MAIL_SENDMAIL_PATH /usr/sbin/sendmail -bs -i Binary for the sendmail transport
MAIL_LOG_CHANNEL none Log channel the log transport writes to; the default channel when empty
MAILGUN_DOMAIN mg.weblabor.mx Your Mailgun sending domain. Change it: the default is Weblabor's
MAILGUN_SECRET none Mailgun API key
MAILGUN_ENDPOINT api.mailgun.net api.eu.mailgun.net for the EU region
POSTMARK_TOKEN none Postmark server token
POSTMARK_MESSAGE_STREAM_ID none Postmark message stream
RESEND_KEY none Resend API key

Amazon SES reads AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION from the files group below; the region defaults to us-east-1 for SES when the variable is missing.

Files and storage

Read by config/filesystems.php. Three disks exist: local in storage/app/private, public in storage/app/public served at APP_URL/storage through the link that php artisan storage:link creates, and s3. Uploads and image handling are in Files, images and storage.

Variable Default Purpose
FILESYSTEM_DISK s3 Disk used when none is named. Set public for files people can see, local for files they cannot
AWS_ACCESS_KEY_ID none AWS key. Shared by S3, SES, SQS, DynamoDB, Bedrock and the SNS phone codes
AWS_SECRET_ACCESS_KEY none AWS secret, shared the same way
AWS_DEFAULT_REGION none for S3 Bucket region. SES, SQS and DynamoDB fall back to us-east-1; the SNS phone codes fall back to us-west-1
AWS_BUCKET none Bucket name
AWS_URL none Public URL of the bucket when it is not the AWS default, such as a CDN in front of it
AWS_ENDPOINT none Custom endpoint for an S3-compatible service such as MinIO or DigitalOcean Spaces
AWS_USE_PATH_STYLE_ENDPOINT false true for services that put the bucket in the path instead of the host
LIVEWIRE_TEMPORARY_FILE_UPLOAD_DISK the default disk Where Livewire parks a file while a form is still open

Queues

Read by config/queue.php. Notifications, web push and billing all run through the queue, so a worker has to be running in every environment; see Queues and scheduled work. The database driver needs no extra service.

Variable Default Purpose
QUEUE_CONNECTION database sync, database, beanstalkd, sqs, redis or null. sync runs jobs inline, useful only in tests
QUEUE_FAILED_DRIVER database-uuids Where failed jobs are kept: database-uuids, dynamodb, file or null
DB_QUEUE_CONNECTION the default connection Database connection for the database driver
DB_QUEUE_TABLE jobs Table for the database driver
DB_QUEUE default Queue name for the database driver
DB_QUEUE_RETRY_AFTER 10 Seconds before a job still running is retried. Raise it above your longest job
BEANSTALKD_QUEUE_HOST localhost Beanstalkd server
BEANSTALKD_QUEUE default Beanstalkd tube
BEANSTALKD_QUEUE_RETRY_AFTER 90 Retry seconds for Beanstalkd
SQS_PREFIX an AWS placeholder URL Your SQS queue URL prefix, https://sqs.<region>.amazonaws.com/<account id>
SQS_QUEUE default SQS queue name
SQS_SUFFIX none Suffix appended to the queue name, used with FIFO queues
REDIS_QUEUE_CONNECTION default Redis connection for the redis driver
REDIS_QUEUE default Redis queue name
REDIS_QUEUE_RETRY_AFTER 90 Retry seconds for Redis

SQS also reads AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION.

Session

Read by config/session.php. Two defaults differ from a stock Laravel install: the lifetime is a year, and the cookie flags follow APP_DEBUG and APP_PWA.

Variable Default Purpose
SESSION_DRIVER file in config, database in .env.example Keep database: the devices list at /account and the "disconnect" buttons read the sessions table
SESSION_LIFETIME 525600 Idle minutes before a session expires; the default is one year. The devices list only shows sessions inside this window
SESSION_EXPIRE_ON_CLOSE false Expire when the browser closes
SESSION_ENCRYPT false Encrypt the stored session payload
SESSION_CONNECTION the default connection Database or Redis connection for the session
SESSION_TABLE sessions Table for the database driver
SESSION_STORE none Cache store for the memcached, redis and dynamodb drivers
SESSION_COOKIE slug of APP_NAME plus -session Cookie name
SESSION_PATH / Cookie path
SESSION_DOMAIN none Cookie domain; set it to share the session across subdomains
SESSION_SECURE_COOKIE false when APP_DEBUG is on, otherwise the value of APP_PWA Send the cookie only over HTTPS. An installed PWA needs it
SESSION_HTTP_ONLY true Hide the cookie from JavaScript
SESSION_SAME_SITE lax when APP_DEBUG is on; otherwise none if APP_PWA is on, else lax none is what lets the installed PWA keep its session; it requires the secure flag
SESSION_PARTITIONED_COOKIE false Partition the cookie by top-level site; needs secure and same_site=none

Cache

Read by config/cache.php. The database store needs no extra service and is the default.

Variable Default Purpose
CACHE_STORE database array, database, file, memcached, redis, dynamodb, octane or null. Also the store for embedding caches in config/ai.php
CACHE_PREFIX slug of APP_NAME plus -cache- Prefix that keeps two applications apart in a shared cache
DB_CACHE_CONNECTION the default connection Connection for the database store
DB_CACHE_TABLE cache Table for the database store
DB_CACHE_LOCK_CONNECTION same as the cache connection Connection for atomic locks
DB_CACHE_LOCK_TABLE cache_locks Table for atomic locks
MEMCACHED_HOST 127.0.0.1 Memcached server
MEMCACHED_PORT 11211 Memcached port
MEMCACHED_PERSISTENT_ID none Reuse the connection between requests
MEMCACHED_USERNAME, MEMCACHED_PASSWORD none SASL credentials
REDIS_CACHE_CONNECTION cache Redis connection for the redis store
REDIS_CACHE_LOCK_CONNECTION default Redis connection for locks
DYNAMODB_CACHE_TABLE cache Table for the dynamodb store, with the AWS_* credentials
DYNAMODB_ENDPOINT none Local DynamoDB endpoint

Redis

Read by config/database.php. Only needed when the queue, the cache or the session points at redis. Two connections exist: default on database 0 and cache on database 1, sharing host and credentials.

Variable Default Purpose
REDIS_CLIENT phpredis phpredis extension or predis package
REDIS_URL none A single URL that replaces host, port, username and password
REDIS_HOST 127.0.0.1 Server
REDIS_PORT 6379 Port
REDIS_USERNAME, REDIS_PASSWORD none Credentials
REDIS_DB 0 Database number of the default connection
REDIS_CACHE_DB 1 Database number of the cache connection
REDIS_CLUSTER redis Cluster mode
REDIS_PREFIX slug of APP_NAME plus -database- Key prefix
REDIS_PERSISTENT false Keep the connection open between requests

Logging

Read by config/logging.php. The default channel is daily, which rotates storage/logs/laravel.log and keeps fourteen days. Whatever you log is readable in the browser at /logs; as shipped that route has no sign-in in front of it, so restrict it before the site is public. Two channels ship for sending errors elsewhere: slack posts through an incoming webhook, and slack_api posts through a bot token; papertrail sends syslog over TLS. See Logs and debugging.

Variable Default Purpose
LOG_CHANNEL daily Channel that receives everything. Use stack to fan out to several
LOG_STACK daily Comma-separated channels the stack channel writes to, such as daily,slack_api
LOG_LEVEL debug; critical for slack Lowest level written. slack_api is fixed at error
LOG_DAILY_DAYS 14 Days of daily files to keep
LOG_DEPRECATIONS_CHANNEL null Where PHP and package deprecations go; null discards them
LOG_DEPRECATIONS_TRACE false Include a stack trace with each deprecation
LOG_SLACK_WEBHOOK_URL none Incoming webhook for the slack channel
LOG_SLACK_USERNAME Laravel Log Sender name in Slack
LOG_SLACK_EMOJI :boom: Sender icon in Slack
SLACK_BOT_TOKEN none Bot token for the slack_api channel
SLACK_LOG_CHANNEL #errores Slack channel the slack_api channel posts to
PAPERTRAIL_URL none Papertrail host
PAPERTRAIL_PORT none Papertrail port
LOG_PAPERTRAIL_HANDLER Monolog SyslogUdpHandler Handler class for the papertrail channel
LOG_STDERR_FORMATTER none Formatter class for the stderr channel, used in containers
LOG_SYSLOG_FACILITY LOG_USER Facility for the syslog channel

Development tools

Read by config/debugbar.php and config/querydetector.php. Both packages are development dependencies and switch themselves on when APP_DEBUG is true; these variables override that.

Variable Default Purpose
DEBUGBAR_ENABLED follows APP_DEBUG Force the Debugbar on or off
DEBUGBAR_OPEN_STORAGE false Let anyone open stored requests
DEBUGBAR_EDITOR phpstorm Editor that file links open in
DEBUGBAR_REMOTE_SITES_PATH, DEBUGBAR_LOCAL_SITES_PATH empty Map container paths to your machine so file links resolve
DEBUGBAR_THEME auto auto, light or dark
QUERY_DETECTOR_ENABLED follows APP_DEBUG Force the N+1 detector on or off
QUERY_DETECTOR_THRESHOLD 1 Repeated queries before it reports
QUERY_DETECTOR_LOG_CHANNEL daily Where it writes when it outputs to the log

More in Working on the code.

Variables that belong to a feature

These are read by config/ too, so they belong in this file, but the meaning of each value is explained in the feature's own guide.

Sign-in and verification, read by config/auth.php and config/services.php. See Configure sign-in and registration, Verify email and phone and The security PIN.

Variable Default
AUTH_APPROACH CreationValidation
AUTH_LOGIN_STEPS one
AUTH_ENABLE_REGISTER true
AUTH_ENABLE_VALIDATION true
AUTH_ENABLE_PIN false
LOGIN_IDENTITIES email
AUTH_VALIDATION_PROVIDER aws
TELNYX_API_KEY none; falls back to the older name TELNYX_TOKEN
TELNYX_VERIFY_PROFILE_ID none
AUTH_PASSWORD_TIMEOUT 10800 seconds before a password confirmation expires
AUTH_GUARD, AUTH_PASSWORD_BROKER, AUTH_MODEL, AUTH_PASSWORD_RESET_TOKEN_TABLE web, users, App\Models\User, password_reset_tokens: standard Laravel, no reason to change them

Feature flags, read by config/features.php. See Configure your project; the referral values are explained in Referrals, and the ticket values in Support tickets.

Variable Default
FEATURE_PLANS_ENABLED false
FEATURE_ADDONS_ENABLED false
FEATURE_ANNOUNCEMENTS false
FEATURE_TRACKING_ENABLED false
FEATURE_REFERRALS_ENABLED false
FEATURE_REFERRALS_REGISTRATION_REWARD 10
FEATURE_REFERRALS_SUBSCRIPTION_REWARD_PERCENT 10
FEATURE_REFERRALS_CURRENCY mxn
FEATURE_REFERRALS_COOKIE_DAYS 30
FEATURE_TICKETS_ENABLED false
FEATURE_TICKETS_PRIORITY_RESPONSE_DAYS, FEATURE_TICKETS_STANDARD_RESPONSE_DAYS 1, 5 business days
FEATURE_TICKETS_NEAR_DUE_FRACTION 0.25
FEATURE_TICKETS_AUTO_CLOSE_DAYS, FEATURE_TICKETS_AUTO_CLOSE_WARNING_DAYS 5, 4
FEATURE_TICKETS_CHAT_ENABLED false; the chat also needs tickets on and real time running
FEATURE_TICKETS_CHAT_IDLE_MINUTES 5

Stripe and billing, read by config/services.php, config/pricing.php, the billing package's billing-core.php and Laravel Cashier's own configuration. See Turn on plans and billing and Free trials and coupons.

Variable Default
STRIPE_KEY none
STRIPE_SECRET none
STRIPE_WEBHOOK_SECRET none
BILLING_CORE_ENABLED true
BILLING_USER_ENABLED true
BILLING_SUITE_ENABLED named in a commented-out adapter block of billing-core.php; nothing reads it until you uncomment that block and write the adapter class
BILLING_COUPONS_ENABLED true
BILLING_FREE_TRIAL_ENABLED false
BILLING_FREE_TRIAL_DAYS 14
CASHIER_CURRENCY usd, read by Cashier itself; the billing package's own currency is the committed primary_currency in config/pricing.php, mxn
CASHIER_CURRENCY_LOCALE, CASHIER_PATH, CASHIER_WEBHOOK_TOLERANCE, CASHIER_LOGGER Cashier's own, en, stripe, 300, none

Web push and the PWA, read by config/webpush.php and config/app.php. See Web push and the PWA.

Variable Default
APP_PWA false
VAPID_SUBJECT APP_URL
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY none; php artisan webpush:vapid prints them
VAPID_PEM_FILE none; an alternative to the two keys
WEBPUSH_DB_TABLE push_subscriptions
WEBPUSH_DB_CONNECTION DB_CONNECTION
WEBPUSH_AUTOMATIC_PADDING true

Real time, read by Laravel's broadcasting configuration and by Reverb's own. It is on only when BROADCAST_CONNECTION is reverb. See Real time with Reverb.

Variable Default
BROADCAST_CONNECTION null, real time off
REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET none
REVERB_HOST none; the public address browsers connect to
REVERB_PORT 443; .env.example writes 8080 for local work
REVERB_SCHEME https

AI providers, read by config/ai.php. The translator uses the provider named in the committed default, which is openai, so OPENAI_API_KEY is the one that matters unless you change that key. See Connect an AI provider.

Variable Default
OPENAI_API_KEY none
OPENAI_URL https://api.openai.com/v1
ANTHROPIC_API_KEY none
ANTHROPIC_URL https://api.anthropic.com/v1
GEMINI_API_KEY none
GEMINI_URL https://generativelanguage.googleapis.com/v1beta/
AZURE_OPENAI_API_KEY, AZURE_OPENAI_URL none
AZURE_OPENAI_API_VERSION 2025-04-01-preview
AZURE_OPENAI_DEPLOYMENT gpt-4o
AZURE_OPENAI_EMBEDDING_DEPLOYMENT text-embedding-3-small
AZURE_OPENAI_IMAGE_DEPLOYMENT gpt-image-1
AWS_BEDROCK_REGION us-east-1
AWS_BEARER_TOKEN_BEDROCK, AWS_SESSION_TOKEN none
AWS_USE_DEFAULT_CREDENTIALS true
COHERE_API_KEY, DEEPSEEK_API_KEY, ELEVENLABS_API_KEY, GROQ_API_KEY, JINA_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY, VOYAGEAI_API_KEY, XAI_API_KEY none
OLLAMA_API_KEY empty; Ollama needs no key
OLLAMA_URL http://localhost:11434

Country detection, read by config/services.php and config/app.php. See Detect the visitor's country.

Variable Default
WEBLABOR_WORLD_TOKEN none; without it the country is still detected from the IP, but nothing is looked up in Weblabor World
WEBLABOR_WORLD_ENDPOINT https://world.weblabor.mx/api, read by the World UI package rather than by config/
WEBLABOR_WORLD_TIMEOUT 3, the seconds each call to Weblabor World may wait, read by config/worldui.php
COUNTRY_CODE_FALLBACK US

Tracking, read by config/services.php and config/features.php. See Tracking and analytics.

Variable Default
FEATURE_TRACKING_ENABLED false
FACEBOOK_ACCESS_TOKEN, FACEBOOK_PIXEL_ID none; both are needed before an event is sent to Facebook
FACEBOOK_TEST_EVENT_CODE none

Activity log, read by config/activitylog.php. See Activity log.

Variable Default
ACTIVITY_LOGGER_ENABLED true
ACTIVITY_LOGGER_DB_CONNECTION the default connection

The DevZone deploy button, the one place where a variable is read straight from .env instead of through config/. See The DevZone.

Variable Default
GIT_USER, GIT_PASSWORD none; the deploy in /admin/dev refuses to pull until both are set, and uses them as the Git credentials for git pull

After you change a value

A running application reads .env on every request only while the configuration is not cached. After php artisan config:cache, which every deploy should run, a change in .env does nothing until you run it again or clear it with php artisan config:clear. The queue worker holds its own copy too: restart it with php artisan queue:restart after any change it should see.