Deploying Laravel Applications
Laravel on Ploi Cloud
Ploi Cloud is optimized for Laravel applications, providing automatic configuration and best practices out of the box.
Automatic Configuration
When you create a Laravel application, Ploi Cloud automatically:
- Sets up the correct PHP version and extensions
- Installs your Composer dependencies
- Runs database migrations during deployment
- Generates a secure APP_KEY for encryption
- Configures Laravel scheduler (when enabled)
Environment Secrets
Essential environment variables for Laravel applications:
APP_ENV=production
APP_DEBUG=false
Database connection variables are automatically injected when you add a database service.
Database Migrations
Migrations run automatically as init commands during deployment:
- The default command is
php artisan migrate --force - Migrations execute when your application starts, before serving traffic
- If migrations fail, the application startup stops to prevent issues
- Init commands run on every deployment to ensure your database is up to date
Queue Workers
To process Laravel queues, add a Worker service:
- Navigate to your application's Services section
- Click "Add service" and select "Worker"
- Enter a descriptive name (e.g., "queue-worker")
- Set the command to
php artisan queue:work --sleep=3 --tries=3 - Deploy your application to start the worker
Workers use the same code and storage as your main application.
Laravel Scheduler
The Laravel scheduler runs your scheduled tasks automatically:
- Go to your application's Settings tab
- Find the "Laravel scheduler" section
- Toggle "Enable scheduler" to activate it
- Deploy your application to apply the change
The scheduler executes php artisan schedule:run every minute.
Build Commands
Default build commands for Laravel applications:
composer install --no-interaction --optimize-autoloader --no-dev- If you enable frontend builds:
npm ciandnpm run build
You can customize these in the Build Configuration section.
HTTPS URLs behind the load balancer
Ploi Cloud terminates TLS at the load balancer and forwards requests to your application over plain HTTP, adding the standard X-Forwarded-Proto: https header. This internal hop stays on the private network between the load balancer and your application, so it is not insecure. It is the standard pattern for any app sitting behind a reverse proxy or load balancer. Laravel only honours that header when the TrustProxies middleware is registered. Without it, helpers like route(), url(), action() and asset() generate URLs with http:// even though visitors arrived over HTTPS. This typically shows up as form action attributes, redirects, password reset or email verification links, or signed URLs being rendered with the wrong scheme.
On Laravel 11 and 12 the middleware is configured in bootstrap/app.php:
use Illuminate\Foundation\Application;
use Illuminate\Http\Middleware\TrustProxies;
use Illuminate\Http\Request;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*', headers: Request::HEADER_X_FORWARDED_FOR
| Request::HEADER_X_FORWARDED_HOST
| Request::HEADER_X_FORWARDED_PORT
| Request::HEADER_X_FORWARDED_PROTO
| Request::HEADER_X_FORWARDED_AWS_ELB);
})
->create();
On Laravel 10 and earlier, set $proxies = '*' in app/Http/Middleware/TrustProxies.php and make sure the middleware stays in the global $middleware array of app/Http/Kernel.php.
If your application uses a custom Http\Kernel that replaces the default middleware stack, add \Illuminate\Http\Middleware\TrustProxies::class back to the global $middleware array. Setting APP_URL=https://... is not enough on its own, because the URL generator uses the incoming request's scheme, not APP_URL, for requests served through the web server.
As a quick fallback you can also call URL::forceScheme('https') in AppServiceProvider::boot() when app()->environment('production'), but registering TrustProxies is the recommended fix because it also exposes the correct client IP and host.