Skip to content

zeyadrezk/laravel-docker-starter

Repository files navigation

Laravel Docker Starter Kit

A beginner-friendly Docker setup for Laravel. Learn how to containerize your Laravel application with PHP, Nginx, MySQL, and Redis.

What is Docker?

Docker lets you package your application with all its dependencies into containers - lightweight, isolated environments that run the same way everywhere.

Why use Docker?

  • No need to install PHP, MySQL, Nginx locally
  • Same environment for all team members
  • Easy to share and deploy
  • Works on Windows, Mac, and Linux

What's Included

Service Description Port
PHP 8.4 Runs your Laravel code 9000
Nginx Web server 8080
MySQL 8.0 Database 3306
Redis Cache & Queues 6379

Prerequisites

  1. Install Docker Desktop
  2. Make sure Docker is running (whale icon in menu bar)

Quick Start

# Clone this repo
git clone https://github.com/zeyadrezk/laravel-docker-starter.git
cd laravel-docker-starter

# Copy environment file
cp .env.example .env

# Run setup (builds everything)
make setup

# Open in browser
open http://localhost:8080

Project Structure

├── Dockerfile              # PHP image configuration
├── docker-compose.yml      # Defines all services
├── .dockerignore           # Files excluded from build
├── .env.example            # Environment template
├── Makefile                # Shortcut commands
└── docker/
    └── nginx/
        └── nginx.conf      # Web server config

Understanding the Files

1. Dockerfile

Builds your PHP environment. Think of it as a recipe:

FROM php:8.4-fpm              # Start with PHP 8.4
RUN apt-get install ...        # Install system packages
RUN docker-php-ext-install ... # Install PHP extensions
COPY . .                       # Copy your code
CMD ["php-fpm"]                # Run PHP

2. docker-compose.yml

Defines how services work together:

services:
  app:      # PHP-FPM (your Laravel code)
  nginx:    # Web server (handles HTTP)
  mysql:    # Database
  redis:    # Cache

3. .env (Environment Variables)

Key settings for Docker:

DB_HOST=mysql      # Use service name, not localhost
REDIS_HOST=redis   # Use service name, not localhost

Why service names? Docker creates an internal network where containers find each other by name.

Commands Reference

Action Make (Short) Docker (Full)
First time setup make setup Build + install + migrate
Start containers make up docker-compose up -d
Stop containers make down docker-compose down
Rebuild containers make build docker-compose up -d --build
View logs make logs docker-compose logs -f
List containers make ps docker-compose ps
Enter PHP shell make shell docker-compose exec app bash
Enter MySQL shell make mysql docker-compose exec mysql mysql -u laravel -psecret laravel
Enter Redis CLI make redis docker-compose exec redis redis-cli
Run tests make test docker-compose exec app php artisan test
Fresh migrate make fresh docker-compose exec app php artisan migrate:fresh --seed
Clear cache make clear docker-compose exec app php artisan cache:clear

Artisan Commands

Action Make (Short) Docker (Full)
Run migrate make artisan cmd="migrate" docker-compose exec app php artisan migrate
Create model make artisan cmd="make:model Post -mc" docker-compose exec app php artisan make:model Post -mc
Create controller make artisan cmd="make:controller UserController" docker-compose exec app php artisan make:controller UserController
Run tinker make artisan cmd="tinker" docker-compose exec app php artisan tinker
Clear config make artisan cmd="config:clear" docker-compose exec app php artisan config:clear
Route list make artisan cmd="route:list" docker-compose exec app php artisan route:list

Composer Commands

Action Make (Short) Docker (Full)
Install packages make install docker-compose exec app composer install
Require package make composer cmd="require laravel/sanctum" docker-compose exec app composer require laravel/sanctum
Update packages make composer cmd="update" docker-compose exec app composer update
Dump autoload make composer cmd="dump-autoload" docker-compose exec app composer dump-autoload

Database Access

Via Terminal:

make mysql
# or
docker-compose exec mysql mysql -u laravel -psecret laravel

Via GUI (TablePlus, DBeaver, etc.):

Setting Value
Host 127.0.0.1
Port 3306
User laravel
Password secret
Database laravel

Troubleshooting

Problem Solution (Make) Solution (Docker)
Container won't start make down && make build docker-compose down && docker-compose up -d --build
Permission errors make shell then chmod -R 775 storage docker-compose exec app chmod -R 775 storage bootstrap/cache
Database connection refused Wait 10s, then make artisan cmd="migrate" docker-compose exec app php artisan migrate
Clear everything make down then delete volumes docker-compose down -v && docker-compose up -d --build

How It Works

Browser Request (localhost:8080)
        ↓
    [ Nginx ]  ←── Serves static files (CSS, JS, images)
        ↓
    [ PHP-FPM ]  ←── Runs Laravel code
        ↓
    [ MySQL ]  ←── Stores data
    [ Redis ]  ←── Caches data
  1. Nginx receives HTTP requests on port 8080
  2. Static files are served directly
  3. PHP requests go to PHP-FPM on port 9000
  4. Laravel connects to MySQL and Redis using service names

How Makefile Works

A Makefile is a simple way to create shortcuts for long commands.

Structure:

command-name:
	actual command to run

Example:

up:
	docker-compose up -d

down:
	docker-compose down

Usage:

make up    # runs: docker-compose up -d
make down  # runs: docker-compose down

With arguments:

artisan:
	docker-compose exec app php artisan $(cmd)
make artisan cmd="migrate"
# runs: docker-compose exec app php artisan migrate

View all commands:

make help

Learn More

Author

Zeyad Rezk - GitHub

License

MIT License - feel free to use this for your projects!

Releases

No releases published

Packages

 
 
 

Contributors