1
votes

I'm have a question extremely similar to this unanswered one: laravel 5 maintenance page broken during composer update

I am new to Laravel (using version 5.2) and am trying to work out the deployment process. From what I've gathered, the workflow that I want to use (once I've made and thoroughly tested changes on a development server, of course) is to put the production site into maintenance mode, deploy changes via git, run composer/artisan tasks (composer update, php artisan migrate, etc.) and then take the production site out of maintenance mode.

The problem I'm running into is that if I have new providers in config/app.php, the live site displays an error message (until I run composer update) even while in maintenance mode.

Is there a way to have the maintenance mode view override the error view so that I can perform my updates in peace without the site telling the world that there are errors? I turned off error reporting so it at least doesn't show the specifics, but I'd love it if it kept any mention of errors on the DL while maintenance mode was enabled.

Alternatively, is there a better deployment workflow that I can use to eliminate this problem all together?

1
Are you using php artisan down and up?user2094178
If you can tell me please, where did you generate your avatar?user2094178

1 Answers

2
votes

Why not use symlinks for releases? Below is an example of a deployment process that I've used on Laravel applications with Envoy. Aside from the PHP variable notation, it would be straightforward to substitute a purely bash/shell script if you are not using Envoy. Essentially, having a script automates the deployment, and using symlinks can make the update nearly instantaneous. Additional benefits include previous releases existing for the unfortunate time when a rollback is necessary.

Note: The below script makes some basic assumptions:

  • Your .env file is in the $root_dir (ex: /var/www/my-website/.env).
  • Your vhost points to the site/public directory within the $root_dir (ex: /var/www/my-website/site/public). However, if you can not update the vhost, you can simply add the following to number 4 below in the empty line:

    ln -nfs {{ $app_dir }}/public {{ $root_dir }}/public ;
    sudo chgrp -h www-data {{ $root_dir }}/public;
    
  • You have added SSH keys to pull from Git repo

  • (optional) nodejs is installed

Here are the relevant example variables for the script:

$repo        = '[email protected]:myusername/my-repo.git';
$root_dir    = '/var/www/my-website';
$release_dir = '/var/www/my-website/releases';
$app_dir     = '/var/www/my-website/site';
$release     = 'release_' . date('YmdHis');
$branch      = 'master';

Here is the gist of the deployment process with code:

  1. Fetch the updated code into a new release directory:

    @task('fetch_repo')
    [ -d {{ $release_dir }} ] || mkdir {{ $release_dir }};
    cd {{ $release_dir }};
    git clone {{ $repo }} -b {{ $branch }} {{ $release }};
    @endtask
    
  2. Install the dependencies by running composer:

    @task('run_composer')
    cd {{ $release_dir }}/{{ $release }};
    composer install;
    @endtask
    
  3. (optional) If we are using asset precompiler like Elixir, we will want to fetch npm dependencies, reset permissions, and run gulp:

    @task('npm_install')
    cd {{ $release_dir }}/{{ $release }};
    sudo npm install;
    @endtask
    
    @task('update_permissions')
    cd {{ $release_dir }};
    sudo chgrp -R www-data {{ $release }};
    sudo chmod -R ug+rwx {{ $release }};
    @endtask
    
    @task('compile_assets')
    cd {{ $release_dir }}/{{ $release }};
    gulp --production;
    @endtask
    
  4. Update symlinks

    @task('update_symlinks')
    ln -nfs {{ $root_dir  }}/.env {{ $release_dir }}/{{ $release }}/.env;
    ln -nfs {{ $release_dir }}/{{ $release }} {{ $app_dir }};
    
    sudo chgrp -h www-data {{ $app_dir }};
    sudo service php5-fpm restart;
    @endtask
    
  5. (Optional) Prune old release folders (30+ days old) so we don't fill up the server.

    @task('prune_old')
    sudo find {{ $release_dir }} -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
    @endtask
    

Note: Restarting the php5-fpm service clears the cache that ensures the new symlink is followed.

I found it somewhat difficult to find deployment script examples (like the aforementioned) when I initially began developing with Laravel, so hopefully this will help alleviate some searching.