"Works on my machine" adalah meme developer yang sudah terlalu familiar. Setiap developer baru di tim butuh beberapa jam (atau hari) untuk menyesuaikan environment-nya. Docker menyelesaikan masalah ini dengan mengemas seluruh environment aplikasi ke dalam container yang bisa berjalan identik di mana saja — MacOS, Windows, Linux, maupun server production.
Mengapa Docker untuk Development Laravel?
Sebelum Docker, setup environment Laravel memerlukan instalasi manual PHP (versi spesifik), ekstensi PHP yang dibutuhkan, web server (Nginx/Apache), MySQL, Redis, dan sebagainya. Di mesin berbeda, versi berbeda menyebabkan perilaku berbeda. Docker memberikan:
- Konsistensi — Semua developer dan server production menggunakan image yang sama
- Isolasi — Proyek berbeda bisa menggunakan PHP versi berbeda tanpa konflik
- Reproductibility — Setup environment baru cukup satu perintah:
docker compose up - Port-ability — Pindah dari satu mesin ke mesin lain tanpa setup ulang
Struktur Docker untuk Laravel
Kita akan membuat setup dengan 4 service: PHP-FPM (aplikasi), Nginx (web server), MySQL (database), dan Redis (cache/queue).
project/
├── docker/
│ ├── nginx/
│ │ └── default.conf
│ └── php/
│ └── Dockerfile
├── docker-compose.yml
└── ... (file Laravel)
docker-compose.yml
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
volumes:
- .:/var/www/html
- ./storage:/var/www/html/storage
depends_on:
- mysql
- redis
environment:
- APP_ENV=local
networks:
- laravel
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- .:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- laravel
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- laravel
redis:
image: redis:alpine
ports:
- "6379:6379"
networks:
- laravel
volumes:
mysql_data:
networks:
laravel:
driver: bridge
Dockerfile untuk PHP
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
git curl libpng-dev libonig-dev \
libxml2-dev zip unzip \
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd \
&& pecl install redis \
&& docker-php-ext-enable redis \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY . .
RUN composer install --no-interaction --prefer-dist --optimize-autoloader
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
EXPOSE 9000
CMD ["php-fpm"]
Konfigurasi Nginx
server {
listen 80;
server_name localhost;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Workflow Development Sehari-hari
# Mulai semua service
docker compose up -d
# Jalankan artisan command
docker compose exec app php artisan migrate
# Masuk ke shell container
docker compose exec app bash
# Lihat log real-time
docker compose logs -f app
# Stop semua service
docker compose down
Tips Optimasi untuk Development
Volume Mounting Performance — Di macOS, bind mounts bisa lambat. Gunakan delegated flag atau pertimbangkan Mutagen untuk sinkronisasi yang lebih cepat.
Xdebug — Tambahkan profil khusus development dengan Xdebug enabled:
app-debug:
extends:
service: app
environment:
XDEBUG_MODE: develop,debug
XDEBUG_CONFIG: client_host=host.docker.internal
Multi-stage Build untuk Production — Gunakan multi-stage Dockerfile untuk memisahkan build dependencies dari runtime image, menghasilkan image yang lebih kecil dan aman untuk production.
Setelah Docker setup selesai, onboarding developer baru cukup: clone repo, copy .env.example ke .env, jalankan docker compose up -d, lalu docker compose exec app php artisan migrate --seed. Selesai dalam 5 menit.