Files
speech2text/DEPLOYMENT.md
2026-06-02 17:35:45 +08:00

7.1 KiB

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

# 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

sudo mkdir -p /svr/speech2text
sudo chown $USER:$USER /svr/speech2text
cd /svr/speech2text
git clone <repo-url> .

3. Konfigurasi Environment

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

cd /svr/speech2text
docker compose up -d --build

5. Setup Laravel

# 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

# 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)

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)

# 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:

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

# 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

# Backup fail audio (private storage)
tar -czf audio_backup_$(date +%Y%m%d).tar.gz \
    /svr/speech2text/app/storage/app/private/

Automated Backup (crontab)

# 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

# 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

docker compose logs <service-name>
docker compose config  # semak syntax docker-compose.yml

Transcription gagal

# 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

docker compose exec app chmod -R 775 storage bootstrap/cache
docker compose exec app chown -R www-data:www-data storage

Database migration error

# 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