Deploy Laravel to Production with Docker
Laravel is the most popular PHP framework in 2026, trusted for everything from SaaS products to e-commerce platforms. Deploying Laravel properly means running a PHP process manager, serving static assets, running queue workers, and managing environment configuration. Docker makes all of this reproducible and portable.
PandaStack runs Docker containers, supports managed PostgreSQL and MySQL databases, and deploys on every git push. This guide gets your Laravel application production-ready on PandaStack.
Prerequisites
- PHP 8.3+ and Composer installed locally
- Docker installed locally
- A GitHub account
- PandaStack CLI:
npm install -g @pandastack/cli
Step 1 — Create a Laravel Project
composer create-project laravel/laravel my-laravel-app
cd my-laravel-appTest locally:
php artisan serve
# http://localhost:8000Step 2 — Write a Production Dockerfile
Laravel can run its built-in server (php artisan serve) in a container. For a simple deployment:
FROM php:8.3-cli-alpine
RUN apk add --no-cache curl libpng-dev libzip-dev zip unzip && docker-php-ext-install pdo pdo_pgsql pdo_mysql zip gd
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts
COPY . .
RUN php artisan config:cache && php artisan route:cache && php artisan view:cache
EXPOSE 8000
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]Build and test locally:
docker build -t my-laravel-app .
docker run -p 8000:8000 -e APP_KEY=$(php artisan key:generate --show) -e DB_CONNECTION=sqlite -e DB_DATABASE=/tmp/db.sqlite my-laravel-app
curl http://localhost:8000Add a .dockerignore:
vendor/
node_modules/
.env
storage/logs/*.logStep 3 — Add a Health Check Endpoint
Create a route in routes/web.php:
Route::get('/health', function () {
return response()->json(['status' => 'ok']);
});Step 4 — Configure pandastack.json
{
"type": "container",
"healthCheckPath": "/health"
}Step 5 — Set Environment Variables
Laravel uses .env for configuration. In production, never commit .env to Git. Instead, set all variables in the PandaStack dashboard under Environment Variables:
APP_ENV=production
APP_KEY=base64:your-generated-key-here
APP_DEBUG=false
APP_URL=https://my-laravel-app.pandastack.io
DB_CONNECTION=pgsql
DB_HOST=your-pandastack-db-host
DB_PORT=5432
DB_DATABASE=laravel
DB_USERNAME=laravel_user
DB_PASSWORD=your-secure-password
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redisGenerate an application key locally:
php artisan key:generate --show
# base64:AbCdEf...Step 6 — Provision a Database
PandaStack supports PostgreSQL and MySQL for Laravel:
panda db create --type postgres --name laravel-dbThe connection details are added to your project environment automatically. Run migrations after your first deployment using the PandaStack CLI or from the dashboard terminal:
panda exec -- php artisan migrate --forceStep 7 — Push to GitHub and Deploy
git init
git add .
git commit -m "Laravel app with Docker and PandaStack config"
gh repo create my-laravel-app --private --source=. --pushDeploy via the CLI:
panda deployOr connect through [dashboard.pandastack.io](https://dashboard.pandastack.io): New Project → connect your GitHub repository → PandaStack detects the Dockerfile and builds.
Step 8 — Optimise for Production
After the first deployment, cache Laravel's config and routes (already in the Dockerfile, but verify they run):
RUN php artisan config:cache && php artisan route:cache && php artisan view:cacheFor queue workers, you can run a separate PandaStack cronjob that processes queued jobs:
# Set up a cronjob in PandaStack to run:
php artisan queue:work --onceStep 9 — Run Background Queue Workers
Laravel's queue system (Horizon, database queues, or Redis queues) requires a separate worker process. On PandaStack, run a queue worker as a cronjob that processes jobs continuously, or set up a second container image dedicated to the worker. To poll the queue periodically, configure a PandaStack cronjob in the dashboard to run:
php artisan queue:work --stop-when-emptyThis processes all pending jobs and exits cleanly — safe for scheduled execution. For Redis-backed queues, provision a managed Redis instance:
panda db create --type redis --name laravel-cacheVerify the Deployment
curl https://my-laravel-app.pandastack.io/health
# {"status":"ok"}
panda logs --followSummary
Laravel on PandaStack runs as a Docker container with managed PostgreSQL or MySQL. Set APP_KEY, database credentials, and other secrets in the dashboard, push to GitHub, and PandaStack handles the rest. Read more at [docs.pandastack.io](https://docs.pandastack.io).