Files
cabutan-bertuah-koipb/DEPLOYMENT.md
2026-06-24 18:30:00 +08:00

179 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DEPLOYMENT.md — Sistem MAT KOIPB (Docker · Ubuntu Server)
Panduan deploy aplikasi **Kehadiran & Cabutan Bertuah MAT KOIPB** menggunakan Docker pada server Ubuntu. Stack: **Nginx + PHP 8.4-FPM (Laravel) + MySQL 8** — semua dalam container, tiada pemasangan PHP/MySQL pada host.
> UI guna CDN + CSS statik (`public/css/koipb.css`) — **tiada langkah build Node/Vite**.
---
## Keperluan Server
| Komponen | Minimum | Disyorkan |
|---|---|---|
| OS | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
| CPU | 2 core | 4 core |
| RAM | 2 GB | 4 GB |
| Storage | 10 GB | 20 GB |
| Docker | 24.x | Latest stable |
| Docker Compose | 2.x | Latest stable |
Untuk 150200 peserta, server kecil sudah memadai.
---
## Struktur Fail Docker
```
/srv/koipb/
├── .env # disalin dari .env.docker.example (JANGAN commit)
├── .env.docker.example # templat
├── Dockerfile # imej PHP-FPM (Laravel)
├── docker-compose.yml # dev (nginx + app + mysql)
├── docker-compose.prod.yml # override production
├── docker/
│ ├── entrypoint.sh # wait-db, composer, key:generate, migrate, seed, cache
│ ├── nginx/default.conf
│ └── php/{php.ini, php-dev.ini, php-prod.ini}
└── ... (kod Laravel)
```
---
## Langkah Deployment Pertama Kali
### 1. Persediaan server
```bash
sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
docker --version && docker compose version
```
### 2. Dapatkan kod
```bash
sudo mkdir -p /srv/koipb && sudo chown $USER:$USER /srv/koipb
cd /srv/koipb
git clone <repo-url> .
```
### 3. Konfigurasi environment
```bash
cp .env.docker.example .env
nano .env
```
Wajib tukar:
| Pemboleh ubah | Nota |
|---|---|
| `APP_KEY` | Biar kosong — entrypoint jana automatik kali pertama |
| `APP_URL` | cth `https://mat.koipb.gov.my` |
| `APP_PORT` | `80` (atau di belakang reverse proxy) |
| `DB_PASSWORD` | password user `koipb` |
| `DB_ROOT_PASSWORD` | password root MySQL container |
| `SEED_DEMO` | `true` = isi 200 anggota + 21 hadiah contoh; `false` = data kosong (import sendiri) |
> `DB_HOST` mesti kekal `mysql` (nama service container).
### 4. Logo
```bash
# Letak logo sebenar (kalau belum):
cp /path/ke/logo.jpg public/images/logo-koipb.jpg
```
### 5. Bina & jalankan (production)
```bash
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
```
Entrypoint akan automatik: tunggu MySQL → composer install → `key:generate``migrate --force` → seed peranan/pengguna (+ demo jika `SEED_DEMO=true`) → cache config/route/view.
Semak:
```bash
docker compose ps
docker compose logs -f app # tunggu "✅ Aplikasi bersedia."
```
Buka `http://<IP-server>` (atau `APP_URL`).
---
## Login Default
Kata laluan semua: **`password`** — **WAJIB tukar selepas log masuk pertama** (atau ubah dalam `RoleUserSeeder` sebelum deploy).
| Peranan | E-mel |
|---|---|
| Admin | `admin@koipb.test` |
| Petugas Kaunter | `kaunter@koipb.test` |
| Petugas Cabutan | `cabutan@koipb.test` |
---
## Operasi Harian
```bash
# Status / log
docker compose ps
docker compose logs -f app
# Masuk shell artisan
docker compose exec app php artisan <command>
# Backup database (penting sebelum & selepas event!)
docker compose exec mysql sh -c 'mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" koipb_mat' > backup-$(date +%F-%H%M).sql
# Restore
cat backup.sql | docker compose exec -T mysql sh -c 'mysql -u root -p"$MYSQL_ROOT_PASSWORD" koipb_mat'
# Henti / mula semula
docker compose -f docker-compose.yml -f docker-compose.prod.yml down
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
> Data MySQL kekal dalam named volume **`koipb_db_data`** walaupun container dipadam. `docker compose down` (tanpa `-v`) **tidak** memadam data. **Jangan** guna `down -v` semasa event.
---
## Kemaskini Versi (Redeploy)
```bash
cd /srv/koipb
git pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
# Entrypoint akan migrate + cache semula automatik.
```
---
## Reverse Proxy + HTTPS (pilihan)
Jika ada Nginx/Caddy di host atau sijil SSL, set `APP_PORT` kepada port dalaman (cth `8080`) dan proksi ke port itu. Contoh blok Nginx host:
```nginx
server {
server_name mat.koipb.gov.my;
location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
}
```
Kemudian pasang sijil melalui `certbot --nginx`.
---
## Penyelesaian Masalah
| Masalah | Tindakan |
|---|---|
| `app` asyik restart | `docker compose logs app` — biasanya MySQL belum sedia atau `.env` salah |
| `419 Page Expired` / log masuk gagal | `APP_KEY` kosong — `docker compose exec app php artisan key:generate --force` lalu `docker compose restart app` |
| 502 Bad Gateway | container `app` belum naik / belum siap `composer install`; tunggu log "Aplikasi bersedia" |
| Tukar `.env` tak berkesan | `docker compose exec app php artisan config:clear` dan restart |
| Reset data untuk event baharu | Log masuk admin → **Tetapan & Reset**, atau `docker compose exec app php artisan migrate:fresh --seed --force` |