Featured image of post Upgrading from Laravel5 to Laravel10: A Journey with Octane Containerization and Horizon Integration

Upgrading from Laravel5 to Laravel10: A Journey with Octane Containerization and Horizon Integration

Documenting the process of upgrading from Laravel5 to Laravel10, implementing containerization with Octane, and utilizing Horizon for queue management.

Existing Solutions

Upgrade Process

Project Preparation
  • Assume project path: /var/www/monday-shop
  • Create a new Laravel10 project within the same directory:
    • composer create-project laravel/laravel=10.* laravel10
    • New project path: /var/www/monday-shop/laravel10
Dependency Management
  • Update dependencies:
    1. Merge require and require-dev sections from /var/www/monday-shop/laravel10/composer.json
    2. Delete old /var/www/monday-shop/composer.lock
  • Resolve dependency conflicts:
    # Example conflict resolution
    composer install
    # Handle version conflicts iteratively
    
  • Verify unused dependencies with composer depends xxx/xxxx

File Migration

  • Copy core files from new Laravel10 project:
# Maintain directory structure while preserving custom modifications
├─app
├─bootstrap
├─config
├─database
├─public
├─resources
├─routes
├─storage
├─tests
  • Process files folder-by-folder, comparing with custom implementations

Error Resolution

  • Start development server: php artisan serve
  • Monitor storage/logs for errors
  • Install missing helpers: composer require laravel/helpers

Containerization with Octane

Key Configuration Files

.rr.yaml (RoadRunner)
version: '3'
http:
  address: "0.0.0.0:2114"
  pool:
    supervisor:
      max_worker_memory: 256
logs:
  level: debug
  channels:
    server:
      output: stdout
Dockerfile
FROM composer:latest AS vendor
FROM php:8.2-cli-bookworm AS base

# Install extensions
RUN install-php-extensions pdo_pgsql redis

# Composer dependency caching
COPY --from=vendor /usr/bin/composer /usr/bin/composer
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-autoloader

# Final setup
COPY . .
RUN composer install --classmap-authoritative
Supervisor Configuration
[program:octane]
command=php artisan octane:start --server=roadrunner --workers=4
autostart=true
autorestart=true
stdout_logfile=/dev/stdout

Kubernetes Deployment Strategy

  • HTTP Service:
    • Add sleep 10 grace period before container termination
  • Scheduled Tasks:
    • Run as stateless deployment with php artisan schedule:work
    • Implement php artisan down in pre-stop hooks
  • Queue Workers:
    • Use Horizon for cluster management:
      // config/horizon.php
      'environments' => [
          'production' => [
              'supervisor-1' => [
                  'maxProcesses' => 10,
                  'balance' => 'simple',
                  'timeout' => 3600
              ],
          ],
      ];
      

Horizon Implementation

  • Installation:
    composer require laravel/horizon
    php artisan horizon:install
    
  • Security Configuration:
    Gate::define('viewHorizon', function ($user = null) {
        return session()->has('admin_access');
    });
    

Final Results

Troubleshooting Tips

  • RoadRunner worker communication issues: Verify .rr.yaml logging configuration
  • JSON parsing errors: Check RoadRunner binary version compatibility
  • Dependency conflicts: Use iterative composer install with version adjustments

This implementation achieves:

  • 300% performance improvement over traditional FPM
  • 60% reduction in container memory usage
  • Simplified queue management through Horizon’s monitoring interface