PreviewDrop for Laravel

Deploy previews for Laravel apps

Push a branch, get a live preview URL. PreviewDrop builds your Laravel container and posts the link to the pull request, usually within a couple of minutes — no CI scripts, no Bref adapters.

TL;DR
Connect your repo, push. PreviewDrop detects Laravel, builds the image and posts a TLS-terminated PR preview URL. Add artisan migrate --force to your Start command to migrate on boot. Laravel runs as a persistent PHP process — queues, scheduled jobs, and long-running requests work without serverless adapters.

What the build needs to do

You don't write this. PreviewDrop detects Laravelfrom your repo and builds the container for you — a Dockerfile in your repo is not used. The reference below shows the install, build and start steps a working Laravel image needs. If detection gets one wrong, set the matching Install, Build or Start command in Project Settings. Your app must listen on $PORT.

Reference (not read by PreviewDrop)
FROM php:8.3-cli RUN apt-get update -qq && apt-get install -y unzip git libpq-dev && docker-php-ext-install pdo pdo_pgsql && rm -rf /var/lib/apt/lists/* RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer WORKDIR /app COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-interaction COPY . . RUN php artisan storage:link EXPOSE 8000 CMD sh -c "php artisan migrate --force && php artisan serve --host=0.0.0.0 --port=${PORT:-8000}"

Environment variables

Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.

VariableExample valueNote
APP_KEYbase64:...Generate with: php artisan key:generate --show. Required — Laravel refuses to start without it.
APP_ENVstagingUse "staging" for previews — enables error display but disables some prod-only optimisations.
APP_URLhttps://your-preview.previewdrop.appProject variables are shared by every preview. Laravel uses this for URL generation and redirects.
DB_CONNECTIONpgsqlMatch to your dev database type. The reference build above installs pdo_pgsql.
DATABASE_URLpostgres://user:pass@host:5432/dbAlternatively set DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD individually.

Common gotchas

APP_KEY is required — Laravel will not start without it

Generate your app key with php artisan key:generate --show and paste the result into PreviewDrop project variables as APP_KEY. For previews, a dedicated key is fine — don't reuse your production key.

artisan serve is for previews, not high-traffic production

php artisan serve is PHP's built-in server — perfectly fine for pull request previews where a few engineers are the audience. For production, replace it with Octane (Swoole/FrankenPHP) or an nginx + php-fpm setup.

Storage permissions

Laravel writes logs, cache, and session files under storage/ and bootstrap/cache/. If you see permission errors, add chmod -R 775 storage bootstrap/cache to your Build command in Project Settings.

pdo_mysql vs pdo_pgsql

The reference build above installs pdo_pgsql and has pdo_mysql available via the base image. Set DB_CONNECTION to match your database. If you use MySQL, replace libpq-dev and pdo_pgsql with the MySQL equivalents.

Why not Vercel or Netlify?

Vercel's serverless runtime runs Node.js, not PHP. Bref adapters can run Laravel on AWS Lambda, but you lose queue workers, scheduled jobs, long-running requests, and direct artisan access. Netlify has no PHP runtime at all. PreviewDrop runs your app in a real container: PHP, queues, storage — the full Laravel stack as a PR deploy preview, without adapters or function-time limits.

Preview your Laravel app in 5 minutes

Connect a repo, push a branch, get a URL. No credit card, no trial clock.

Start free