Laravel Environment Configuration (.env) Master Guide
Complete Developer Reference: Application Settings, Security, Database, Caching, Queues, Mail, Storage and Production Optimization
This guide provides a comprehensive explanation of Laravel's .env configuration, covering the default environment variables, their purposes, available options, practical examples, security implications and recommended configurations for enterprise applications.
It is designed for developers building Laravel applications such as:
- Enterprise Resource Planning (ERP).
- SACCO and financial management systems.
- Human Resource Management Systems (HRMS).
- School Management Systems.
- Inventory and Supply Chain Management.
- Hospital Management Systems.
- E-commerce and business applications.
- REST APIs and SaaS platforms.
The examples use a Laravel + MySQL/PostgreSQL + Vue.js + Tailwind CSS architecture.
1. Understanding Laravel Environment Configuration
Laravel uses environment variables to separate application configuration from application code.
The .env file contains environment-specific values such as:
- Application identity.
- Encryption keys.
- Database credentials.
- Password hashing settings.
- Session management.
- Cache configuration.
- Queue configuration.
- Email delivery.
- Cloud storage.
- Third-party integrations.
- Frontend environment variables.
The main advantage is that you can deploy the same application to different environments without changing its source code.
For example:
| Environment | Application URL | APP_ENV | APP_DEBUG |
|---|---|---|---|
| Local | localhost:8000 | local | true |
| Development | dev.example.com | development | true |
| Testing | test.example.com | testing | true |
| Staging | staging.example.com | staging | false |
| Production | example.com | production | false |
Each environment can have its own .env file.
1.1 Where is the .env file located?
In a standard Laravel installation:
laravel-project/
│
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
│
├── .env
├── .env.example
├── artisan
├── composer.json
├── package.json
└── vite.config.jsImportant files:
| File | Purpose |
|---|---|
.env | Actual environment configuration |
.env.example | Template for environment variables |
config/ | Laravel configuration files |
bootstrap/app.php | Application bootstrap configuration |
artisan | Laravel command-line interface |
Security: Never commit your production .env file to a public Git repository.
2. Application Identity and Environment
Configuration:
APP_NAME="Nestict Enterprise"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
| Variable | Description |
|---|---|
APP_NAME | Application name |
APP_ENV | Current application environment |
APP_KEY | Encryption key |
APP_DEBUG | Controls detailed error reporting |
APP_URL | Application base URL |
2.1 APP_NAME
Defines the application's name.
APP_NAME="Nestict ERP"It can be referenced throughout the application:
config('app.name');It is also commonly used in email sender names and notification templates.
2.2 APP_ENV
Identifies the environment in which the application operates.
APP_ENV=localCommon values:
| Value | Description |
|---|---|
| local | Local development |
| development | Development server |
| testing | Automated testing |
| staging | Pre-production |
| production | Live application |
You can check the environment:
php artisan about --only=environmentOr:
app()->environment();You can also check a specific environment:
if (app()->environment('production')) {
// Production-specific operations
}2.3 APP_KEY
Laravel's encryption key.
APP_KEY=Generate the key:
php artisan key:generateLaravel generates a cryptographically secure application key.
The key is used by Laravel's encryption services and contributes to the security of encrypted cookies and other application data.
Important: Do not regenerate an existing production key casually. Doing so can invalidate encrypted data and sessions.
2.4 APP_DEBUG
Controls detailed error reporting.
Development:
APP_DEBUG=trueProduction:
APP_DEBUG=falseWhen enabled, detailed exceptions and stack traces may be exposed.
Never enable it on a publicly accessible production application.
2.5 APP_URL
Defines the application's base URL.
APP_URL=https://erp.nestict.comUsed by URL generation, notifications, console operations and other application components.
3. Language, Localization and Timezone
Configuration:
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_KE
| Variable | Purpose |
|---|---|
APP_LOCALE | Default application language |
APP_FALLBACK_LOCALE | Fallback translation language |
APP_FAKER_LOCALE | Locale used by Faker |
For Kenyan applications:
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_KETimezone
In Laravel, timezone is generally configured in:
config/app.php
'timezone' => 'Africa/Nairobi',This is particularly important for:
- Payroll processing.
- SACCO transactions.
- Financial reports.
- Attendance management.
- Payment deadlines.
- Audit timestamps.
- Scheduled tasks.
For applications operating internationally, consider storing timestamps in UTC and converting them to the user's local timezone when displaying them.
4. Maintenance Mode Configuration
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=databaseMaintenance mode temporarily restricts application access.
Enable:
php artisan downDisable:
php artisan upCommon maintenance drivers:
| Driver | Description |
|---|---|
| file | Stores maintenance status in filesystem |
| cache | Stores maintenance status in cache |
APP_MAINTENANCE_STORE specifies the cache store when using the cache maintenance driver.
For standard applications:
APP_MAINTENANCE_DRIVER=fileThis is sufficient.
For distributed deployments, cache-based maintenance mode can help coordinate maintenance across multiple application servers.
5. PHP Development Server Configuration
# PHP_CLI_SERVER_WORKERS=4Controls the number of workers used by PHP's built-in development server on supported platforms and PHP versions.
Start Laravel's development server:
php artisan serveThis setting does not configure PHP-FPM.
For production environments, PHP-FPM worker configuration is managed separately.
6. Password Hashing and BCRYPT_ROUNDS
One of the most important security configurations.
BCRYPT_ROUNDS=12Laravel supports password hashing through bcrypt and Argon2.
Passwords should never be stored as plain text.
Example:
use Illuminate\Support\Facades\Hash;
$hashedPassword = Hash::make('MySecurePassword123');To verify a password:
if (Hash::check('MySecurePassword123', $hashedPassword)) {
// Password matches
}6.1 Understanding bcrypt
Bcrypt is a password hashing algorithm designed to make password guessing computationally expensive.
A stored bcrypt hash looks similar to:
$2y$12$abcdefghijklmnopqrstuv...The number 12 represents the cost factor.
Bcrypt uses an exponential work factor:
2^12 = 4096
Increasing the cost factor approximately doubles the computational work for each additional step.
6.2 BCRYPT_ROUNDS comparison
| Cost factor | Relative work | Typical application |
|---|---|---|
| 4 | 16 | Automated testing |
| 8 | 256 | Lightweight development |
| 10 | 1,024 | Development |
| 11 | 2,048 | Moderate security |
| 12 | 4,096 | Production starting point |
| 13 | 8,192 | Higher security |
| 14 | 16,384 | Higher security, benchmark first |
| 15 | 32,768 | Specialized environments |
Relative work is proportional to the bcrypt work factor, not a direct measure of milliseconds.
Recommended configuration
BCRYPT_ROUNDS=12This is a reasonable starting point for enterprise applications.
Benchmark the actual hashing time on your production hardware before increasing the cost.
6.3 Argon2id
Laravel also supports Argon2id.
Argon2id is a memory-hard password hashing algorithm.
Unlike bcrypt, it allows configuration of:
- Memory consumption.
- Computational iterations.
- Parallel threads.
For example, your hashing configuration can use:
HASH_DRIVER=argon2idThe relevant settings belong in Laravel's hashing configuration.
Check:
php artisan config:show hashingImportant: BCRYPT_ROUNDS does not control Argon2id. The two algorithms have different configuration parameters.
6.4 Password verification and rehashing
Laravel provides:
Hash::needsRehash($hashedPassword);This checks whether a password hash should be upgraded to the currently configured hashing parameters.
It is useful when strengthening password hashing requirements without forcing every user to reset their password.
7. Logging Configuration
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debugLogging records application activities, warnings and errors.
7.1 LOG_CHANNEL
Defines the default logging channel.
Common options:
| Channel | Description |
|---|---|
| single | One log file |
| daily | Separate log files by date |
| stack | Combines multiple logging channels |
| stderr | Writes to standard error |
| syslog | Uses system logging |
| errorlog | Uses PHP error logging |
| null | Discards logs |
7.2 LOG_STACK
Defines which channels are included in a stack logger.
Example:
LOG_CHANNEL=stack
LOG_STACK=singleFor daily logs:
LOG_CHANNEL=stack
LOG_STACK=daily7.3 LOG_LEVEL
Defines the minimum severity level recorded.
| Level | Meaning |
|---|---|
| emergency | System is unusable |
| alert | Immediate action required |
| critical | Critical failure |
| error | Application error |
| warning | Potential problem |
| notice | Significant normal event |
| info | Informational event |
| debug | Detailed diagnostic information |
Development:
LOG_LEVEL=debugProduction:
LOG_LEVEL=warningTypical log location:
storage/logs/laravel.logFor large enterprise systems, consider centralized logging with Grafana Loki or the ELK Stack.
8. Database Configuration
Your original configuration uses SQLite:
DB_CONNECTION=sqliteLaravel supports several database systems.
| Driver | Database | Default port |
|---|---|---|
| sqlite | SQLite | N/A |
| mysql | MySQL | 3306 |
| mariadb | MariaDB | 3306 |
| pgsql | PostgreSQL | 5432 |
| sqlsrv | Microsoft SQL Server | 1433 |
8.1 SQLite
DB_CONNECTION=sqliteSQLite stores database records in a local file.
Typical location:
database/database.sqliteAdvantages:
- No separate database server.
- Simple installation.
- Lightweight.
- Useful for testing and prototyping.
Limitations:
- Less suitable for many concurrent write operations.
- Fewer options for distributed database architecture.
- Different database behaviour from MySQL and PostgreSQL.
8.2 MySQL configuration
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nestict_erp
DB_USERNAME=nestict_user
DB_PASSWORD="StrongDatabasePassword"
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci8.3 PostgreSQL configuration
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=nestict_erp
DB_USERNAME=nestict_user
DB_PASSWORD="StrongDatabasePassword"Database recommendations
For an enterprise application:
- Use a dedicated database account.
- Avoid using the root database account.
- Restrict database network access.
- Configure automated backups.
- Monitor slow queries.
- Use database indexes appropriately.
- Apply migrations through controlled deployment procedures.
- Use transactions for financial operations.
9. Session Management
Your original configuration:
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=nullSessions preserve information about users between HTTP requests.
9.1 SESSION_DRIVER
Determines where session data is stored.
| Driver | Description |
|---|---|
| file | Local filesystem |
| cookie | Client-side cookie |
| database | Database table |
| redis | Redis |
| memcached | Memcached |
| array | Temporary memory, mainly testing |
9.2 SESSION_LIFETIME
SESSION_LIFETIME=120Session lifetime in minutes.
Examples:
| Value | Duration |
|---|---|
| 15 | 15 minutes |
| 30 | 30 minutes |
| 60 | 1 hour |
| 120 | 2 hours |
| 240 | 4 hours |
| 480 | 8 hours |
This is generally an inactivity timeout, not an absolute maximum authentication lifetime.
9.3 SESSION_ENCRYPT
SESSION_ENCRYPT=trueWhen enabled, Laravel encrypts session data before storing it in the configured session backend.
Recommended for sensitive applications.
9.4 SESSION_PATH
SESSION_PATH=/Defines the URL path for which the session cookie is available.
/ means the entire domain.
9.5 SESSION_DOMAIN
SESSION_DOMAIN=nullControls the cookie domain.
For a standalone application, leaving it unset is generally preferable.
For intentional cookie sharing across subdomains:
SESSION_DOMAIN=.nestict.comCookie sharing is not a substitute for implementing proper Single Sign-On.
9.6 Additional session security settings
Depending on your Laravel version, these settings may also be available:
SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=lax
SESSION_EXPIRE_ON_CLOSE=false
| Variable | Purpose |
|---|---|
SESSION_SECURE_COOKIE | Sends cookies over HTTPS only |
SESSION_HTTP_ONLY | Prevents JavaScript access to cookies |
SESSION_SAME_SITE | Controls cross-site cookie behaviour |
SESSION_EXPIRE_ON_CLOSE | Expires cookies when browser closes |
For production:
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_PATH=/
SESSION_DOMAIN=null
SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=laxEnsure HTTPS is configured before enabling secure cookies.
10. Broadcasting Configuration
BROADCAST_CONNECTION=logBroadcasting allows Laravel to publish events to connected clients.
Typical applications:
- Real-time notifications.
- Live chat.
- Payment updates.
- Approval notifications.
- Live dashboards.
- Collaboration tools.
Common drivers:
| Driver | Purpose |
|---|---|
| log | Writes broadcast events to logs |
| null | Disables broadcasting |
| reverb | Laravel WebSocket server |
| pusher | Pusher service |
| ably | Ably service |
For development without real-time features:
BROADCAST_CONNECTION=logFor real-time applications, consider Laravel Reverb.
11. Filesystem and File Storage
FILESYSTEM_DISK=localLaravel supports multiple filesystem storage backends.
| Disk | Purpose |
|---|---|
| local | Private local storage |
| public | Public local storage |
| s3 | Amazon S3 or compatible storage |
11.1 Local storage
FILESYSTEM_DISK=localUseful for private files.
11.2 Public storage
FILESYSTEM_DISK=publicCreate the symbolic link:
php artisan storage:link11.3 S3 storage
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=af-south-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=falseThe AWS region shown is an example. Use the actual region where your bucket exists.
Enterprise file storage recommendations
| Document | Storage |
|---|---|
| Company logos | Public |
| Product images | Public |
| Employee profile pictures | Controlled access |
| Payroll reports | Private |
| SACCO statements | Private |
| Member identification documents | Private |
| Financial reports | Private |
| Backup archives | Restricted storage |
For sensitive documents, implement authorization checks and temporary download URLs where appropriate.
12. Queue Configuration
QUEUE_CONNECTION=databaseQueues allow Laravel to process tasks asynchronously.
Instead of forcing users to wait for long-running operations, Laravel places jobs into a queue for background workers.
Examples:
- Bulk email delivery.
- SMS notifications.
- PDF report generation.
- Payroll processing.
- Excel imports.
- Large data exports.
- Document processing.
- External API integrations.
12.1 Available queue drivers
| Driver | Purpose |
|---|---|
| sync | Executes immediately |
| database | Database-backed jobs |
| redis | Redis-backed jobs |
| sqs | Amazon Simple Queue Service |
| beanstalkd | Beanstalkd queue |
12.2 Database queue
QUEUE_CONNECTION=databaseCreate the queue table using the command appropriate to your Laravel version.
For versions supporting the command:
php artisan make:queue-table
php artisan migrateStart a worker:
php artisan queue:work12.3 Redis queue
QUEUE_CONNECTION=redisStart:
php artisan queue:work redisFor production, manage workers using Supervisor or another process manager.
Important queue settings
Depending on Laravel version and configuration, you may encounter:
| Setting | Purpose |
|---|---|
retry_after | Time before an unfinished job can be retried |
block_for | Redis queue blocking duration |
after_commit | Dispatch jobs after database transactions commit |
tries | Maximum job attempts |
timeout | Maximum execution time |
These are commonly configured in config/queue.php or individual jobs, not necessarily directly in .env.
For financial operations, carefully design job retries and idempotency to prevent duplicate transactions.
13. Cache Configuration
CACHE_STORE=database
# CACHE_PREFIX=Caching stores frequently accessed data to reduce repetitive processing.
13.1 Available cache drivers
| Driver | Description |
|---|---|
| array | Temporary in-memory cache |
| file | Filesystem cache |
| database | Database-backed cache |
| redis | Redis cache |
| memcached | Memcached cache |
| dynamodb | AWS DynamoDB |
13.2 File cache
CACHE_STORE=fileSuitable for simple applications.
13.3 Database cache
CACHE_STORE=databaseStores cached data in database tables.
13.4 Redis cache
CACHE_STORE=redis
CACHE_PREFIX=nestict_erp_Useful for high-traffic applications.
Common caching use cases:
- Dashboard statistics.
- Navigation menus.
- User permissions.
- System settings.
- Frequently accessed records.
- API response caching.
Avoid caching sensitive information without considering access controls and cache invalidation.
14. Memcached Configuration
MEMCACHED_HOST=127.0.0.1Memcached is an in-memory caching system.
It can be used as an alternative to Redis for cache storage.
Typical configuration may also include:
MEMCACHED_PERSISTENT_ID=
MEMCACHED_USERNAME=
MEMCACHED_PASSWORD=
MEMCACHED_PORT=11211These settings are relevant only when using Memcached and when the application's cache configuration reads them.
You do not need to install Memcached if you are using Redis.
15. Redis Configuration
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379Redis is an in-memory data structure server.
Laravel can use Redis for:
- Application caching.
- Session storage.
- Background queues.
- Rate limiting.
- Temporary application data.
15.1 REDIS_CLIENT
REDIS_CLIENT=phpredisAvailable options commonly include:
phpredis: Native PHP extension.predis: PHP Redis library.
I recommend phpredis where the PHP extension is available.
15.2 REDIS_HOST
REDIS_HOST=127.0.0.1The Redis server address.
15.3 REDIS_PASSWORD
REDIS_PASSWORD=nullRedis authentication password.
15.4 REDIS_PORT
REDIS_PORT=6379Default Redis port.
15.5 Additional Redis settings
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_PREFIX=nestict_erp_
| Variable | Purpose |
|---|---|
REDIS_DB | Default Redis database index |
REDIS_CACHE_DB | Cache database index |
REDIS_PREFIX | Prefix for Redis keys |
The exact database and connection settings depend on config/database.php.
Security: Never expose Redis directly to the public internet. Use private networking, authentication and appropriate access controls.
16. Mail Configuration
Your original configuration:
MAIL_MAILER=log
MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"Laravel supports multiple mail delivery mechanisms.
16.1 Available mailers
| Mailer | Purpose |
|---|---|
| log | Writes emails to application logs |
| array | Stores emails in memory |
| smtp | SMTP delivery |
| ses | Amazon SES |
| mailgun | Mailgun |
| postmark | Postmark |
| resend | Resend |
| failover | Tries alternative transports |
| roundrobin | Distributes delivery between transports |
16.2 Development mail configuration
MAIL_MAILER=logThis does not send real emails.
It writes email information to the log.
Useful during development.
16.3 SMTP configuration
MAIL_MAILER=smtp
MAIL_SCHEME=smtp
MAIL_HOST=mail.nestict.com
MAIL_PORT=587
MAIL_USERNAME=support@nestict.com
MAIL_PASSWORD="YOUR_SMTP_PASSWORD"
MAIL_FROM_ADDRESS=support@nestict.com
MAIL_FROM_NAME="${APP_NAME}"Common SMTP ports:
| Port | Description |
|---|---|
| 25 | Traditional SMTP |
| 465 | Implicit TLS |
| 587 | SMTP submission, generally STARTTLS |
Ensure the scheme and port match the SMTP provider's requirements.
17. AWS Configuration
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=falseThese variables are commonly used for Amazon Web Services integrations.
| Variable | Purpose |
|---|---|
AWS_ACCESS_KEY_ID | Access key |
AWS_SECRET_ACCESS_KEY | Secret key |
AWS_DEFAULT_REGION | AWS region |
AWS_BUCKET | S3 bucket |
AWS_USE_PATH_STYLE_ENDPOINT | S3 URL addressing behaviour |
Possible use cases:
- Amazon S3 storage.
- Amazon SES.
- AWS integrations.
- Cloud-based document management.
If AWS is not used, leave these variables empty.
Prefer IAM roles or temporary credentials when deploying on supported AWS infrastructure.
18. Vite and Frontend Environment Variables
Your configuration:
VITE_APP_NAME="${APP_NAME}"Laravel uses Vite to manage frontend assets.
This is particularly relevant when integrating:
- Vue.js.
- React.
- Tailwind CSS.
- JavaScript modules.
- TypeScript.
Example:
APP_NAME="Nestict ERP"
APP_URL=https://erp.nestict.com
VITE_APP_NAME="${APP_NAME}"
VITE_API_URL="${APP_URL}/api"In Vue.js:
const appName = import.meta.env.VITE_APP_NAME;
const apiUrl = import.meta.env.VITE_API_URL;Important security rule:
Every VITE_ variable should be considered publicly accessible.
Never expose:
- Database passwords.
- SMTP credentials.
- Private API keys.
- OAuth client secrets.
- Encryption keys.
- AWS secret keys.
19. Additional Environment Variables Worth Understanding
The default .env.example is not a complete list of every variable Laravel applications can use.
Depending on the Laravel version, installed packages and application architecture, you may encounter the following.
| Variable | Purpose |
|---|---|
SANCTUM_STATEFUL_DOMAINS | Sanctum SPA authentication domains |
TRUSTED_PROXIES | Trusted reverse proxy configuration |
OCTANE_SERVER | Laravel Octane server selection |
REVERB_APP_ID | Reverb application identifier |
REVERB_APP_KEY | Reverb public application key |
REVERB_APP_SECRET | Reverb application secret |
REVERB_HOST | Reverb server hostname |
REVERB_PORT | Reverb server port |
AWS_ENDPOINT | Custom S3-compatible endpoint, where configured |
SCOUT_DRIVER | Laravel Scout search driver |
TELESCOPE_ENABLED | Telescope package configuration, where supported |
HORIZON_PREFIX | Horizon Redis key prefix |
OCTANE_HTTPS | Octane HTTPS-related configuration, where supported |
These are not all universal Laravel core variables. Their effect depends on whether the relevant configuration or package reads them.
For an enterprise application, organize additional configuration by business domain rather than placing every application setting in .env.
20. Understanding .env and the config Directory
This is one of the most important Laravel concepts.
The .env file provides environment-specific values.
The config/ directory defines how Laravel uses those values.
Typical structure:
config/
│
├── app.php
├── auth.php
├── broadcasting.php
├── cache.php
├── database.php
├── filesystems.php
├── hashing.php
├── logging.php
├── mail.php
├── queue.php
├── services.php
└── session.phpConfiguration relationship:
.env
|
v
Laravel Configuration
|
+--------+--------+
| | |
v v v
database hashing session
| | |
v v v
MySQL Bcrypt RedisFor example:
.env
BCRYPT_ROUNDS=12config/hashing.php
' bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 12),
],The actual configuration file may differ by Laravel version.
Application code should normally read configuration through:
config('hashing.bcrypt.rounds');Not:
env('BCRYPT_ROUNDS');Why?
When Laravel configuration is cached, direct env() calls outside configuration files may not return the expected values.
This is why Laravel recommends accessing application configuration through config().
21. Creating Custom Enterprise Configuration Files
You do not need to place every application setting inside .env.
For a complex ERP or SACCO application, create domain-specific configuration files.
Example:
config/
│
├── app.php
├── database.php
├── auth.php
├── sacco.php
├── erp.php
├── hr.php
├── finance.php
├── payments.php
├── notifications.php
└── integrations.phpExample: config/sacco.php
<?php
return [
'name' => env('SACCO_NAME', 'Nestict SACCO'),
'currency' => env('SACCO_CURRENCY', 'KES'),
'country' => env('SACCO_COUNTRY', 'KE'),
'timezone' => env('SACCO_TIMEZONE', 'Africa/Nairobi'),
'member_code_prefix' => env('SACCO_MEMBER_PREFIX', 'MEM'),
'minimum_share_capital' => env('SACCO_MIN_SHARE_CAPITAL', 1000),
];Corresponding .env variables:
SACCO_NAME="Nestict SACCO"
SACCO_CURRENCY=KES
SACCO_COUNTRY=KE
SACCO_TIMEZONE=Africa/Nairobi
SACCO_MEMBER_PREFIX=MEM
SACCO_MIN_SHARE_CAPITAL=1000Access them:
config('sacco.currency');
config('sacco.minimum_share_capital');This approach separates infrastructure configuration from business configuration.
Important: Financial rules such as interest rates, loan limits and statutory deductions should generally be maintained in controlled database configuration with audit history and approval workflows, rather than relying exclusively on deployment environment variables.
22. Production vs Development Configuration
A development environment and a production environment should not use identical settings.
Here is a practical comparison.
| Configuration | Development | Production |
|---|---|---|
| APP_ENV | local | production |
| APP_DEBUG | true | false |
| APP_URL | localhost | HTTPS domain |
| BCRYPT_ROUNDS | 10-12 | 12, benchmark |
| LOG_LEVEL | debug | warning/info |
| DB_CONNECTION | SQLite/MySQL | MySQL/PostgreSQL |
| SESSION_DRIVER | database | Redis/database |
| SESSION_ENCRYPT | true | true |
| CACHE_STORE | file | Redis |
| QUEUE_CONNECTION | database | Redis/database |
| BROADCAST_CONNECTION | log | Reverb/log |
| MAIL_MAILER | log | SMTP/SES |
| FILESYSTEM_DISK | local | private/S3 |
| PHP execution | Artisan Serve | PHP-FPM |
| Asset compilation | Vite development | Vite production build |
These are recommendations, not mandatory combinations.
You can run production perfectly well with database sessions, database queues and database caching if the workload and infrastructure justify it.
23. Recommended Production .env Template
The following is a starting template for a Laravel enterprise application hosted on a Nestict server.
# ==================================================
# APPLICATION
# ==================================================
APP_NAME="Nestict Enterprise ERP"
APP_ENV=production
APP_KEY=base64:GENERATED_APPLICATION_KEY
APP_DEBUG=false
APP_URL=https://erp.nestict.com
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_KE
APP_MAINTENANCE_DRIVER=file
# ==================================================
# SECURITY AND PASSWORD HASHING
# ==================================================
BCRYPT_ROUNDS=12
# ==================================================
# DATABASE
# ==================================================
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nestict_erp
DB_USERNAME=nestict_user
DB_PASSWORD="CHANGE_THIS_PASSWORD"
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
# ==================================================
# LOGGING
# ==================================================
LOG_CHANNEL=stack
LOG_STACK=daily
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=warning
# ==================================================
# SESSION
# ==================================================
SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_PATH=/
SESSION_DOMAIN=null
SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=lax
# ==================================================
# CACHE
# ==================================================
CACHE_STORE=redis
CACHE_PREFIX=nestict_erp_
# ==================================================
# REDIS
# ==================================================
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_PREFIX=nestict_erp_
# ==================================================
# QUEUES
# ==================================================
QUEUE_CONNECTION=redis
# ==================================================
# BROADCASTING
# ==================================================
BROADCAST_CONNECTION=log
# ==================================================
# FILE STORAGE
# ==================================================
FILESYSTEM_DISK=local
# ==================================================
# EMAIL
# ==================================================
MAIL_MAILER=smtp
MAIL_SCHEME=smtp
MAIL_HOST=mail.nestict.com
MAIL_PORT=587
MAIL_USERNAME=support@nestict.com
MAIL_PASSWORD="CHANGE_THIS_PASSWORD"
MAIL_FROM_ADDRESS=support@nestict.com
MAIL_FROM_NAME="${APP_NAME}"
# ==================================================
# AWS
# ==================================================
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=af-south-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
# ==================================================
# VITE
# ==================================================
VITE_APP_NAME="${APP_NAME}"
VITE_API_URL="${APP_URL}/api"Before using this template
Ensure:
- MySQL is installed and running.
- Redis is installed and accessible.
- The PHP Redis extension is enabled.
- The database exists.
- The database user has appropriate privileges.
- SMTP credentials are valid.
- HTTPS is configured.
- The application's Laravel version supports the selected variables.
If Redis is unavailable, use the appropriate database or file drivers instead.
24. Laravel Commands for Environment Management
These commands are particularly useful when maintaining Laravel applications.
| Command | Function |
|---|---|
php artisan about | Application overview |
php artisan about --only=environment | Environment details |
php artisan config:show database | Display database configuration |
php artisan config:show hashing | Display hashing configuration |
php artisan config:show session | Display session configuration |
php artisan config:show cache | Display cache configuration |
php artisan config:show queue | Display queue configuration |
php artisan config:show mail | Display mail configuration |
php artisan config:clear | Clear configuration cache |
php artisan config:cache | Cache configuration |
php artisan route:cache | Cache routes |
php artisan view:cache | Compile Blade views |
php artisan event:cache | Cache events |
php artisan optimize | Apply Laravel optimization |
php artisan optimize:clear | Clear optimization caches |
php artisan key:generate | Generate application key |
php artisan env:encrypt | Encrypt environment file |
php artisan env:decrypt | Decrypt environment file |
For production deployment:
php artisan optimizeTo clear optimization caches during troubleshooting:
php artisan optimize:clearCaution: optimize:clear also clears the default cache store. Consider this when running it on a live application.
25. Laravel Deployment Checklist
Before deploying an application to production, verify the following.
Application
- APP_ENV is production.
- APP_DEBUG is false.
- APP_KEY is generated.
- APP_URL uses HTTPS.
- Correct timezone is configured.
Database
- Production database exists.
- Dedicated database user is configured.
- Database credentials are secure.
- Backups are automated.
- Migrations have been reviewed.
Security
- Password hashing is configured.
- HTTPS is enforced.
- Session cookies are secured.
- CSRF protection is enabled.
- Rate limiting is implemented.
- Authorization policies are configured.
- Sensitive documents are private.
.envis excluded from Git.
Performance
- Configuration cache is enabled.
- Routes are optimized where appropriate.
- OPcache is enabled.
- PHP-FPM is configured.
- Cache driver is appropriate.
- Queue workers are running.
- Database indexes are reviewed.
Operations
- Logs are monitored.
- Queue failures are monitored.
- Automated backups are tested.
- Error monitoring is configured.
- Deployment rollback procedures exist.
26. Official Documentation and Further Reading
Use the official Laravel documentation as the primary reference. Configuration details can change between Laravel releases.
| Topic | Documentation |
|---|---|
| Configuration | Laravel Configuration |
| Hashing | Laravel Hashing |
| Authentication | Laravel Authentication |
| Database | Laravel Database |
| Sessions | Laravel Sessions |
| Cache | Laravel Cache |
| Queues | Laravel Queues |
| Laravel Mail | |
| Filesystem | Laravel Filesystem |
| Deployment | Laravel Deployment |
| Vite | Laravel Vite |
27. Final Architecture Recommendation
For enterprise Laravel development, think of the .env file as the configuration interface between your application and its infrastructure.
A mature architecture might look like this:
USERS
|
v
NGINX / HTTPS
|
v
LARAVEL APPLICATION
|
+----------+----------+
| | |
v v v
DATABASE REDIS STORAGE
| | |
| | |
v v v
MySQL/ Cache Documents
PostgreSQL Sessions Reports
Queues Backups
|
v
QUEUE WORKERS
|
+----------+----------+
| | |
v v v
EMAIL SMS REPORTS
|
v
INTEGRATIONS
|
v
VUE.JS FRONTEND
TAILWIND CSSThe key architectural principle is to keep application configuration, business rules, infrastructure credentials and frontend settings properly separated.
This makes Laravel applications easier to maintain, secure, scale and deploy across development, staging and production environments.
Version note: This guide follows the modern Laravel configuration conventions represented by your supplied .env file. Some settings and Artisan commands differ between Laravel releases and installed packages. Always check the relevant configuration files in your actual project before adding variables.