12 KiB
Deployment Guide
Panduan instalasi aplikasi di server produksi Ubuntu 22.04+.
Spesifikasi Server
| Komponen | Minimum | Rekomendasi |
|---|---|---|
| CPU | 2 core | 4 core |
| RAM | 4 GB | 8 GB |
| Storage | 40 GB SSD | 100 GB SSD |
| OS | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
Langkah 1 — Install Dependensi
sudo apt update && sudo apt upgrade -y
# PHP 8.3 + ekstensi
sudo add-apt-repository ppa:ondrej/php -y
sudo apt install -y php8.3 php8.3-fpm php8.3-pgsql php8.3-redis \
php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip php8.3-gd \
php8.3-bcmath php8.3-intl php8.3-readline
# PostgreSQL, Redis, Nginx, Supervisor
sudo apt install -y postgresql postgresql-contrib redis-server nginx supervisor
sudo systemctl enable redis-server
# Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Langkah 2 — Setup Database
sudo -u postgres psql
CREATE USER biiproject WITH PASSWORD 'password_kuat_anda';
CREATE DATABASE biiproject_db OWNER biiproject;
GRANT ALL PRIVILEGES ON DATABASE biiproject_db TO biiproject;
\q
Langkah 3 — Deploy Aplikasi
cd /var/www
sudo git clone <repo-url> html
sudo chown -R $USER:www-data html
cd html
composer install --no-dev --optimize-autoloader
npm install && npm run build
cp .env.example .env
php artisan key:generate
Edit .env
APP_NAME="biiproject"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://domain.com
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=biiproject_db
DB_USERNAME=biiproject
DB_PASSWORD=password_kuat_anda
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
BROADCAST_CONNECTION=reverb
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REVERB_APP_ID=your-app-id
REVERB_APP_KEY=your-app-key
REVERB_APP_SECRET=your-app-secret
REVERB_HOST=domain.com
REVERB_PORT=8080
REVERB_SCHEME=https
BCRYPT_ROUNDS=12
# Opsional — Error monitoring
SENTRY_LARAVEL_DSN=https://xxxx@sentry.io/xxxx
SENTRY_TRACES_SAMPLE_RATE=0.1
SENTRY_PROFILES_SAMPLE_RATE=0.1
Migrasi, Seed & Optimisasi
php artisan migrate --force
php artisan db:seed --force
php artisan cache:clear # wajib setelah seeder
php artisan storage:link
php artisan optimize
php artisan l5-swagger:generate # regen API docs
Post-Deploy Verification
# Quality gate — pastikan tidak ada regresi
./vendor/bin/phpstan analyse --memory-limit=1G
./vendor/bin/pint --test
composer audit --no-dev
# Health check
curl -sf https://domain.com/api/health | jq .
# expect: {"status":"healthy","timestamp":"...","checks":{...}}
Langkah 4 — Konfigurasi Nginx
/etc/nginx/sites-available/biiproject:
server {
listen 80;
server_name domain.com;
root /var/www/html/public;
index index.php;
client_max_body_size 50M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
# WebSocket Reverb
location /app {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 60s;
}
location ~ /\.(?!well-known) { deny all; }
}
Catatan keamanan: Laravel mengirim header
X-Content-Type-Options,X-Frame-Options,Referrer-Policy, danPermissions-Policydari middlewareSecurityHeaders. Tidak perlu duplikasi di Nginx — biarkan aplikasi yang kontrol (lebih mudah di-update via setting).
sudo ln -s /etc/nginx/sites-available/biiproject /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Langkah 5 — SSL (Let's Encrypt)
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d domain.com
Setelah HTTPS aktif, aktifkan HSTS dari admin panel: Global Settings → Login Security → HSTS Enabled. Aplikasi akan mengirim header Strict-Transport-Security: max-age=31536000; includeSubDomains; preload.
Langkah 6 — Background Workers (Supervisor)
Queue Worker
/etc/supervisor/conf.d/biiproject-worker.conf:
[program:biiproject-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/worker.log
Reverb (WebSocket)
/etc/supervisor/conf.d/biiproject-reverb.conf:
[program:biiproject-reverb]
command=php /var/www/html/artisan reverb:start --host=0.0.0.0 --port=8080
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/reverb.log
Scheduler (Cron)
echo "* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1" \
| sudo crontab -u www-data -
Scheduler menjalankan
dashboard:broadcast-statssetiap menit — membutuhkan queue worker dan Reverb sudah berjalan agar broadcast terkirim ke browser. Pastikan keduanya distart via Supervisor sebelum mengaktifkan cron.
Aktifkan
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start all
Langkah 7 — Permission File
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html/storage /var/www/html/bootstrap/cache
Langkah 8 — Konfigurasi Pasca-Deploy
A. Global Settings
Login sebagai Super Admin → System Settings → Global Settings. Pastikan:
Password Policy: min 12, charset mixed-case + digit + symbol, expiry & history sesuai kebijakanLogin Security: max attempts 5, lockout duration, 2FA toggle, captcha jika perluIP & Access: whitelist admin (IP kantor/VPN), auto-block on burstHSTS Enabled: ON (setelah SSL aktif)Single Session: ON jika kebijakan satu-device-per-akun
B. Verifikasi Quality Gate
# Pastikan dependencies aman
composer audit --no-dev --abandoned=ignore
# Pastikan tidak ada regresi
php artisan test --parallel
Layanan Eksternal (Opsional)
Sebagian besar bisa diatur via Global Settings di admin panel — tidak perlu edit .env.
Email SMTP
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@domain.com
MAIL_PASSWORD=xxxxxxxx
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@domain.com
MAIL_FROM_NAME="biiproject"
Sentry (Error Monitoring)
SENTRY_LARAVEL_DSN=https://xxxx@o0.ingest.sentry.io/xxxx
SENTRY_TRACES_SAMPLE_RATE=0.1
Buat project di sentry.io, pilih platform Laravel, dan salin DSN-nya.
Telegram Bot
- Chat
@BotFather→/newbot→ simpan Token - Kirim pesan ke bot, buka
https://api.telegram.org/bot<TOKEN>/getUpdates→ simpan Chat ID - Masukkan via Global Settings → Notifications
Catatan:
IpAccessControlmiddleware mengirim alert otomatis ke Telegram saat sebuah IP di-auto-block karena burst — pastikan token + chat id valid.
Google Drive Backup
- Google Cloud Console → buat project → enable Google Drive API
- Buat OAuth 2.0 Client ID (Desktop app)
- Dapatkan Refresh Token via OAuth Playground
- Masukkan Client ID, Client Secret, Refresh Token, dan nama folder via Global Settings → Backup
Amazon S3
- Buat IAM user dengan policy
AmazonS3FullAccess - Buat S3 bucket
- Masukkan Access Key, Secret, Bucket, Region (dan endpoint opsional) via Global Settings → Backup
Firebase Cloud Messaging (Push Notification Mobile)
- Buat project di Firebase Console → Project Settings → Cloud Messaging
- Unduh
google-services.json(Android) atauGoogleService-Info.plist(iOS) - Letakkan di direktori mobile app sesuai panduan Expo
- Device token diregistrasikan otomatis via API
/api/v1/devices/register
CI/CD
Workflow di .github/workflows/ci.yml. Setiap push ke main/develop/config/advanced dan setiap PR ke main/develop menjalankan:
- Test —
php artisan test --parallel(Postgres 15 + Redis 7 service containers) - Lint —
pint --test+composer audit --abandoned=ignore+permissions:audit - Static Analysis —
phpstan analyse --memory-limit=1G
Branch protection: PR tidak bisa di-merge kalau salah satu job gagal.
Update Aplikasi
Cara tercepat dan teraman untuk memperbarui aplikasi adalah menggunakan skrip deployment otomatis yang sudah disediakan:
cd /var/www/html
sudo chmod +x deploy.sh
./deploy.sh
Skrip ini akan melakukan:
- Masuk ke Maintenance Mode.
- Update dependencies (Composer & NPM).
- Build assets (Vite).
- Run migrations.
- Optimasi cache & pembersihan log.
- Restart background workers (Queue & Reverb).
- Verifikasi kesehatan sistem.
- Keluar dari Maintenance Mode.
Update Manual
cd /var/www/html
git pull origin main
php artisan down --secret="your-bypass-key"
composer install --no-dev --optimize-autoloader
npm ci && npm run build
php artisan migrate --force
php artisan cache:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
php artisan l5-swagger:generate
sudo supervisorctl restart biiproject-worker:*
sudo supervisorctl restart biiproject-reverb
# Verifikasi
curl -sf https://domain.com/api/health | jq -e '.checks.database.status == "ok"'
php artisan up
Deployment via Docker (alternatif)
git clone <repo-url> Project
cd Project
cp .env.example .env
# Edit .env:
# DB_HOST=pgsql (nama service Docker, bukan 127.0.0.1)
# REDIS_HOST=redis
./vendor/bin/sail up -d
./vendor/bin/sail artisan migrate --seed --force
./vendor/bin/sail artisan cache:clear
./vendor/bin/sail artisan optimize
Penting: Semua perintah
php artisandi lingkungan Docker harus dijalankan via./vendor/bin/sail artisan, bukan langsung. Hostpgsqlhanya bisa di-resolve dari dalam Docker network.
Troubleshooting
| Masalah | Solusi |
|---|---|
| 502 Bad Gateway | sudo systemctl status php8.3-fpm |
| Queue tidak jalan | sudo supervisorctl status |
| Permission denied | sudo chown -R www-data:www-data storage bootstrap/cache |
| Cache error setelah update | php artisan optimize:clear && php artisan optimize |
| Settings tidak muncul setelah seeder | php artisan cache:clear (settings di-cache 60 menit) |
| WebSocket gagal connect | sudo supervisorctl status biiproject-reverb + cek port 8080 di firewall |
pgsql host tidak resolve |
Pastikan DB_HOST=127.0.0.1 (bukan pgsql) di server non-Docker |
| Telescope/log tidak ditemukan | Cek storage/logs/laravel.log & menu System Monitoring → Logs |
| Error monitoring tidak aktif | Pastikan SENTRY_LARAVEL_DSN sudah diset di .env |
/api/health return 503 |
Cek setiap field checks.*.status — yang fail mengindikasikan masalah. warn (storage >90%) tetap 200 by design. |
| OAuth callback 404 | Pastikan route order: /auth/callback HARUS sebelum /auth/{provider} di routes/web.php. |
column "google_id" does not exist |
Pastikan migrasi 2026_05_12_120000_add_social_columns_to_users_table sudah jalan. |
| Dashboard stats tidak update real-time | Cek Reverb berjalan (supervisorctl status biiproject-reverb), queue worker aktif, dan BROADCAST_CONNECTION=reverb di .env. |
| Dashboard widget tidak tersimpan | Pastikan migrasi 2026_05_16_220000_create_dashboard_widget_preferences_table sudah dijalankan. |
Performance Tuning
PHP-FPM
/etc/php/8.3/fpm/pool.d/www.conf:
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
OPcache
/etc/php/8.3/fpm/php.ini:
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 ; production only
opcache.preload=/var/www/html/bootstrap/cache/preload.php
opcache.preload_user=www-data
Redis Tuning
/etc/redis/redis.conf:
maxmemory 1gb
maxmemory-policy allkeys-lru
PostgreSQL
Tambah index recommendation: sudah ada (lihat migrasi 2026_05_14_100000_add_performance_indexes). Untuk dataset besar (>10M rows pada activity_log), pertimbangkan pg_partman untuk partisi bulanan.