Simplify Your Laravel Project Installation with One Custom Command
Overview
This article will demonstrate how to create a command to install your Laravel project. The command will ensure that the application is consistent across all team members by executing all the necessary steps to get the application up and running.
Introduction
When working with a Laravel project, you don't want to complicate your life by requiring your team members to run different commands to get your application working. Instead, creating one command that executes everything needed ensures that everything is consistent within everyone's application.
Creating the Command
To create the command, start by running the following command:
art make:command System/InstallCommand
This will create the command under app/Console/Commands/System
. You can create additional directories inside the Commands
directory to keep your application more organized. For example, you could lump all system:*
commands under the System/
directory.
Here is the code for the InstallCommand
:
<?php
declare(strict_types=1);
namespace App\Console\Commands\System;
use App;
use Illuminate\Console\Command;
class InstallCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'system:install';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Install the application on a non-production environment.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
// Check that the application you are installing has the proper .env configuration
if (config('app.name') !== 'myappname') {
$this->error('Application name is not myappname.');
return Command::FAILURE;
}
// Check if this command is being run in production
if ($this->isRunningInProduction()) {
$this->error('Cannot run this command in production.');
return Command::FAILURE;
}
// Create symbolic links
$this->info('Create Symbolic links.');
$this->call('storage:link', ['--force' => true]);
// Clear cached bootstrap files
$this->clearCommands();
// Migrate and seed a fresh database to work with
$this->info('Migrate and seed a fresh database to work with.');
$this->call('migrate:fresh', ['--seed' => true]);
// Display success message
$this->line('[Installation is now complete]', 'info');
return Command::SUCCESS;
}
/**
* Check if this command is being run in production
*
* @return bool
*/
protected function isRunningInProduction(): bool
{
return App::isProduction() === true;
}
/**
* Clear cached bootstrap files
*/
protected function clearCommands(): void
{
$this->info('Clearing cached bootstrap files.');
// Clear cached bootstrap files such as optimize and queue
collect([
'optimize' => fn () => $this->callSilent('optimize:clear') == 0,
'queue' => fn () => $this->callSilent('queue:clear') == 0,
])->each(fn ($task, $description) => $this->command->task($description, $task));
$this->newLine();
}
}
Explanation
When you run the system:install
command, several things happen:
- The command checks to make sure that the application you are installing has the proper .env configuration. This code checks that
config('app.name')
matchesmyappname
. This initial check ensures that your environment variables match.
if (config('app.name') !== 'myappname') {
$this->error('Application name is not myappname.');
return Command::FAILURE;
}
- The command checks whether it is being run in production, to avoid accidentally installing your application on a live server. This method should have more complex logic, check to make sure that specific critical configuration variables hold non-production values in a way to not divulge any sensitive information.
if ($this->isRunningInProduction()) {
$this->error('Cannot run this command in production.');
return Command::FAILURE;
}
- The command creates the storage links configured:
$this->call('storage:link', ['--force' => true]);
- Your custom command runs
optimize:clear
, which as of Laravel 10 clearsevents
,views
,cache
,route
,config
, andcompiled
by default. In the code we added an additional item during an app install such asqueue:clear
, you can check your packages to add additional clear commands.
$this->clearCommands();
- The command runs
migrate:fresh
with the seed, to drop and create the tables from a fresh state. This allows you to work between separate branches without any issues that are introduced with rollbacks.
$this->call('migrate:fresh', ['--seed' => true]);
- The command displays a message and sends the success signal to instruct the machine running this command that everything installed correctly and fire off any additional commands as needed.
$this->line('[Installation is now complete]', 'info');
By following these steps and creating a consistent installation process, you can save yourself and your team members time and unnecessary hassle when working on your Laravel project.