feat: Docker Compose setup untuk development & production

- docker/php/Dockerfile: PHP 8.4-FPM + GD + imagick (PECL) + semua extension Laravel
- docker/php/php.ini: upload 20MB, memory 512MB, opcache, Asia/Kuala_Lumpur
- docker/php/php-dev.ini: validate_timestamps=1, display_errors=On (dev)
- docker/nginx/default.conf: gzip, security headers, static asset caching
- docker/entrypoint.sh: tunggu MySQL → migrate → seed AdminSeeder → cache (prod)
- docker-compose.yml: dev stack — port 8003, DB host 33060, queue worker
- docker-compose.prod.yml: production overrides — storage volume, no DB port exposed
- .env.docker: template env untuk Docker (DB_HOST=db)
- .dockerignore: exclude node_modules, vendor, .env, logs

fix: testGenerate try/catch kembalikan JSON error (bukan HTML 500)
fix: loadPreview() semak r.ok, tunjuk error alert, loading spinner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Saufi
2026-05-18 15:36:47 +08:00
parent c9b50ccc5e
commit 576c71c960
11 changed files with 613 additions and 5 deletions

65
docker-compose.prod.yml Normal file
View File

@@ -0,0 +1,65 @@
###############################################################################
# eCert MBIP — Docker Compose Production Overrides (Ubuntu Server)
#
# Penggunaan:
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
#
# Perbezaan dari dev:
# • APP_ENV=production, APP_DEBUG=false
# • DB port TIDAK didedahkan ke host
# • Storage sijil/template disimpan dalam named volume (kekal semasa deploy)
# • Opcache validate_timestamps=0 (prestasi)
# • php-dev.ini tidak dimuat
###############################################################################
name: ecert
services:
# ── PHP-FPM Application (production) ──────────────────────────────────────
app:
container_name: ecert_app
restart: always
volumes:
# Kod dari server (git pull)
- .:/var/www
# php.ini sahaja (tanpa php-dev.ini)
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/99-ecert.ini:ro
# Storage kekal semasa redeploy
- storage_data:/var/www/storage
environment:
APP_ENV: production
APP_DEBUG: "false"
# ── Nginx (production) ─────────────────────────────────────────────────────
nginx:
container_name: ecert_nginx
restart: always
volumes:
- .:/var/www:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
# Mount storage supaya nginx boleh serve fail statik jika perlu
- storage_data:/var/www/storage:ro
# ── MySQL (production) ─────────────────────────────────────────────────────
db:
container_name: ecert_db
restart: always
ports: [] # Jangan dedahkan DB port ke luar dalam production
volumes:
- dbdata:/var/lib/mysql
# ── Queue Worker (production) ──────────────────────────────────────────────
queue:
container_name: ecert_queue
restart: always
volumes:
- .:/var/www
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/99-ecert.ini:ro
- storage_data:/var/www/storage
environment:
APP_ENV: production
###############################################################################
volumes:
storage_data:
driver: local