2025-12-17 10:48:59 +07:00
|
|
|
# Deployment Guide - Production
|
|
|
|
|
|
|
|
|
|
## ⚠️ PENTING: Vendor Folder
|
|
|
|
|
|
|
|
|
|
**Vendor folder TIDAK di-commit ke git repository!**
|
|
|
|
|
|
|
|
|
|
Setiap kali deploy atau pull code baru, **WAJIB** jalankan:
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
```bash
|
|
|
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🚀 Quick Deployment Steps
|
|
|
|
|
|
|
|
|
|
### 1. First Time Deployment
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# 1. Clone repository
|
|
|
|
|
cd /www/wwwroot/api.btekno.cloud
|
|
|
|
|
git clone https://git.btekno.cloud/kangmin/api-btekno.git api
|
|
|
|
|
|
|
|
|
|
# 2. Masuk ke folder project
|
|
|
|
|
cd api
|
|
|
|
|
|
|
|
|
|
# 3. WAJIB: Install dependencies
|
|
|
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
|
|
|
|
|
|
# 4. Setup environment
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
nano .env # Edit dengan konfigurasi production
|
|
|
|
|
|
2025-12-17 10:54:06 +07:00
|
|
|
# 5. Apply migrations (dari folder project root)
|
|
|
|
|
cd /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
mysql -u sql_retribusi -p sql_retribusi < ./migrations/001_create_audit_logs.sql
|
|
|
|
|
mysql -u sql_retribusi -p sql_retribusi < ./migrations/002_create_hourly_summary.sql
|
|
|
|
|
mysql -u sql_retribusi -p sql_retribusi < ./migrations/003_create_realtime_events.sql
|
|
|
|
|
|
|
|
|
|
# Atau menggunakan path absolut:
|
|
|
|
|
mysql -u sql_retribusi -p sql_retribusi < /www/wwwroot/api.btekno.cloud/api/migrations/001_create_audit_logs.sql
|
|
|
|
|
mysql -u sql_retribusi -p sql_retribusi < /www/wwwroot/api.btekno.cloud/api/migrations/002_create_hourly_summary.sql
|
|
|
|
|
mysql -u sql_retribusi -p sql_retribusi < /www/wwwroot/api.btekno.cloud/api/migrations/003_create_realtime_events.sql
|
2025-12-17 10:48:59 +07:00
|
|
|
|
|
|
|
|
# 6. Set permissions
|
|
|
|
|
chown -R www:www /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
chmod -R 755 /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2. Update Deployment (Setelah Pull Code)
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# 1. Pull latest code
|
|
|
|
|
cd /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
git pull origin main
|
|
|
|
|
|
|
|
|
|
# 2. WAJIB: Update dependencies (jika ada perubahan composer.json)
|
|
|
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
|
|
|
|
|
|
# 3. Regenerate autoloader
|
|
|
|
|
composer dump-autoload --optimize
|
|
|
|
|
|
2025-12-17 13:57:11 +07:00
|
|
|
# 4. Update .env dengan konfigurasi CORS (jika belum ada)
|
|
|
|
|
# Edit .env dan tambahkan:
|
|
|
|
|
# CORS_ALLOWED_ORIGINS=*
|
|
|
|
|
# CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
|
|
|
|
|
# CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-API-KEY,Accept,Origin
|
|
|
|
|
# CORS_ALLOW_CREDENTIALS=true
|
|
|
|
|
|
|
|
|
|
# 5. Restart PHP-FPM (opsional, untuk memastikan perubahan ter-load)
|
|
|
|
|
# Via aaPanel: Website -> PHP -> Service Management -> Reload
|
|
|
|
|
# Atau via command:
|
|
|
|
|
# systemctl reload php-fpm-83 # Sesuaikan dengan PHP version
|
|
|
|
|
|
|
|
|
|
# 6. Clear cache (jika ada)
|
2025-12-17 10:48:59 +07:00
|
|
|
# Tidak ada cache untuk project ini, skip
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 3. Setup aaPanel
|
|
|
|
|
|
|
|
|
|
1. **Create Website**:
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
- Domain: `api.btekno.cloud`
|
|
|
|
|
- DocumentRoot: `/www/wwwroot/api.btekno.cloud/api/public`
|
|
|
|
|
- PHP Version: 8.2 atau 8.3
|
|
|
|
|
|
|
|
|
|
2. **PHP Settings**:
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
- Enable `extension=pdo_mysql`
|
|
|
|
|
- Enable `extension=mbstring`
|
|
|
|
|
- Memory limit: 256M (minimum)
|
|
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
3. **Nginx Configuration** (PENTING untuk fix 404):
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
Masuk ke: **Website -> api.btekno.cloud -> Settings -> Configuration**
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
Ganti isi configuration dengan:
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
```nginx
|
|
|
|
|
server {
|
|
|
|
|
listen 80;
|
|
|
|
|
listen 443 ssl http2;
|
|
|
|
|
server_name api.btekno.cloud;
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Document Root - HARUS ke folder public/
|
|
|
|
|
root /www/wwwroot/api.btekno.cloud/api/public;
|
|
|
|
|
index index.php index.html;
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Logs
|
|
|
|
|
access_log /www/wwwlogs/api.btekno.cloud.log;
|
|
|
|
|
error_log /www/wwwlogs/api.btekno.cloud.error.log;
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Disable access to hidden files
|
|
|
|
|
location ~ /\. {
|
|
|
|
|
deny all;
|
|
|
|
|
access_log off;
|
|
|
|
|
log_not_found off;
|
|
|
|
|
}
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Main location block - routing untuk Slim Framework
|
|
|
|
|
location / {
|
|
|
|
|
try_files $uri $uri/ /index.php?$query_string;
|
|
|
|
|
}
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# PHP-FPM configuration
|
|
|
|
|
location ~ \.php$ {
|
|
|
|
|
try_files $uri =404;
|
|
|
|
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
|
|
|
|
fastcgi_pass unix:/tmp/php-cgi-83.sock; # Sesuaikan dengan PHP version (83, 82, dll)
|
|
|
|
|
fastcgi_index index.php;
|
|
|
|
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
|
|
|
include fastcgi_params;
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Disable buffering for SSE
|
|
|
|
|
fastcgi_buffering off;
|
|
|
|
|
}
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Disable PHP execution in uploads
|
|
|
|
|
location ~* /uploads/.*\.php$ {
|
|
|
|
|
deny all;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
**Cek PHP socket path:**
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
```bash
|
|
|
|
|
# Cek PHP version yang digunakan
|
|
|
|
|
php -v
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
# Cek socket path (biasanya di /tmp/php-cgi-XX.sock)
|
|
|
|
|
ls -la /tmp/php-cgi-*.sock
|
|
|
|
|
```
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
Setelah edit, klik **Save** dan **Reload** nginx.
|
2025-12-17 13:36:29 +07:00
|
|
|
|
2025-12-17 11:00:41 +07:00
|
|
|
**Atau copy file `nginx.conf.example` dan sesuaikan path PHP socket.**
|
2025-12-17 10:48:59 +07:00
|
|
|
|
|
|
|
|
## 🔧 Environment Configuration
|
|
|
|
|
|
|
|
|
|
Edit `.env` file:
|
|
|
|
|
|
|
|
|
|
```env
|
|
|
|
|
APP_ENV=production
|
|
|
|
|
APP_DEBUG=false
|
|
|
|
|
|
|
|
|
|
# Database
|
|
|
|
|
DB_HOST=localhost
|
|
|
|
|
DB_NAME=sql_retribusi
|
|
|
|
|
DB_USER=sql_retribusi
|
|
|
|
|
DB_PASS=your_secure_password
|
|
|
|
|
|
|
|
|
|
# JWT
|
|
|
|
|
JWT_SECRET=generate-random-secure-string-here
|
|
|
|
|
JWT_TTL_SECONDS=3600
|
|
|
|
|
JWT_ISSUER=api-btekno
|
|
|
|
|
|
|
|
|
|
# API Key
|
|
|
|
|
RETRIBUSI_API_KEY=generate-secure-api-key-here
|
2025-12-17 13:57:11 +07:00
|
|
|
|
|
|
|
|
# CORS (Cross-Origin Resource Sharing)
|
|
|
|
|
# Untuk development: gunakan '*' untuk allow semua origin
|
|
|
|
|
# Untuk production: list origin yang diizinkan dipisah koma
|
|
|
|
|
CORS_ALLOWED_ORIGINS=*
|
|
|
|
|
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
|
|
|
|
|
CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-API-KEY,Accept,Origin
|
|
|
|
|
CORS_ALLOW_CREDENTIALS=true
|
2025-12-17 10:48:59 +07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Generate secure keys:**
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
```bash
|
|
|
|
|
# JWT Secret (min 32 characters)
|
|
|
|
|
openssl rand -base64 32
|
|
|
|
|
|
|
|
|
|
# API Key
|
|
|
|
|
openssl rand -hex 32
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 📋 Cron Jobs Setup
|
|
|
|
|
|
|
|
|
|
Setup di aaPanel → Cron:
|
|
|
|
|
|
|
|
|
|
```cron
|
2025-12-17 17:41:27 +07:00
|
|
|
# Daily summary (run at 1 AM every day, rekap kemarin)
|
2025-12-17 10:48:59 +07:00
|
|
|
0 1 * * * cd /www/wwwroot/api.btekno.cloud/api && /www/server/php/83/bin/php bin/daily_summary.php
|
|
|
|
|
|
2025-12-17 17:41:27 +07:00
|
|
|
# Hourly summary - REALTIME UPDATE (run every hour, update jam yang baru saja berlalu)
|
|
|
|
|
# Contoh: jam 2:00 update jam 1:00, jam 3:00 update jam 2:00, dst
|
|
|
|
|
0 * * * * cd /www/wwwroot/api.btekno.cloud/api && /www/server/php/83/bin/php bin/hourly_summary.php today $(date -d '1 hour ago' +\%H)
|
|
|
|
|
|
|
|
|
|
# Hourly summary - FINAL RECAP (run at 1 AM every day, rekap semua jam kemarin)
|
|
|
|
|
# Opsional: untuk memastikan semua jam kemarin sudah ter-rekap dengan benar
|
|
|
|
|
0 1 * * * cd /www/wwwroot/api.btekno.cloud/api && /www/server/php/83/bin/php bin/hourly_summary.php yesterday
|
2025-12-17 10:48:59 +07:00
|
|
|
```
|
|
|
|
|
|
2025-12-17 17:41:27 +07:00
|
|
|
**Penjelasan:**
|
|
|
|
|
|
|
|
|
|
1. **Daily summary**: Rekap harian untuk kemarin (jalan jam 1 pagi)
|
|
|
|
|
2. **Hourly summary - REALTIME**: Update setiap jam untuk jam yang baru saja berlalu (untuk dashboard realtime)
|
|
|
|
|
3. **Hourly summary - FINAL RECAP**: Rekap final semua jam kemarin (opsional, untuk memastikan data lengkap)
|
|
|
|
|
|
|
|
|
|
**Note**:
|
|
|
|
|
- Ganti `/www/server/php/83/bin/php` dengan path PHP yang sesuai di server Anda
|
|
|
|
|
- Untuk update realtime, cron harus jalan **setiap jam** (`0 * * * *`)
|
|
|
|
|
- Script default ke `today` jika tidak ada argumen, jadi cocok untuk update realtime
|
2025-12-17 10:48:59 +07:00
|
|
|
|
|
|
|
|
## ✅ Verification
|
|
|
|
|
|
|
|
|
|
Setelah deployment, test endpoint:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Health check
|
|
|
|
|
curl https://api.btekno.cloud/health
|
|
|
|
|
|
|
|
|
|
# Should return:
|
|
|
|
|
# {"status":"ok","time":1735123456}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🐛 Common Issues
|
|
|
|
|
|
|
|
|
|
### Error: vendor/autoload.php not found
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
**Cause**: Vendor folder belum di-install
|
2025-12-17 11:00:21 +07:00
|
|
|
**Solution**:
|
|
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
```bash
|
|
|
|
|
cd /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Error: Database connection failed
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
**Cause**: Database config salah di `.env`
|
2025-12-17 11:00:21 +07:00
|
|
|
**Solution**:
|
|
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
- Cek `DB_HOST`, `DB_NAME`, `DB_USER`, `DB_PASS` di `.env`
|
|
|
|
|
- Test koneksi: `mysql -u sql_retribusi -p sql_retribusi`
|
|
|
|
|
|
|
|
|
|
### Error: JWT secret not set
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
**Cause**: `JWT_SECRET` kosong di `.env`
|
|
|
|
|
**Solution**: Generate dan set JWT_SECRET di `.env`
|
|
|
|
|
|
|
|
|
|
### Error: Permission denied
|
2025-12-17 11:00:21 +07:00
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
**Cause**: File permission salah
|
2025-12-17 11:00:21 +07:00
|
|
|
**Solution**:
|
|
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
```bash
|
|
|
|
|
chown -R www:www /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
chmod -R 755 /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
```
|
|
|
|
|
|
2025-12-17 13:57:11 +07:00
|
|
|
### Error: CORS belum dikonfigurasi / CORS error di browser
|
|
|
|
|
|
|
|
|
|
**Cause**: CORS middleware belum ter-deploy atau konfigurasi `.env` belum ada
|
|
|
|
|
**Solution**:
|
|
|
|
|
|
|
|
|
|
1. **Pastikan code terbaru sudah di-pull:**
|
|
|
|
|
```bash
|
|
|
|
|
cd /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
git pull origin main
|
|
|
|
|
composer dump-autoload --optimize
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
2. **Pastikan `.env` sudah ada konfigurasi CORS:**
|
|
|
|
|
```bash
|
|
|
|
|
nano /www/wwwroot/api.btekno.cloud/api/.env
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Tambahkan (atau pastikan sudah ada):
|
|
|
|
|
```env
|
|
|
|
|
CORS_ALLOWED_ORIGINS=*
|
|
|
|
|
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
|
|
|
|
|
CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-API-KEY,Accept,Origin
|
|
|
|
|
CORS_ALLOW_CREDENTIALS=true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
3. **Restart PHP-FPM:**
|
|
|
|
|
```bash
|
|
|
|
|
# Via aaPanel: Website -> PHP -> Service Management -> Reload
|
|
|
|
|
# Atau via command (sesuaikan PHP version):
|
|
|
|
|
systemctl reload php-fpm-83
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
4. **Test CORS dari browser console:**
|
|
|
|
|
```javascript
|
|
|
|
|
fetch('https://api.btekno.cloud/health', {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then(res => res.json())
|
|
|
|
|
.then(data => console.log('CORS OK:', data))
|
|
|
|
|
.catch(err => console.error('CORS Error:', err));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
5. **Cek response headers:**
|
|
|
|
|
```bash
|
|
|
|
|
curl -I -H "Origin: http://localhost:3000" https://api.btekno.cloud/health
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Harus ada header `Access-Control-Allow-Origin` di response.
|
|
|
|
|
|
2025-12-17 10:48:59 +07:00
|
|
|
## 📊 Monitoring
|
|
|
|
|
|
|
|
|
|
- Check logs: `/www/wwwroot/api.btekno.cloud/api/logs/` (jika ada)
|
|
|
|
|
- Check PHP error log di aaPanel
|
|
|
|
|
- Monitor database size dan performance
|
|
|
|
|
- Monitor realtime_events table (cleanup old data jika perlu)
|
|
|
|
|
|
|
|
|
|
## 🔄 Rollback
|
|
|
|
|
|
|
|
|
|
Jika ada masalah setelah update:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# 1. Rollback ke commit sebelumnya
|
|
|
|
|
cd /www/wwwroot/api.btekno.cloud/api
|
|
|
|
|
git log --oneline # Lihat commit history
|
|
|
|
|
git checkout <previous-commit-hash>
|
|
|
|
|
|
|
|
|
|
# 2. Reinstall dependencies
|
|
|
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
|
|
|
|
|
|
# 3. Test endpoint
|
|
|
|
|
curl https://api.btekno.cloud/health
|
|
|
|
|
```
|