---
title: "Working with Laravel config:cache"
date: "2016-10-25"
category: "php"
slug: "working-laravel-config-cache"
---

Laravel provides a static cache utility [via Artisan](https://laravel.com/docs/5.3/configuration) to collapse all configuration files into a single file for better performance:

`php artisan config:cache`

When run from the [[is-terminal-access-available]], the cached paths may differ from those used by the web server, causing application errors when the site is accessed via the browser.

## Solution

Override `bootstrap/app.php` to use a custom application loader that bypasses the cache in CLI mode and automatically regenerates it on web requests.

### Creating the Custom Bootstrapper

Create a file called **ApplicationWrapper.php** in **app/**:

<?php
namespace App;

use Illuminate\\Foundation\\Application;

class ApplicationWrapper extends Application {

    public function \_\_construct($basePath)
    {
        if (!isset($\_SERVER['SITE\_ROOT'])) {
            $\_SERVER['SITE\_ROOT'] = '';
        }
        parent::\_\_construct($basePath);
    }

   /\*\*
    \* Fake configuration cache response for CLI
    \* as paths will always be different
    \*
    \* @return bool
    \*/
    public function configurationIsCached() {
        if ($this->runningInConsole()) {
            return false;
        }
        return parent::configurationIsCached();
    }

   /\*\*
    \* Emulate \\Illuminate\\Foundation\\Console\\ConfigCache\\fire()
    \*
    \* @return bool
    \*/
    public function doCache() {
       if (!$this->runningInConsole()) {
           $config = $this->app['config']->all();
           $this->files->put(
               $this->getCachedConfigPath(), '<?php return '.var\_export($config, true).';'.PHP\_EOL
           );
       }
        return true;
    }

    /\*
     \* Override boot to register production config cache
     \* @return boolean
     \*/
    public function boot()
    {
        parent::boot();
        if ($this->environment() !== "production") {
           return;
        }
        if (!$this->runningInConsole()) {
            $app = $this->app;
            $this->terminating(function() use ($app) {
                $app->configurationIsCached() || $app->doCache();
            });
        } else {
           $path = parent::getCachedConfigPath();
           $this->terminating(function() use ($path) {
              file\_exists($path) && unlink($path);
           });
        }

    }
}

Key details:

1. Cache generation happens post-boot so configuration is fully loaded. Caching occurs once at the end of the request to minimize overhead.
2. `APP_ENV` is assumed to be "production", controlled by [.env](https://laravel.com/docs/configuration#environment-configuration).
3. `artisan config:cache` creates then immediately removes `config.php`, allowing the web server to regenerate it.

### Updating bootstrap/app.php

In **bootstrap/app.php**, change:

$app = new Illuminate\\Foundation\\Application(
    realpath(\_\_DIR\_\_.'/../')
);

to:

$app = new App\\ApplicationWrapper(
    realpath(\_\_DIR\_\_.'/../')
);

Run `php artisan config:clear` to trigger automatic regeneration on the next page request.

### Regenerating Cache on Git Push

Create a `hooks/post-receive` file in your git repository on the server:

#!/bin/sh
LIVE="/var/www/"

read oldrev newrev refname
if [[ $refname = "refs/heads/master" ]]; then
    echo "===== DEPLOYING TO LIVE SITE ====="
    unset GIT\_DIR
    cd $LIVE
    ./build.sh
    echo "===== DONE ====="
fi

Create a **build.sh** script (assuming your Laravel app is at `/var/www/laravel-directory` and git repository at `/var/www/git-repository`):

#!/bin/sh
pushd /var/www/laravel-directory
git pull /var/www/git-repository
# Recompile all class defs into a monolithic file
php artisan optimize --force
php artisan config:clear

Now every `git push` will automatically deploy, generate a class loader, and clear the configuration cache:

$ git push
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 440 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: ===== DEPLOYING TO LIVE SITE =====
remote: /var/www/laravel-production /var/www
remote: From ./../git
remote: \* branch HEAD -> FETCH\_HEAD
remote: Updating b7b99b8..d4f04a5
remote: Fast-forward
remote: config/filesystems.php | 4 ++--
remote: config/view.php | 4 ++--
remote: 2 files changed, 4 insertions(+), 4 deletions(-)
remote: Generating optimized class loader
remote: Compiling common classes
remote: Configuration cache cleared!
remote: ===== DONE =====
To ssh://apnscp#apnscp.com@luna.apnscp.com/var/www/git
 b7b99b8..d4f04a5 master -> master
