Configuration Guide

Comprehensive configuration guide for the Inventory Management API covering environment variables, application settings, and advanced configurations.

Table of Contents

  1. TOC

Environment Configuration

Core Application Settings

# Application Identity
APP_NAME="Inventory Management"
APP_ENV=production                    # local, testing, staging, production
APP_KEY=base64:GENERATED_KEY         # Generated with php artisan key:generate
APP_DEBUG=false                      # true for development, false for production
APP_TIMEZONE=UTC                     # Application timezone
APP_URL=https://your-domain.com      # Full application URL
APP_LOCALE=en                        # Default application locale
APP_FALLBACK_LOCALE=en              # Fallback locale

Database Configuration

Production (MariaDB/MySQL)

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=inventory_production
DB_USERNAME=inventory_user
DB_PASSWORD=secure_password
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci

Development (SQLite)

DB_CONNECTION=sqlite
DB_DATABASE=database/database.sqlite
DB_FOREIGN_KEYS=true

Testing (In-memory SQLite)

DB_CONNECTION=sqlite
DB_DATABASE=:memory:

Storage Configuration

Local Storage (Default)

# Upload Images (user uploads)
UPLOAD_IMAGES_DISK=local_upload_images
UPLOAD_IMAGES_PATH=uploads/images

# Available Images (processed/optimized)
AVAILABLE_IMAGES_DISK=local_available_images
AVAILABLE_IMAGES_PATH=available/images

# Pictures (final processed images)
PICTURES_DISK=local_pictures
PICTURES_PATH=pictures

AWS S3 Storage

# S3 Configuration
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=inventory-app-storage
AWS_USE_PATH_STYLE_ENDPOINT=false

# Storage Disks
UPLOAD_IMAGES_DISK=s3_upload_images
UPLOAD_IMAGES_PATH=uploads/images

AVAILABLE_IMAGES_DISK=s3_available_images
AVAILABLE_IMAGES_PATH=available/images

PICTURES_DISK=s3_pictures
PICTURES_PATH=pictures

Caching Configuration

File Cache (Development)

CACHE_STORE=file
CACHE_PREFIX=inventory_app

Redis Cache (Production)

CACHE_STORE=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB=0

Session Configuration

File Sessions (Default)

SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
SESSION_SECURE_COOKIE=true          # true for HTTPS
SESSION_SAME_SITE=strict

Database Sessions

SESSION_DRIVER=database
SESSION_CONNECTION=mysql
SESSION_TABLE=sessions

Queue Configuration

Sync Queue (Development)

QUEUE_CONNECTION=sync

Database Queue (Production)

QUEUE_CONNECTION=database
QUEUE_TABLE=jobs
QUEUE_RETRY_AFTER=90
QUEUE_FAILED_TABLE=failed_jobs

Redis Queue (High Performance)

QUEUE_CONNECTION=redis
REDIS_QUEUE_HOST=127.0.0.1
REDIS_QUEUE_PORT=6379
REDIS_QUEUE_DB=1

Mail Configuration

SMTP (Production)

MAIL_MAILER=smtp
MAIL_HOST=smtp.your-provider.com
MAIL_PORT=587
MAIL_USERNAME=your-email@domain.com
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@your-domain.com
MAIL_FROM_NAME="Inventory Management"

Log (Development)

MAIL_MAILER=log

Authentication Configuration

# Sanctum (API Authentication)
SANCTUM_STATEFUL_DOMAINS=localhost,127.0.0.1,your-frontend-domain.com
SANCTUM_GUARD=web
SANCTUM_MIDDLEWARE=web

# JWT Configuration (if using JWT)
JWT_SECRET=your-jwt-secret
JWT_TTL=60                          # Token TTL in minutes
JWT_REFRESH_TTL=20160              # Refresh token TTL in minutes

Logging Configuration

LOG_CHANNEL=daily                   # single, daily, slack, papertrail
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=error                     # emergency, alert, critical, error, warning, notice, info, debug
LOG_DAILY_DAYS=14                   # Days to keep daily logs

Security Configuration

# CSRF Protection
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=strict

# CORS Configuration
CORS_ALLOWED_ORIGINS=https://your-frontend-domain.com
CORS_ALLOWED_METHODS=GET,POST,PUT,PATCH,DELETE,OPTIONS
CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-Requested-With
CORS_EXPOSED_HEADERS=
CORS_MAX_AGE=0
CORS_SUPPORTS_CREDENTIALS=true

Application Configuration Files

config/app.php

Key configuration options:

<?php

return [
    'name' => env('APP_NAME', 'Inventory Management'),
    'env' => env('APP_ENV', 'production'),
    'debug' => env('APP_DEBUG', false),
    'url' => env('APP_URL', 'http://localhost'),
    'timezone' => env('APP_TIMEZONE', 'UTC'),
    'locale' => env('APP_LOCALE', 'en'),
    'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),

    // Key configuration for encryption
    'key' => env('APP_KEY'),
    'cipher' => 'AES-256-CBC',

    // Providers configuration
    'providers' => [
        // Laravel Framework Service Providers
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        // ... other providers

        // Application Service Providers
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
    ],
];

config/database.php

Database connections configuration:

<?php

return [
    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [
        'sqlite' => [
            'driver' => 'sqlite',
            'url' => env('DATABASE_URL'),
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
            'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
        ],

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
    ],
];

config/filesystems.php

Storage configuration:

<?php

return [
    'default' => env('FILESYSTEM_DISK', 'local'),

    'disks' => [
        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'throw' => false,
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
            'throw' => false,
        ],

        // Custom storage disks for image management
        'local_upload_images' => [
            'driver' => 'local',
            'root' => storage_path('app/'.env('UPLOAD_IMAGES_PATH', 'uploads/images')),
            'url' => env('APP_URL').'/storage/'.env('UPLOAD_IMAGES_PATH', 'uploads/images'),
            'visibility' => 'public',
        ],

        'local_available_images' => [
            'driver' => 'local',
            'root' => storage_path('app/'.env('AVAILABLE_IMAGES_PATH', 'available/images')),
            'url' => env('APP_URL').'/storage/'.env('AVAILABLE_IMAGES_PATH', 'available/images'),
            'visibility' => 'public',
        ],

        'local_pictures' => [
            'driver' => 'local',
            'root' => storage_path('app/'.env('PICTURES_PATH', 'pictures')),
            'url' => env('APP_URL').'/storage/'.env('PICTURES_PATH', 'pictures'),
            'visibility' => 'public',
        ],
    ],
];

config/sanctum.php

API authentication configuration:

<?php

return [
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
        '%s%s',
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
        Sanctum::currentApplicationUrlWithPort()
    ))),

    'guard' => env('SANCTUM_GUARD', 'web'),
    'expiration' => null,
    'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
    'middleware' => [
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
        'validate_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
    ],
];

Environment-Specific Configurations

Development Environment

# .env.local
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000

DB_CONNECTION=sqlite
DB_DATABASE=database/database.sqlite

CACHE_STORE=file
SESSION_DRIVER=file
QUEUE_CONNECTION=sync
MAIL_MAILER=log

LOG_CHANNEL=single
LOG_LEVEL=debug

# Frontend development
VITE_APP_URL=http://localhost:8000

Testing Environment

# .env.testing
APP_ENV=testing
APP_DEBUG=true
APP_KEY=base64:TEST_KEY

DB_CONNECTION=sqlite
DB_DATABASE=:memory:

CACHE_STORE=array
SESSION_DRIVER=array
QUEUE_CONNECTION=sync
MAIL_MAILER=array

LOG_CHANNEL=single
LOG_LEVEL=debug

Staging Environment

# .env.staging
APP_ENV=staging
APP_DEBUG=false
APP_URL=https://staging.your-domain.com

DB_CONNECTION=mysql
DB_HOST=staging-db.your-domain.com
DB_DATABASE=inventory_staging

CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis

MAIL_MAILER=smtp
LOG_CHANNEL=daily
LOG_LEVEL=info

Production Environment

# .env.production
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com

DB_CONNECTION=mysql
DB_HOST=production-db.your-domain.com
DB_DATABASE=inventory_production

CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis

MAIL_MAILER=smtp
LOG_CHANNEL=daily
LOG_LEVEL=error

# Security settings
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=strict

Performance Configuration

PHP Configuration (php.ini)

; Memory and execution limits
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
max_input_vars = 3000

; File upload settings
upload_max_filesize = 64M
post_max_size = 64M
max_file_uploads = 20

; OPcache configuration
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1

Database Configuration

MySQL/MariaDB Configuration

; my.cnf / my.ini
[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
query_cache_type = 1
query_cache_size = 128M
max_connections = 200

Redis Configuration

# redis.conf
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000

Security Configuration

Web Server Security Headers

Apache (.htaccess)

# Security headers
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

# Content Security Policy
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'"

Nginx

# Security headers
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

Laravel Security Configuration

// config/cors.php
<?php

return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];

Monitoring Configuration

Laravel Telescope (Development)

TELESCOPE_ENABLED=true
TELESCOPE_PATH=telescope

Laravel Horizon (Queue Monitoring)

HORIZON_PATH=horizon
HORIZON_ENVIRONMENT=production

Log Configuration for Monitoring

// config/logging.php
'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['single', 'slack'],
        'ignore_exceptions' => false,
    ],

    'slack' => [
        'driver' => 'slack',
        'url' => env('LOG_SLACK_WEBHOOK_URL'),
        'username' => 'Laravel Log',
        'emoji' => ':boom:',
        'level' => env('LOG_LEVEL', 'critical'),
    ],
],

Configuration Validation

Environment Validation

Create a configuration validation command:

php artisan make:command ValidateConfiguration
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ValidateConfiguration extends Command
{
    protected $signature = 'config:validate';
    protected $description = 'Validate application configuration';

    public function handle()
    {
        $this->info('Validating application configuration...');

        // Check database connection
        try {
            DB::connection()->getPdo();
            $this->info('✅ Database connection: OK');
        } catch (\Exception $e) {
            $this->error('❌ Database connection: FAILED');
            $this->error($e->getMessage());
        }

        // Check storage disks
        $disks = ['local_upload_images', 'local_available_images', 'local_pictures'];
        foreach ($disks as $disk) {
            try {
                Storage::disk($disk)->exists('test');
                $this->info("✅ Storage disk '{$disk}': OK");
            } catch (\Exception $e) {
                $this->error("❌ Storage disk '{$disk}': FAILED");
                $this->error($e->getMessage());
            }
        }

        // Check required environment variables
        $required = ['APP_KEY', 'DB_CONNECTION', 'APP_URL'];
        foreach ($required as $env) {
            if (env($env)) {
                $this->info("✅ Environment variable '{$env}': OK");
            } else {
                $this->error("❌ Environment variable '{$env}': MISSING");
            }
        }

        $this->info('Configuration validation complete.');
    }
}

Next Steps