Master environment and configuration management in Laravel. Learn how to secure your app with .env files, centralized config, and environment-specific logic.
Previously in this course, we explored Project Structure for Large Applications. While that lesson focused on organizing your domain code, this lesson provides the "glue" that allows that code to run safely across different stages of your deployment pipeline.
Managing configuration effectively is the difference between a project that runs seamlessly in development and one that crashes in production due to missing keys or incorrect database credentials.
In a professional Laravel application, code should be environment-agnostic. Your business logic shouldn't care if it's running on your local machine or a production server. To achieve this, we separate secrets/sensitive settings from the application code.
Laravel uses a two-tier approach to this:
.env file: This is your local "source of truth" for variables that change between environments (DB_PASSWORD, API_KEYS, etc.). It is never committed to version control.config/ directory: This is your source of truth for the application's internal structure. You reference these files throughout your code using the config() helper, which in turn pulls values from the $_ENV superglobal.Never access env() directly in your application logic (e.g., inside controllers or services). This is a common pitfall because the config:cache Artisan command will return null for any env() call once the configuration is cached for performance.
Instead, define your settings in a file within config/. Let’s look at how we’d handle a third-party integration for our project board:
PHP#6A9955">// config/services.php return [ 'jira' => [ 'api_key' => env('JIRA_API_KEY'), 'base_url' => env('JIRA_BASE_URL', 'https:#6A9955">//api.atlassian.com'), ], ];
By mapping the .env value to a configuration key here, you ensure that even when the config is cached in production, config('services.jira.api_key') will return the correct value. You can read more about these Secret management best practices to ensure your keys remain safe.
Sometimes, you need to swap out entire implementations based on the environment. For instance, you might want to use a LogViewerService in local that stores data in a file, but use an ElasticsearchService in production.
You can use the AppServiceProvider or create custom providers to handle this conditional logic during the application bootstrap phase:
PHP#6A9955">// app/Providers/AppServiceProvider.php public function register() { if ($this->app->environment('local')) { $this->app->bind(ExternalIntegrationInterface::class, LocalMockIntegration::class); } else { $this->app->bind(ExternalIntegrationInterface::class, ProductionIntegration::class); } }
This allows your core business logic to remain untouched while the "plumbing" adjusts to the needs of the devops environment.
In our ongoing project board, we need to integrate a third-party notification service.
config/notifications.php.webhook_url key that reads from NOTIFICATIONS_WEBHOOK_URL in your .env.NotificationService to inject this value using config('notifications.webhook_url') instead of calling env() directly.php artisan config:show notifications (if using a package) or by inspecting config() in a tinker session..env values: As mentioned, avoid calling env() inside your classes. Always wrap them in a config/ file. If you find your configuration returning null after deployment, this is almost certainly the cause..env: Never commit your .env file to Git. Use .env.example to provide a template of required keys for other developers.development and production environments similar can lead to "it works on my machine" bugs. To mitigate this, consider Handling Environment Parity: Ensuring ML Pipeline Consistency strategies, which apply to general web development as well.Effective environment management keeps your application portable and secure. Always use the config/ directory as a bridge between your environment variables and your code. By centralizing these settings and leveraging service providers for environment-specific logic, you maintain a clean, testable, and robust codebase.
Up next: Deploying Laravel Applications. We will take the configurations we just mastered and apply them to a real-world production deployment workflow.
Master OAuth2 implementation in Laravel by building a secure Authorization Code flow. Learn to handle token issuance, validation, and architectural best practices.
Read moreLearn how to use Laravel Horizon for advanced queue monitoring, failure management, and performance tuning to keep your background jobs running smoothly.
Environment and Configuration Management