📦 Pendahuluan
Artikel ini merapikan draft kamu dan melengkapinya dengan langkah-langkah praktis, file konfigurasi yang rapi, dan semua perintah yang perlu dijalankan — dari membuat image sampai menjalankan migrasi. Fokus: Laravel 11 + PHP 8.3 (Apache), database MySQL/MariaDB (bisa di container atau external), dan Docker Compose.
1. Struktur project (saran)
my-laravel-project/ ├─ docker/ │ ├─ apache/ │ │ └─ vhost.conf │ └─ Dockerfile ├─ .dockerignore ├─ docker-compose.yml ├─ .env └─ (folder laravel biasa: app, bootstrap, config, public, routes, storage, vendor, ...)
2. Dockerfile (PHP 8.3 + Apache, optimized untuk development)
Simpan di docker/Dockerfile atau dockerfile sesuai compose.
-- dockerfile
# docker/Dockerfile
FROM php:8.3-apache
# System deps & php extensions
RUN apt-get update && apt-get install -y \
git zip unzip curl libpng-dev libjpeg-dev libonig-dev libxml2-dev libzip-dev \
libpq-dev libicu-dev g++ nano wget ca-certificates && \
docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip intl
# Enable Apache rewrite
RUN a2enmod rewrite
# Set working dir
WORKDIR /var/www/html
# Copy vhost if ada
COPY docker/apache/vhost.conf /etc/apache2/sites-available/000-default.conf
# Copy composer binary from official composer image
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Copy project files (for build). In dev kita mount volume, tapi keep for build
COPY . .
# Install composer deps (production-ish). For dev you may skip --no-dev
RUN composer install --no-interaction --prefer-dist --optimize-autoloader
# Permissions (sesuaikan dengan environment)
RUN chown -R www-data:www-data /var/www/html && chmod -R 755 /var/www/html
EXPOSE 80
CMD ["apache2-foreground"]Catatan: Untuk development kita biasanya mount source sebagai volume sehingga perubahan langsung terlihat. composer install di Dockerfile berguna untuk image build/pipeline.
3. Contoh docker/apache/vhost.conf
Sederhana agar public/ Laravel jadi DocumentRoot.
-- apacheconf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/public
<Directory /var/www/html/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>4. docker-compose.yml (dua opsi)
- Opsi A — Database di dalam Compose (local dev)
-- yaml
version: "3.8"
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: laravel_app
ports:
- "8080:80" # akses http://localhost:8080
volumes:
- ./:/var/www/html
environment:
APP_ENV: local
APP_DEBUG: 'true'
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: laravel
DB_USERNAME: laravel
DB_PASSWORD: secret
depends_on:
- db
db:
image: mariadb:10.11 # atau mysql:8.0
container_name: mariadb_db
restart: unless-stopped
ports:
- "3307:3306" # dipetakan ke host 3307 agar tidak konflik
environment:
MYSQL_ROOT_PASSWORD: root_secret
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
volumes:
- db_data:/var/lib/mysqlvolumes:
db_data:
- Opsi B — Gunakan database eksternal (misal: Synology / NAS / host lain)
Jika DB sudah berjalan di luar Docker Compose, hapus/disable service db dan atur DB_HOST ke IP/DNS host tersebut.
-- yaml
version: "3.8"
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: laravel_app
ports:
- "8080:80"
volumes:
- ./:/var/www/html
environment:
APP_ENV: local
APP_DEBUG: 'true'
DB_HOST: "192.168.1.123" # ganti dengan IP/DNS Synology
DB_PORT: 3306
DB_DATABASE: laravel_db
DB_USERNAME: db_user
DB_PASSWORD: db_passwordImportant: Pastikan firewall / port forwarding pada NAS mengizinkan koneksi dari Docker host ke database (port default 3306).
5. .env Laravel — minimal bagian database
Tempat file .env di root project Laravel (jangan commit ke repo).
-- .env
APP_NAME=Laravel APP_ENV=local APP_KEY= # akan di-generate APP_DEBUG=true APP_URL=http://localhost:8080 DB_CONNECTION=mysql DB_HOST=db # atau IP eksternal bila Opsi B DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=laravel DB_PASSWORD=secret
6. .dockerignore (jangan masukkan sensitif / vendor besar)
-- .dockerignore
vendor node_modules npm-debug.log .DS_Store .env .git storage/*.key
7. Perintah build & run (praktis)
Letakkan di terminal pada folder project.
- Lihat container jalan?
-- bash
docker compose up -d --build
- Lihat container jalan?
-- bash
docker compose ps # atau docker ps
- Cek logs bila ada error:
-- bash
docker compose logs -f app # atau untuk db docker compose logs -f db
- Masuk ke container app (bash):
-- bash
docker compose exec app bash # atau docker exec -it laravel_app bash
- Di dalam container: generate APP_KEY, jalankan migrasi, install composer (jika perlu)
-- bash
# generate app key php artisan key:generate # jalankan migrasi php artisan migrate --force # jika composer belum ada/atau butuh install deps (container dev) composer install
Jika kamu tidak ingin masuk container, bisa jalankan command composer/artisan via docker compose exec app php artisan ... atau docker compose run --rm app composer install.
8. Cara menghubungkan ke database eksternal (Synology/NAS)
- Set DB_HOST ke IP lokal/NAT/DNS dari NAS.
- Pastikan port 3306 (atau port custom) terbuka dan menerima koneksi dari host Docker.
- Jika ada user/privileges: buat user di MariaDB dan beri hak ke DB yang akan digunakan.
- Test koneksi dari host sebelum container:
-- bash
mysql -h 192.168.1.123 -P 3306 -u db_user -p
9. Perintah penting summary (copy-paste)
-- bash
# build & run docker compose up -d --build # melihat container docker compose ps docker ps # logs docker compose logs -f app docker compose logs -f db # masuk container docker compose exec app bash # jalankan artisan/composer dari host ke container docker compose exec app php artisan migrate --force docker compose exec app composer install # stop/remove docker compose down docker compose down --volumes --remove-orphans # remove image jika mau rebuild bersih docker image rm <image-id or name>
10. Permission & storage (sering jadi masalah)
Jika Laravel error terkait permission (writing/storage/cache), jalankan:
-- bash
# dari host (jika mount volume) sudo chown -R $(id -u):$(id -g) storage bootstrap/cache chmod -R 775 storage bootstrap/cache # atau di dalam container docker compose exec app bash chown -R www-data:www-data storage bootstrap/cache chmod -R 775 storage bootstrap/cache
11. Tips debugging umum
- 502 / blank page: cek php error log, docker compose logs.
- 500: cek storage/logs/laravel.log dan apache error.log.
- DB cannot connect: cek DB_HOST, firewall, dan telnet/ping.
- Cache/env issues: jalankan php artisan config:clear && php artisan cache:clear && php artisan migrate.
- Composer memory error: jalankan COMPOSER_MEMORY_LIMIT=-1 composer install.
- Jika service db tidak ready: gunakan depends_on hanya menunggu start container, bukan service ready. Gunakan script wait-for-db atau artisan command retry pada migrasi.
Contoh quick-wait script (simple) saat menjalankan migrasi:
-- bash
# contoh inside container until nc -z -v -w30 "$DB_HOST" "$DB_PORT"; do echo "Waiting for database..." sleep 3 done php artisan migrate --force
12. Cadangan & best practice
- Jangan commit .env dan file sensitif ke repo.
- Gunakan .dockerignore.
- Untuk production: build image tanpa mount code, gunakan multi-stage builds, non-root user, dan gunakan orchestration (k8s / docker swarm / cloud).
- Pada production, jangan expose DB ke internet tanpa VPN/firewall.
13. Contoh alur cepat (step-by-step eksekusi)
- Siapkan file Dockerfile, docker-compose.yml, vhost.conf, .env.
- Tambahkan .dockerignore.
- Jalankan:
-- bash
docker compose up -d --build
- Lihat container jalan:
-- bash
docker compose ps
- Generate key & migrasi:
-- bash
docker compose exec app php artisan key:generate docker compose exec app php artisan migrate --force
- Buka browser: http://localhost:8080 (atau port yang kamu mapping)
14. Troubleshooting singkat (FAQ)
Q: ERROR 1045 (28000): Access denied
A: Pastikan user/password benar dan user di DB memiliki izin untuk host yang dipakai (% atau IP container).
Q: Permission denied pada storage
A: Set ownership ke www-data dan chmod 775.
Q: composer install butuh memory
A: COMPOSER_MEMORY_LIMIT=-1 composer install.
✅ Kesimpulan singkat
Dengan Docker + Docker Compose kamu dapat membuat environment Laravel yang konsisten dan portable. Kunci sukses:
- Struktur file yang rapi (Dockerfile, vhost, compose).
- .env yang benar (DB_HOST sesuai konteks).
- Volume mount saat development.
- Gunakan docker compose exec untuk menjalankan artisan/composer.
- Pastikan permission storage & bootstrap/cache.
Kalau mau, saya bisa:
- Sediakan versi docker-compose yang ready untuk production (NGINX + PHP-FPM + supervisor + redis)
- Bantu debugging jika kamu kirimkan log error spesifik.