Every developer has experienced the classic frustration of deploying a web application to a live server only to watch it break completely. The code ran flawlessly on local development machines, but the production server had a different PHP version, missing extensions, or mismatched database configurations.
Containerization solves this problem by packaging your entire application along with its dependencies into a single isolated container. Let us look at how we containerize a production-ready Laravel application and MySQL database using Docker and Docker Compose.
1. Writing a Multi-Stage Dockerfile for PHP
For a production environment, you should avoid bloated development images. Using a multi-stage build allows you to compile dependencies cleanly without leaving unnecessary build tools in your final production image.
Here is a reliable structure for your application Dockerfile:
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
git curl libpng-dev libonig-dev libxml2-dev zip unzip
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
WORKDIR /var/www
COPY . .
RUN composer install --no-dev --optimize-autoloader
2. Orchestrating Services with Docker Compose
Managing multiple containers manually becomes complicated very quickly. Docker Compose allows you to define your entire web stack, including Nginx, PHP-FPM, and MySQL, inside a single YAML configuration file.
Make sure to use named volumes for your database container to ensure persistent data storage across container restarts:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
restart: always
volumes:
- .:/var/www
environment:
- DB_HOST=mysql
mysql:
image: mysql:8.0
restart: always
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
3. Managing Environment Variables Safely
Never hardcode sensitive database passwords or API keys inside your Docker configuration files. Always inject them using an .env file or through your cloud hosting provider secrets manager during deployment.
Final Thoughts
Moving your Laravel applications into Docker containers eliminates environment inconsistencies and streamlines your deployment workflow. Once your containers are running smoothly behind a reverse proxy, scaling and maintaining your infrastructure becomes significantly easier.