Laravel Development Setup

#laravel #php #setup #development #environment #docker

Last Updated: May 18, 2025 Related: .NET vs Laravel Complete Developer Guide


Quick Navigation


Development Environment Setup

Laravel Sail (Official Docker Environment)

# Create new Laravel project with Sail
curl -s https://laravel.build/my-app | bash
cd my-app

# Start the application
./vendor/bin/sail up -d

# Access the application
# http://localhost

Custom Docker Setup

# docker-compose.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html
    depends_on:
      - database
      - redis
    environment:
      - APP_ENV=local
      - APP_DEBUG=true

  database:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: laravel
      MYSQL_PASSWORD: password
    volumes:
      - db_data:/var/lib/mysql

  redis:
    image: redis:alpine
    ports:
      - "6379:6379"

  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025"
      - "8025:8025"

volumes:
  db_data:

๐Ÿ’ป Local Development Setup

Requirements

Installation Commands

# Install PHP and dependencies (Ubuntu/Debian)
sudo apt update
sudo apt install php8.2 php8.2-cli php8.2-common php8.2-mysql \
php8.2-xml php8.2-curl php8.2-mbstring php8.2-zip php8.2-gd

# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Install Node.js (using NodeSource)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

Laravel Installation Methods

๐Ÿš€ Laravel Installer

# Install Laravel installer globally
composer global require laravel/installer

# Create new project
laravel new my-app
cd my-app

# Alternative: Create with specific version
laravel new my-app --version=10.*

๐Ÿ“ฆ Composer Create-Project

# Create new Laravel project
composer create-project laravel/laravel my-app

# With specific version
composer create-project laravel/laravel:^10.0 my-app

# For development (includes dev dependencies)
composer create-project laravel/laravel my-app --prefer-source

โš™๏ธ Initial Configuration

# Generate application key
php artisan key:generate

# Set up environment file
cp .env.example .env

# Configure database in .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_app
DB_USERNAME=root
DB_PASSWORD=password

# Run migrations
php artisan migrate

# Link storage directory
php artisan storage:link

Database Configuration

๐Ÿ—„๏ธ Multiple Database Connections

// config/database.php
'connections' => [
    'primary' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'primary_db'),
        'username' => env('DB_USERNAME', 'root'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],
    
    'analytics' => [
        'driver' => 'mysql',
        'host' => env('ANALYTICS_DB_HOST', '127.0.0.1'),
        'database' => env('ANALYTICS_DB_DATABASE', 'analytics_db'),
        'username' => env('ANALYTICS_DB_USERNAME', 'root'),
        'password' => env('ANALYTICS_DB_PASSWORD', ''),
        // ... other config
    ],

    'testing' => [
        'driver' => 'sqlite',
        'database' => ':memory:',
        'prefix' => '',
    ],
];

// Usage in models
class User extends Model
{
    protected $connection = 'primary';
}

class AnalyticsEvent extends Model
{
    protected $connection = 'analytics';
}

๐Ÿ“Š Database Seeding Setup

// database/seeders/DatabaseSeeder.php
class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        if environment('local', 'staging') {
            $this->call([
                UserSeeder::class,
                ProductSeeder::class,
                CategorySeeder::class,
            ]);
        }
        
        // Production-safe seeders
        $this->call([
            RoleSeeder::class,
            PermissionSeeder::class,
        ]);
    }
}

// Example seeder with factory
class UserSeeder extends Seeder
{
    public function run(): void
    {
        // Create admin user
        User::factory()->create([
            'name' => 'Admin User',
            'email' => 'admin@example.com',
            'email_verified_at' => now(),
            'role' => 'admin',
        ]);
        
        // Create test users
        User::factory(50)->create();
    }
}

// Run seeders
php artisan db:seed
php artisan db:seed --class=UserSeeder

Essential Packages

๐Ÿ› ๏ธ Development Packages

# Debug and profiling
composer require --dev barryvdh/laravel-debugbar
composer require --dev barryvdh/laravel-ide-helper

# Testing
composer require --dev pestphp/pest
composer require --dev pestphp/pest-plugin-laravel

# Code quality
composer require --dev nunomaduro/larastan
composer require --dev squizlabs/php_codesniffer

# API documentation
composer require --dev darkaonline/l5-swagger

๐Ÿ“ฆ Production Packages

# API resources and validation
composer require spatie/laravel-query-builder
composer require spatie/laravel-permission

# Monitoring and logging
composer require spatie/laravel-activitylog
composer require sentry/sentry-laravel

# Performance
composer require predis/predis  # Redis client
composer require pusher/pusher-php-server  # WebSocket support

# Image processing
composer require intervention/image

โšก Frontend Assets Setup

# Install Node dependencies
npm install

# Development build
npm run dev

# Watch for changes
npm run watch

# Production build
npm run build

# Install additional packages
npm install axios vue@next @vitejs/plugin-vue
npm install --save-dev tailwindcss autoprefixer

Development Workflow

๐Ÿ”ง Artisan Commands Reference

# Application
php artisan serve                    # Start development server
php artisan down                     # Put app in maintenance mode
php artisan up                       # Bring app back online

# Database
php artisan migrate                  # Run migrations
php artisan migrate:rollback         # Rollback migrations
php artisan migrate:refresh --seed   # Refresh and seed
php artisan db:wipe                  # Drop all tables

# Code generation
php artisan make:controller UserController --resource
php artisan make:model User -mfcs   # Model with migration, factory, controller, seeder
php artisan make:request StoreUserRequest
php artisan make:middleware CheckAge

# Optimization
php artisan optimize                 # Optimize for production
php artisan optimize:clear           # Clear optimization cache
php artisan config:cache             # Cache configuration
php artisan route:cache              # Cache routes
php artisan view:cache               # Cache views

๐Ÿ—๏ธ Project Structure Conventions

app/
โ”œโ”€โ”€ Console/Commands/          # Custom Artisan commands
โ”œโ”€โ”€ Http/
โ”‚   โ”œโ”€โ”€ Controllers/
โ”‚   โ”‚   โ”œโ”€โ”€ Api/              # API controllers
โ”‚   โ”‚   โ””โ”€โ”€ Web/              # Web controllers
โ”‚   โ”œโ”€โ”€ Middleware/
โ”‚   โ”œโ”€โ”€ Requests/             # Form requests
โ”‚   โ””โ”€โ”€ Resources/            # API resources
โ”œโ”€โ”€ Models/
โ”œโ”€โ”€ Services/                 # Business logic
โ”œโ”€โ”€ Repositories/             # Data access layer
โ””โ”€โ”€ Jobs/                     # Queued jobs

resources/
โ”œโ”€โ”€ views/
โ”‚   โ”œโ”€โ”€ components/           # Blade components
โ”‚   โ”œโ”€โ”€ layouts/              # Page layouts
โ”‚   โ””โ”€โ”€ partials/             # Reusable partials
โ”œโ”€โ”€ js/                       # JavaScript files
โ””โ”€โ”€ css/                      # Stylesheets

config/                       # Configuration files
database/
โ”œโ”€โ”€ migrations/
โ”œโ”€โ”€ factories/
โ””โ”€โ”€ seeders/

tests/
โ”œโ”€โ”€ Feature/                  # Feature tests
โ”œโ”€โ”€ Unit/                     # Unit tests
โ””โ”€โ”€ Pest.php                  # Pest configuration

๐Ÿ”„ Git Workflow

# .gitignore additions for Laravel
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log

# Pre-commit hooks setup
composer require --dev brianium/paratest
composer require --dev phpunit/phpunit

# Add to package.json scripts
"scripts": {
    "test": "php artisan test",
    "test:parallel": "php artisan test --parallel",
    "lint": "phpcs --standard=PSR12 app/",
    "lint:fix": "phpcbf --standard=PSR12 app/"
}

Testing Setup

๐Ÿงช Pest PHP Configuration

// tests/Pest.php
use Illuminate\Foundation\Testing\RefreshDatabase;

usesclass, RefreshDatabase::class)->in('Feature';
usesclass)->in('Unit';

// Global functions
function actingAsUser($user = null): TestCase
{
    $user = $user ?: User::factory()->create();
    return test()->actingAs($user);
}

function actingAsAdmin(): TestCase
{
    $admin = User::factory()->admin()->create();
    return test()->actingAs($admin);
}

โœ… Example Tests

// tests/Feature/UserRegistrationTest.php
<?php

test('user can register with valid data', function () {
    $userData = [
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'password' => 'password123',
        'password_confirmation' => 'password123',
    ];

    $response = $this->post('/register', $userData);

    $response->assertRedirect('/dashboard');
    $this->assertDatabaseHas('users', [
        'email' => 'john@example.com',
    ]);
});

test('user cannot register with invalid email', function () {
    $userData = [
        'name' => 'John Doe',
        'email' => 'invalid-email',
        'password' => 'password123',
        'password_confirmation' => 'password123',
    ];

    $response = $this->post('/register', $userData);

    $response->assertSessionHasErrors('email');
    $this->assertDatabaseMissing('users', [
        'email' => 'invalid-email',
    ]);
});

// tests/Unit/UserModelTest.php
test('user can have many posts', function () {
    $user = User::factory()->create();
    $posts = Post::factory(3)->create(['user_id' => $user->id]);

    expect($user->posts)->toHaveCount(3);
    expectclass;
});

๐Ÿญ Database Testing

// tests/TestCase.php
abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    protected function setUp(): void
    {
        parent::setUp();
        
        // Run migrations for each test
        $this->artisan('migrate:fresh');
        
        // Seed test data
        $this->seed();
    }

    protected function tearDown(): void
    {
        // Clean up after each test
        $this->artisan('migrate:reset');
        
        parent::tearDown();
    }
}

// Database assertions
test('product creation updates inventory', function () {
    $product = Product::factory()->create(['quantity' => 100]);
    
    $product->decreaseQuantity(20);
    
    expect($product->fresh()->quantity)->toBe(80);
    
    $this->assertDatabaseHas('products', [
        'id' => $product->id,
        'quantity' => 80,
    ]);
});

Environment Configuration

๐Ÿ”ง Environment Files

# .env.local (development with Docker)
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:generated-key
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=password

BROADCAST_DRIVER=redis
CACHE_DRIVER=redis
FILESYSTEM_DISK=local
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

๐Ÿ”’ Environment Validation

// config/app.php - Add validation for required env vars
if (app()->environment('production')) {
    $required = [
        'APP_KEY', 
        'DB_PASSWORD', 
        'MAIL_PASSWORD'
    ];
    
    foreach ($required as $var) {
        if (empty(env($var))) {
            throw new Exception("Required environment variable {$var} is not set");
        }
    }
}

// Or use a dedicated package
composer require vlucas/phpdotenv

// In bootstrap/app.php
$dotenv = Dotenv\Dotenv::createUnsafeImmutable(__DIR__.'/../');
$dotenv->load();
$dotenv->required(['APP_KEY', 'DB_CONNECTION']);

Performance Optimization

โšก Caching Strategies

// config/cache.php - Multiple cache stores
'stores' => [
    'file' => [
        'driver' => 'file',
        'path' => storage_path('framework/cache/data'),
    ],

    'redis' => [
        'driver' => 'redis',
        'connection' => 'cache',
        'lock_connection' => 'default',
    ],

    'tags' => [
        'driver' => 'redis',
        'connection' => 'cache',
    ],
],

// Usage
Cache::tags(['users', 'posts'])->put('user.1', $user, 3600);
Cache::tags(['posts'])->flush(); // Clear only post-related cache

// Model caching
class User extends Model
{
    public function getCachedPosts()
    {
        return Cache::remember(
            "user.{$this->id}.posts",
            3600,
            fn() => $this->posts()->get()
        );
    }
}

๐Ÿš€ Queue Configuration

// config/queue.php
'connections' => [
    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => env('REDIS_QUEUE', 'default'),
        'retry_after' => 90,
        'block_for' => null,
        'after_commit' => false,
    ],
],

// Job example
class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        public User $user
    ) {}

    public function handle(): void
    {
        Mail::to($this->user->email)->send(new WelcomeMail($this->user));
    }

    public function failed(Throwable $exception): void
    {
        // Handle failed job
        Log::error('Welcome email failed', [
            'user_id' => $this->user->id,
            'error' => $exception->getMessage(),
        ]);
    }
}

// Queue workers
php artisan queue:work --sleep=3 --tries=3 --timeout=60
php artisan queue:listen --timeout=60

Development Tools

๐Ÿ” Debugging Tools

// Install Laravel Debugbar
composer require barryvdh/laravel-debugbar --dev

// config/debugbar.php
'enabled' => env('DEBUGBAR_ENABLED', null),

// Add to .env
DEBUGBAR_ENABLED=true

// IDE Helper
composer require barryvdh/laravel-ide-helper --dev

// Generate helper files
php artisan ide-helper:generate
php artisan ide-helper:models
php artisan ide-helper:meta

// Telescope (for local development)
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migrate

๐Ÿ“Š Code Quality Tools

// Larastan (PHPStan for Laravel)
composer require --dev nunomaduro/larastan

// phpstan.neon
includes:
    - vendor/nunomaduro/larastan/extension.neon

parameters:
    paths:
        - app/
    level: 5
    ignoreErrors:
        - '#Call to an undefined method [a-zA-Z0-9\\_]+Illuminate\\Database\\Eloquent\\Builder#'

// Run analysis
./vendor/bin/phpstan analyse

// PHP CS Fixer
composer require --dev friendsofphp/php-cs-fixer

// .php-cs-fixer.php
<?php

$finder = PhpCsFixer\Finder::create()
    ->in(__DIR__)
    ->exclude(['bootstrap/cache', 'storage', 'vendor'])
    ->notPath('*.blade.php');

return (new PhpCsFixer\Config())
    ->setRules([
        '@PSR2' => true,
        'array_syntax' => ['syntax' => 'short'],
        'ordered_imports' => ['sort_algorithm' => 'alpha'],
        'no_unused_imports' => true,
    ])
    ->setFinder($finder);


Quick Commands Reference

Setup Commands

# New project with Sail
curl -s https://laravel.build/myapp | bash

# Traditional setup
composer create-project laravel/laravel myapp
cd myapp && php artisan key:generate

# Database setup
php artisan migrate:refresh --seed
php artisan db:seed --class=UserSeeder

Development Commands

# Serve application
php artisan serve
./vendor/bin/sail up -d

# Asset compilation
npm run dev
npm run watch
npm run build

# Testing
php artisan test
./vendor/bin/pest
php artisan test --parallel

Maintenance Commands

# Clear caches
php artisan optimize:clear
php artisan config:clear
php artisan cache:clear

# Optimization
php artisan optimize
php artisan config:cache
php artisan route:cache

Tags

#laravel #php #setup #development #docker #testing #environment


This setup guide should be updated as Laravel versions and best practices evolve.