first
This commit is contained in:
318
DEPLOYMENT.md
Normal file
318
DEPLOYMENT.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# DEPLOYMENT.md — Speech2Text MBIP
|
||||
|
||||
## Keperluan Server
|
||||
|
||||
| Komponen | Minimum | Disyorkan |
|
||||
|---|---|---|
|
||||
| OS | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
|
||||
| CPU | 4 core | 8 core |
|
||||
| RAM | 8 GB | 16 GB |
|
||||
| Storage | 100 GB | 500 GB+ (untuk audio files) |
|
||||
| Docker | 24.x | Latest stable |
|
||||
| Docker Compose | 2.x | Latest stable |
|
||||
|
||||
**Nota:** RAM tambahan diperlukan jika menggunakan Whisper model yang lebih besar (medium/large).
|
||||
|
||||
---
|
||||
|
||||
## Struktur Direktori Server
|
||||
|
||||
```
|
||||
/svr/speech2text/
|
||||
├── .env # environment variables (JANGAN commit ke git)
|
||||
├── .env.example # template (commit ke git)
|
||||
├── docker-compose.yml # development / staging
|
||||
├── docker-compose.prod.yml # production override
|
||||
├── Dockerfile # Laravel app image
|
||||
├── docker/
|
||||
│ ├── nginx/
|
||||
│ │ └── default.conf
|
||||
│ ├── php/
|
||||
│ │ └── php.ini
|
||||
│ ├── supervisor/
|
||||
│ │ └── supervisord.conf
|
||||
│ └── transcription-worker/
|
||||
│ └── Dockerfile
|
||||
├── app/ # Laravel source code
|
||||
│ ├── storage/
|
||||
│ │ └── app/
|
||||
│ │ └── private/ # fail audio (tidak accessible web)
|
||||
│ └── ...
|
||||
└── mysql-data/ # MySQL data volume (auto-created)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Langkah Deployment Pertama Kali
|
||||
|
||||
### 1. Persediaan Server
|
||||
|
||||
```bash
|
||||
# Update server
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
|
||||
# Verify
|
||||
docker --version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
### 2. Clone Repository
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /svr/speech2text
|
||||
sudo chown $USER:$USER /svr/speech2text
|
||||
cd /svr/speech2text
|
||||
git clone <repo-url> .
|
||||
```
|
||||
|
||||
### 3. Konfigurasi Environment
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
nano .env # atau gunakan editor pilihan anda
|
||||
```
|
||||
|
||||
Nilai wajib diisi dalam `.env`:
|
||||
|
||||
```
|
||||
APP_KEY= # akan dijanakan kemudian
|
||||
DB_PASSWORD=<password-kuat>
|
||||
ADMIN_DEFAULT_NAME=<nama-admin>
|
||||
ADMIN_DEFAULT_EMAIL=<email-admin>
|
||||
ADMIN_DEFAULT_PASSWORD=<password-admin-kuat>
|
||||
```
|
||||
|
||||
### 4. Build dan Jalankan Container
|
||||
|
||||
```bash
|
||||
cd /svr/speech2text
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
### 5. Setup Laravel
|
||||
|
||||
```bash
|
||||
# Jana APP_KEY
|
||||
docker compose exec app php artisan key:generate
|
||||
|
||||
# Jalankan migration dan seeder
|
||||
docker compose exec app php artisan migrate --seed
|
||||
|
||||
# Set permission storage
|
||||
docker compose exec app chmod -R 775 storage bootstrap/cache
|
||||
docker compose exec app chown -R www-data:www-data storage bootstrap/cache
|
||||
```
|
||||
|
||||
### 6. Verify Services
|
||||
|
||||
```bash
|
||||
# Semak semua container berjalan
|
||||
docker compose ps
|
||||
|
||||
# Semak logs
|
||||
docker compose logs -f app
|
||||
docker compose logs -f queue-worker
|
||||
docker compose logs -f transcription-worker
|
||||
|
||||
# Semak queue worker
|
||||
docker compose exec app php artisan queue:monitor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Update (Selepas Push Kod Baru)
|
||||
|
||||
```bash
|
||||
cd /svr/speech2text
|
||||
|
||||
# Pull kod terbaru
|
||||
git pull origin main
|
||||
|
||||
# Rebuild container jika ada perubahan Dockerfile
|
||||
docker compose up -d --build app
|
||||
|
||||
# Atau restart tanpa rebuild jika hanya kod PHP berubah
|
||||
docker compose restart app queue-worker scheduler
|
||||
|
||||
# Jalankan migration baru (jika ada)
|
||||
docker compose exec app php artisan migrate --force
|
||||
|
||||
# Clear cache
|
||||
docker compose exec app php artisan config:cache
|
||||
docker compose exec app php artisan route:cache
|
||||
docker compose exec app php artisan view:cache
|
||||
|
||||
# Restart queue worker untuk ambil kod baru
|
||||
docker compose restart queue-worker
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Production Override (`docker-compose.prod.yml`)
|
||||
|
||||
```bash
|
||||
# Jalankan dengan production config
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Konfigurasi Nginx (Luar Docker — jika ada reverse proxy)
|
||||
|
||||
Jika server ada Nginx luar Docker sebagai reverse proxy:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name speech2text.mbip.my;
|
||||
|
||||
ssl_certificate /etc/ssl/certs/mbip.crt;
|
||||
ssl_certificate_key /etc/ssl/private/mbip.key;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080; # port Docker nginx
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 300s;
|
||||
client_max_body_size 210M; # PRIVATE_AUDIO_MAX_MB + buffer
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name speech2text.mbip.my;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Backup
|
||||
|
||||
### Database Backup
|
||||
|
||||
```bash
|
||||
# Backup manual
|
||||
docker compose exec mysql mysqldump \
|
||||
-u root -p$DB_PASSWORD \
|
||||
speech2text > backup_$(date +%Y%m%d_%H%M%S).sql
|
||||
|
||||
# Compress
|
||||
gzip backup_*.sql
|
||||
```
|
||||
|
||||
### Storage Backup
|
||||
|
||||
```bash
|
||||
# Backup fail audio (private storage)
|
||||
tar -czf audio_backup_$(date +%Y%m%d).tar.gz \
|
||||
/svr/speech2text/app/storage/app/private/
|
||||
```
|
||||
|
||||
### Automated Backup (crontab)
|
||||
|
||||
```bash
|
||||
# Edit crontab
|
||||
crontab -e
|
||||
|
||||
# Tambah:
|
||||
0 2 * * * cd /svr/speech2text && docker compose exec -T mysql \
|
||||
mysqldump -u root -p$DB_PASSWORD speech2text | \
|
||||
gzip > /backup/db/speech2text_$(date +\%Y\%m\%d).sql.gz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring
|
||||
|
||||
```bash
|
||||
# Semak status container
|
||||
docker compose ps
|
||||
|
||||
# Lihat penggunaan resource
|
||||
docker stats
|
||||
|
||||
# Lihat logs real-time
|
||||
docker compose logs -f
|
||||
|
||||
# Logs spesifik service
|
||||
docker compose logs -f queue-worker
|
||||
docker compose logs -f transcription-worker
|
||||
|
||||
# Semak queue jobs pending
|
||||
docker compose exec app php artisan queue:monitor
|
||||
|
||||
# Semak failed jobs
|
||||
docker compose exec app php artisan queue:failed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container tidak start
|
||||
|
||||
```bash
|
||||
docker compose logs <service-name>
|
||||
docker compose config # semak syntax docker-compose.yml
|
||||
```
|
||||
|
||||
### Transcription gagal
|
||||
|
||||
```bash
|
||||
# Semak transcription worker
|
||||
docker compose logs transcription-worker
|
||||
|
||||
# Test transcription worker secara manual
|
||||
docker compose exec app curl http://transcription-worker:8000/health
|
||||
|
||||
# Retry failed jobs
|
||||
docker compose exec app php artisan queue:retry all
|
||||
```
|
||||
|
||||
### Storage permission error
|
||||
|
||||
```bash
|
||||
docker compose exec app chmod -R 775 storage bootstrap/cache
|
||||
docker compose exec app chown -R www-data:www-data storage
|
||||
```
|
||||
|
||||
### Database migration error
|
||||
|
||||
```bash
|
||||
# Semak status migration
|
||||
docker compose exec app php artisan migrate:status
|
||||
|
||||
# Rollback jika perlu
|
||||
docker compose exec app php artisan migrate:rollback
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist Pre-Production
|
||||
|
||||
- [ ] `APP_ENV=production`
|
||||
- [ ] `APP_DEBUG=false`
|
||||
- [ ] `APP_KEY` telah dijanakan dan disimpan dengan selamat
|
||||
- [ ] Database password kuat (minimum 16 karakter, alphanumeric + simbol)
|
||||
- [ ] HTTPS/TLS dikonfig
|
||||
- [ ] Firewall: hanya port 80/443 terbuka dari internet
|
||||
- [ ] Port 3306 (MySQL), 6379 (Redis), 8000 (transcription-worker) TIDAK terbuka dari internet
|
||||
- [ ] `.env` dalam `.gitignore`
|
||||
- [ ] `storage/app/private/` tidak accessible dari web
|
||||
- [ ] Backup berjalan secara automatik
|
||||
- [ ] Log rotation dikonfig
|
||||
- [ ] Admin default password ditukar selepas login pertama
|
||||
- [ ] Rate limiting aktif
|
||||
- [ ] Queue worker berjalan
|
||||
- [ ] Scheduler berjalan
|
||||
- [ ] Test upload audio berjaya
|
||||
- [ ] Test transcription berjaya
|
||||
- [ ] Test authorization (admin tidak dapat akses kandungan) lulus
|
||||
Reference in New Issue
Block a user