DEV Community

Cover image for Production-Ready Docker Setup for Laravel & Filament
yebor974 for Filament Mastery

Posted on • Originally published at filamentmastery.com

Production-Ready Docker Setup for Laravel & Filament

Introduction

Most Docker setups for Laravel applications are… fine.

They work locally, they run php artisan serve, and that’s about it.

But when you start building real-world Laravel & Filament applications used in production, those setups quickly become a liability:

  • slow builds
  • bloated images
  • security issues
  • poor separation between development and production

I’ve personally run into these issues multiple times before refining this setup.

👉 This article focuses on the core ideas and architecture.
The full production-ready implementation (with complete Dockerfile, edge cases and CI/CD integration) is available on Filament Mastery.


What This Article Covers

In this article, I’ll walk through the key concepts behind a Docker setup I use in production for Laravel & Filament projects.

This includes:

  • multi-stage builds
  • optimized dependency installation
  • frontend asset compilation
  • non-root execution for better security
  • environment-specific configuration (dev vs production)

The Problem with “Basic Docker Setups”

A typical Dockerfile often looks like this:

FROM php:8.4-fpm
COPY . .
RUN composer install
RUN npm install
Enter fullscreen mode Exit fullscreen mode

Simple… but problematic.

Main issues:

  • installs dev dependencies in production
  • no asset compilation strategy
  • runs as root
  • large and slow images
  • no separation of concerns

👉 This is fine for learning, but not for production.


A Better Approach

Instead of a single container doing everything, I rely on multi-stage builds and clear separation of responsibilities.

Typical structure:

  • a Composer stage to install PHP dependencies
  • a Node stage to build frontend assets
  • a final PHP-FPM image focused only on runtime

👉 The goal is simple: keep the runtime image as small, secure and predictable as possible.


Key Idea: Build-Time vs Runtime

One of the biggest improvements comes from moving as much work as possible to build time.

In my experience, this means:

  • installing dependencies during build (not at runtime)
  • compiling assets once
  • shipping only the final artifacts

👉 The container becomes immutable and easier to reason about.


Example (Simplified)

Instead of a single-stage Dockerfile, the idea is to split concerns:

# Composer stage (dependencies)
RUN composer install --no-dev

# Node stage (assets)
RUN npm ci && npm run build

# Final image
COPY built assets + vendor only
Enter fullscreen mode Exit fullscreen mode

👉 This is intentionally simplified, but it reflects the core idea.


Why This Matters

With this approach:

  • builds are faster thanks to caching
  • images are significantly smaller
  • attack surface is reduced
  • development and production concerns are clearly separated

In production environments, these differences quickly become critical.


Going Further

This article only covers the Docker image itself.

In a real production setup, you also need:

  • a proper Docker Compose architecture
  • a CI/CD pipeline to build and validate images
  • deployment strategies

👉 I’m progressively documenting this production setup (Docker, Compose, CI/CD and more) here:
https://filamentmastery.com/articles/production-ready-docker-setup-for-laravel-filament/

Docker setups are often underestimated in Laravel projects.

But in my experience, investing in a clean, production-ready setup early saves a lot of time later, especially when your application starts scaling.

Top comments (0)