A beginner-friendly Docker setup for Laravel. Learn how to containerize your Laravel application with PHP, Nginx, MySQL, and Redis.
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
| Service | Description | Port |
|---|---|---|
| PHP 8.4 | Runs your Laravel code | 9000 |
| Nginx | Web server | 8080 |
| MySQL 8.0 | Database | 3306 |
| Redis | Cache & Queues | 6379 |
- Install Docker Desktop
- Make sure Docker is running (whale icon in menu bar)
# 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├── 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
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 PHPDefines how services work together:
services:
app: # PHP-FPM (your Laravel code)
nginx: # Web server (handles HTTP)
mysql: # Database
redis: # CacheKey settings for Docker:
DB_HOST=mysql # Use service name, not localhost
REDIS_HOST=redis # Use service name, not localhostWhy service names? Docker creates an internal network where containers find each other by name.
| 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 |
| 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 |
| 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 |
Via Terminal:
make mysql
# or
docker-compose exec mysql mysql -u laravel -psecret laravelVia GUI (TablePlus, DBeaver, etc.):
| Setting | Value |
|---|---|
| Host | 127.0.0.1 |
| Port | 3306 |
| User | laravel |
| Password | secret |
| Database | laravel |
| 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 |
Browser Request (localhost:8080)
↓
[ Nginx ] ←── Serves static files (CSS, JS, images)
↓
[ PHP-FPM ] ←── Runs Laravel code
↓
[ MySQL ] ←── Stores data
[ Redis ] ←── Caches data
- Nginx receives HTTP requests on port 8080
- Static files are served directly
- PHP requests go to PHP-FPM on port 9000
- Laravel connects to MySQL and Redis using service names
A Makefile is a simple way to create shortcuts for long commands.
Structure:
command-name:
actual command to runExample:
up:
docker-compose up -d
down:
docker-compose downUsage:
make up # runs: docker-compose up -d
make down # runs: docker-compose downWith arguments:
artisan:
docker-compose exec app php artisan $(cmd)make artisan cmd="migrate"
# runs: docker-compose exec app php artisan migrateView all commands:
make helpZeyad Rezk - GitHub
MIT License - feel free to use this for your projects!