🐳 Basic Docker Workflow Using PHP + MySQL + Laravel

Docker has become a standard tool for local development: it isolates environments, makes projects reproducible, and eliminates the classic “works on my machine” problem. In this post, I’ll walk you through a basic Docker workflow using a simple PHP + MySQL + Laravel stack.


🎯 What We Want to Achieve

  • A PHP container (e.g., PHP 8.2) to run Laravel
  • A MySQL container
  • An optional but recommended Nginx container
  • A single
    docker-compose.yml

    to orchestrate everything

  • A minimal set of commands for daily development

📦 Project Structure

A typical structure looks like this:

project/
 ├─ src/              # Laravel project
 ├─ docker/
 │   ├─ php/
 │   │   └─ Dockerfile
 │   └─ nginx/
 │       └─ default.conf
 └─ docker-compose.yml

⚙️ PHP Dockerfile

docker/php/Dockerfile

:

FROM php:8.2-fpm

RUN apt-get update && apt-get install -y \
git zip unzip curl libpq-dev libzip-dev \
&& docker-php-ext-install pdo pdo_mysql zip

COPY –from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

This gives you a minimal PHP-FPM image with Composer and required extensions.


🗄️ MySQL Configuration

Inside

docker-compose.yml

:

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql

🌐 Nginx Configuration

docker/nginx/default.conf

:

server {
listen 80;
root /var/www/html/public;

index index.php index.html;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}


🧩 docker-compose.yml

version: '3.8'

services:
  php:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    container_name: php
    volumes:
      - ./src:/var/www/html
    depends_on:
      - mysql

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

🚀 Starting the Project

1. Create a Laravel project

docker compose run --rm php composer create-project laravel/laravel .

2. Start all containers

docker compose up -d

3. Check in the browser

http://localhost:8080

🔄 Basic Daily Workflow

1. Install dependencies

docker compose exec php composer install

2. Run migrations

docker compose exec php php artisan migrate

3. Run Artisan commands

docker compose exec php php artisan tinker

4. View logs

docker compose logs -f php
docker compose logs -f nginx
docker compose logs -f mysql

5. Restart a service

docker compose restart php

🧹 Useful Tips

  • Don’t install PHP, MySQL, or Nginx locally — Docker replaces all of them.
  • Keep configs in separate files (
    docker/php/Dockerfile

    ,

    docker/nginx/default.conf

    ) for easier maintenance.

  • Use a volume for MySQL to avoid losing data.
  • Run Composer inside the container, not on your host machine.

🎉 Conclusion

This basic stack is a great starting point for any PHP/Laravel project. It’s simple, transparent, and easy to extend: Redis, Horizon, Queue Workers, Mailhog — all of these can be added with just a few lines in

docker-compose.yml

.

Leave a Reply

Your email address will not be published. Required fields are marked *