Included |
---|
✅ Basic setting |
✅ Phpstan |
✅ PHP CS Fixer |
✅ Rector |
✅ TypeScript |
✅ Xdebug |
✅ Docker |
✅ GitHub actions |
✅ Makefile |
- Run the git clone command
git clone [email protected]:dev-lnk/laravel-blank.git .
. - Copy the
.env.example
file and rename it to.env
, customize the#Docker
section to your needs. - Run the command
make build
, and thenmake install
. - Check the application's operation using the link
http://localhost
orhttp://localhost:${APP_WEB_PORT}
. - Run stat analysis and tests using the command
make test
.
This is a blank Laravel 12 project set up to get started with development. What the setup includes:
- Configured docker for local development.
- Middleware is configured in a separate file.
namespace App\Http\Middleware;
use Illuminate\Foundation\Configuration\Middleware;
class MiddlewareHandler
{
protected array $aliases = [
//'auth' => AuthMiddleware::class
];
public function __invoke(Middleware $middleware): Middleware
{
if ($this->aliases) {
$middleware->alias($this->aliases);
}
return $middleware;
}
}
- Cron jobs are configured in a separate file.
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
class ScheduleHandler
{
public function __invoke(Schedule $schedule): void
{
//$schedule->command(HealthCommand::class)->hourly();
}
}
- Exception handling is configured in a separate file
namespace App\Exceptions;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Http\Request;
class ExceptionsHandler
{
public function __invoke(Exceptions $exceptions): Exceptions
{
$exceptions->renderable(
function (NotFoundHttpException $e, ?Request $request = null) {
if($request?->is('api/*')) {
return $this->jsonResponse($e->getStatusCode());
}
return response()->view('errors.404', status: $e->getStatusCode());
}
);
return $exceptions;
}
private function jsonResponse(int $code): JsonResponse
{
return response()->json([
'error' => "HTTP error: $code"
])->setStatusCode($code);
}
}
- Configured tests.
namespace Tests;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;
abstract class TestCase extends BaseTestCase
{
use RefreshDatabase;
protected bool $seed = true;
protected function setUp(): void
{
parent::setUp();
Artisan::call('optimize:clear');
Notification::fake();
Http::preventStrayRequests();
$this->withoutVite();
}
}
- Added RouteServiceProvider
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
public function boot(): void
{
// $this->routes(function () {
// Route::middleware(['web', 'app.auth'])
// ->namespace($this->namespace)
// ->prefix('my')
// ->group(base_path('routes/my.php'));
// });
}
}
- Installed and configured phpstan (max level).
- Installed and configured TypeScript, used instead of JavaScript.
The final bootstrap/app.php
file looks like this:
<?php
use App\Console\ScheduleHandler;
use App\Exceptions\ExceptionsHandler;
use App\Http\Middleware\MiddlewareHandler;
use Illuminate\Foundation\Application;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(new MiddlewareHandler())
->withSchedule(new ScheduleHandler())
->withExceptions(new ExceptionsHandler())
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->create();
- nginx:1.29-alpine
- php:8.4-fpm (with xdebug)
- mysql:9.4
- redis:8.2.0-alpine
- node:24.5-alpine3.22
- Many commands to speed up development and work with docker can be found in the
Makefile
- If you don't need Docker, remove:
/docker
,docker-compose.yml
,Makefile
. Convert.env
to standard Laravel form - To launch containers with
worker
andscheduler
, delete comments on the corresponding blocks indocker-compose.yml