A correctly configured .env file and working storage are essential for any Laravel application. In this guide, you will learn how to set these up correctly for a production environment.

Understanding the .env File

The .env file contains environment-specific configuration that should not be version controlled.

Why Use .env

  • Separates configuration from code
  • Prevents sensitive data from being in Git
  • Makes deployment to different environments easy
  • Each environment (dev, staging, production) has its own .env

Creating the .env File

When you clone Laravel, create a .env file:

cd ~/domains/jouwdomein.nl/project
# Copy the example file
cp .env.example .env
# Generate the app key
php artisan key:generate

Essential .env Settings

Configure these settings for production.

Application Settings

APP_NAME="My Laravel App"
APP_ENV=production
APP_KEY=base64:generated-key-here
APP_DEBUG=false
APP_TIMEZONE=Europe/Amsterdam
APP_URL=https://jouwdomein.nl

Important:

  • APP_ENV=production activates production optimizations
  • APP_DEBUG=false prevents error messages from being visible
  • APP_URL must contain your full URL with https

Database Configuration

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=jouw_database
DB_USERNAME=jouw_user
DB_PASSWORD=jouw_wachtwoord
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci

Logging Configuration

LOG_CHANNEL=daily
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=error

For production:

  • daily creates a new log file each day
  • LOG_LEVEL=error logs only errors, not warnings

Cache and Session

CACHE_STORE=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_PATH=/
SESSION_DOMAIN=.jouwdomein.nl

For better performance on shared hosting, file is the best choice.

Queue Configuration

QUEUE_CONNECTION=database

Or for shared hosting without workers:

QUEUE_CONNECTION=sync

Mail Configuration

MAIL_MAILER=smtp
MAIL_HOST=mail.jouwdomein.nl
MAIL_PORT=587
MAIL_USERNAME=info@jouwdomein.nl
MAIL_PASSWORD=your-email-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=info@jouwdomein.nl
MAIL_FROM_NAME="${APP_NAME}"

Configuring Storage

Laravel uses the storage folder for logs, cache, and uploads.

Storage Structure

storage/
├── app/
│   ├── public/      # Publicly accessible uploads
│   └── private/     # Private files
├── framework/
│   ├── cache/       # File cache
│   ├── sessions/    # Session files
│   └── views/       # Compiled views
└── logs/            # Log files

The public storage must be accessible via the web:

# Create the symlink
php artisan storage:link

This creates: public/storage -> storage/app/public

Check if the link works:

ls -la public/
# You should see: storage -> /path/to/storage/app/public

If the artisan command does not work:

cd public
ln -s ../storage/app/public storage

Setting Storage Permissions

Ensure Laravel can write:

# Make writable recursively
chmod -R 775 storage
chmod -R 775 bootstrap/cache
# Set owner (if necessary)
chown -R www-data:www-data storage
chown -R www-data:www-data bootstrap/cache

On shared hosting, usually only chmod is needed.

Production Security

Secure your .env and storage.

Securing .env

The .env file should never be publicly accessible:

  1. Laravel's public folder is the document root
  2. .env is one level higher
  3. .htaccess blocks access

Check with:

curl https://jouwdomein.nl/.env
# Should return 403 or 404, NEVER the content!

.env in .gitignore

Ensure .env never goes into Git:

.env
.env.backup
.env.production

Protecting Storage

Protect private uploads:

// In routes/web.php
Route::get('/download/{file}', function ($file) {
    // Authorization check
    if (!auth()->check()) {
        abort(403);
    }
    return Storage::download('private/' . $file);
});

Cache Configuration

Optimize caching for production.

Config Cache

php artisan config:cache

This combines all config files into a cached file.

Note: After config:cache, .env will no longer be read directly. Changes in .env require:

php artisan config:clear
php artisan config:cache

Route Cache

php artisan route:cache

Significantly speeds up route resolution.

View Cache

php artisan view:cache

Pre-compiles all Blade templates.

Everything at Once

php artisan optimize

Or during deployment:

php artisan optimize:clear
php artisan optimize

Common Issues

Storage Permission Denied

# Reset permissions
chmod -R 775 storage bootstrap/cache
# SELinux context (CentOS/RHEL)
chcon -R -t httpd_sys_rw_content_t storage

On some servers, symlinks are disabled:

# Copy instead of symlink
cp -r storage/app/public/* public/storage/

Or adjust the FileController to serve files.

.env Changes Not Working

# Clear config cache
php artisan config:clear
# Or if you don't have SSH
# Remove: bootstrap/cache/config.php

APP_KEY Issues

If you are missing or have an incorrect APP_KEY:

php artisan key:generate

This regenerates the key. Note: existing encrypted data will become unreadable.

Environment Detection

Check the current environment in code:

// In code
if (app()->environment('production')) {
    // Production specific code
}
// In Blade
@production
    
@endproduction

Best Practices

.env Management

  • Never use the same .env on dev and production
  • Keep production .env secure (password manager)
  • Use strong, unique passwords
  • Rotate credentials regularly

Storage Management

  • Configure backup for storage/app
  • Consider cloud storage for scaling
  • Regularly clean up old logs

Need Help?

We are here for you! Are you facing any issues or have questions? Our support team is happy to assist you personally. Send us a message via the ticket system - we usually respond within a few hours and are happy to help you.