quantlab-deployment

star 0

Gunakan skill ini untuk semua operasi deployment QuantLab — backend ke AWS EC2 (systemd), frontend ke Cloudflare Pages, setup SSL/HTTPS, Supabase database, GitHub Actions CI/CD, dan monitoring. Mencakup troubleshooting deployment failures.

dedy45 By dedy45 schedule Updated 2/28/2026

name: quantlab-deployment description: Gunakan skill ini untuk semua operasi deployment QuantLab — backend ke AWS EC2 (systemd), frontend ke Cloudflare Pages, setup SSL/HTTPS, Supabase database, GitHub Actions CI/CD, dan monitoring. Mencakup troubleshooting deployment failures.

QuantLab Deployment Skill

Skill ini memandu agent dalam semua aspek deployment QuantLab ke production dan pengelolaan infrastruktur.


🎯 Kapan Skill Ini Diaktifkan

Aktifkan OTOMATIS jika:

  • User minta deploy backend atau frontend
  • Ada masalah dengan CI/CD (GitHub Actions)
  • Setup SSL/HTTPS untuk backend API
  • Configure Supabase database
  • Setup atau troubleshoot systemd service
  • Konfigurasi environment variables di production
  • Monitoring atau health check production server
  • Troubleshoot "connection refused" atau "port not accessible"

🏗️ Production Infrastructure

┌─────────────────────────────────────────────────────────────┐
│  FRONTEND: Cloudflare Pages                                   │
│  URL: https://quantlab.bamsbung.com                          │
│  Deploy: git push → GitHub Actions → wrangler pages deploy   │
│  Build: npm run build → dist/ → CF Pages                     │
└─────────────────┬───────────────────────────────────────────┘
                  │ HTTPS API calls
┌─────────────────▼───────────────────────────────────────────┐
│  BACKEND: AWS EC2                                       │
│  IP: 54.251.201.70                                           │
│  Port: 8080 (HTTP) → TODO: 443 (HTTPS via nginx)            │
│  Server: Ubuntu 24.04, 2 vCPU, 914MB RAM                    │
│  Binary: /opt/quantlab/quantlab-api (4.8MB)                  │
│  Service: systemd quantlab-api.service                        │
│  Runtime: 9.5 MB RSS (sangat efisien)                        │
└─────────────────────────────────────────────────────────────┘

🚀 Deploy Backend ke EC2

Cara 1: GitHub Actions (DIREKOMENDASIKAN untuk production)

Prerequisites:

  1. GitHub Secret sudah dikonfigurasi (lihat bagian GitHub Secrets)
  2. Push ke main branch
# .github/workflows/backend.yml akan otomatis:
# 1. cargo test → cargo clippy → cargo audit
# 2. cargo build --release → strip binary
# 3. SCP binary ke EC2
# 4. systemctl restart quantlab-api
# 5. curl /v1/health → verify

Cara 2: Manual Deploy via SSH (untuk hotfix)

# 1. Build lokal (jika environment Linux/WSL)
cd .Production/backend/rust-api
cargo build --release
strip target/release/quantlab-api

# 2. SCP ke server
scp -i ~/.ssh/ec2.pem target/release/quantlab-api ubuntu@54.251.201.70:/tmp/

# 3. SSH ke server
ssh -i ~/.ssh/ec2.pem ubuntu@54.251.201.70

# 4. Di server:
sudo systemctl stop quantlab-api
sudo cp /tmp/quantlab-api /opt/quantlab/quantlab-api
sudo chmod +x /opt/quantlab/quantlab-api
sudo systemctl start quantlab-api
sudo systemctl status quantlab-api

# 5. Verify
curl http://localhost:8080/v1/health

Cara 3: Build On-Server (untuk binary size compatibility)

# SSH ke server
ssh -i ~/.ssh/ec2.pem ubuntu@54.251.201.70

# Setup swap jika belum ada (diperlukan untuk cargo build --release)
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Clone/pull kode terbaru
cd /opt/quantlab/src
git pull origin main

# Build (⚠️ akan butuh ~5-10 menit dengan 2GB swap)
cargo build --release

# Deploy
sudo systemctl stop quantlab-api
sudo cp target/release/quantlab-api /opt/quantlab/quantlab-api
sudo systemctl start quantlab-api

🌐 Deploy Frontend ke Cloudflare Pages

Cara 1: GitHub Actions (DIREKOMENDASIKAN)

# Push ke main → CI otomatis deploy
git push origin main

Cara 2: Manual via Wrangler CLI

cd .Production/frontend

# Build
npm run build

# Deploy
npx wrangler pages deploy dist \
  --project-name=quantlab \
  --commit-message="Manual deploy $(date +%Y-%m-%d)"

Setup Cloudflare Pages Environment Variables

Dashboard: https://dash.cloudflare.com
→ Pages → quantlab → Settings → Environment Variables
→ Add untuk Production DAN Preview:

PUBLIC_SUPABASE_URL      = https://supabase.bamsbung.com
PUBLIC_SUPABASE_ANON_KEY = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.[200+ chars]
PUBLIC_API_BASE          = https://[ec2-ip]/v1

⚠️ PENTING: Set untuk Production DAN Preview environment! ⚠️ Setelah set env vars, klik Save lalu trigger redeploy!


🔐 GitHub Actions Secrets Setup

Backend Repository (quantbackend)

Settings → Secrets and variables → Actions → New repository secret

EC2_HOST        = 54.251.201.70
EC2_USER        = ubuntu  
EC2_SSH_KEY     = [isi konten file .pem LENGKAP termasuk header]
BINANCE_API_KEY       = [Binance API key]
BINANCE_API_SECRET    = [Binance API secret]

Frontend Repository (quantfrontend)

Settings → Secrets and variables → Actions → New repository secret

CLOUDFLARE_API_TOKEN  = [Token CF dengan Pages:Edit permission]
CLOUDFLARE_ACCOUNT_ID = [Account ID dari CF dashboard]

Cara Buat CF API Token yang Benar

Cloudflare Dashboard → My Profile → API Tokens → Create Token
→ Use template: "Edit Cloudflare Pages"
→ Permissions: Zone: Pages: Edit
→ Account: [your account]
→ Save → Copy token

# Test token:
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer [TOKEN]" \
  -H "Content-Type: application/json"
# Expected: {"result":{"status":"active"}}

🔒 Setup SSL/HTTPS (P0 — Belum Done!)

Backend saat ini hanya HTTP (port 8080). Frontend (HTTPS) tidak bisa call HTTP backend di production.

Option A: nginx + Let's Encrypt (DIREKOMENDASIKAN)

# SSH ke EC2
ssh -i ~/.ssh/ec2.pem ubuntu@54.251.201.70

# Install nginx
sudo apt-get update
sudo apt-get install -y nginx certbot python3-certbot-nginx

# Buat domain dulu: api.quantlab.bamsbung.com → 54.251.201.70
# (Set A record di DNS: api.quantlab.bamsbung.com → 54.251.201.70)

# Konfigurasi nginx
sudo nano /etc/nginx/sites-available/quantlab-api

# Isi:
server {
    listen 80;
    server_name api.quantlab.bamsbung.com;
    
    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
        
        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# Aktifkan site
sudo ln -s /etc/nginx/sites-available/quantlab-api /etc/nginx/sites-enabled/
sudo nginx -t  # test config
sudo systemctl restart nginx

# Get SSL cert
sudo certbot --nginx -d api.quantlab.bamsbung.com

# Verify
curl https://api.quantlab.bamsbung.com/v1/health

Option B: Cloudflare Tunnel (Zero Config SSL)

# Install cloudflared
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb

# Login dan create tunnel
cloudflared tunnel login
cloudflared tunnel create quantlab-api

# Config file
nano ~/.cloudflared/config.yml
# isi:
tunnel: [TUNNEL_ID]
credentials-file: /home/ubuntu/.cloudflared/[TUNNEL_ID].json

ingress:
  - hostname: api.quantlab.bamsbung.com
    service: http://localhost:8080
  - service: http_status:404

# Install sebagai service
sudo cloudflared service install
sudo systemctl start cloudflared

🗄️ Setup Supabase Database

  1. Deploy Supabase via Docker di EC2
  2. Gunakan port 54322 untuk Postgres Database agar bypass Supavisor
  3. Setting Caddy reverse proxy untuk API/Auth ke supabase.bamsbung.com

2. Get Connection String

Project Settings → Database → Connection string → URI
Format: postgresql://postgres:[password]@54.251.201.70:54322/postgres

3. Run Migrations di Server

# SSH ke EC2
ssh -i ~/.ssh/ec2.pem ubuntu@54.251.201.70

# Set DATABASE_URL di .env
echo 'DATABASE_URL=postgresql://postgres:[pass]@localhost:54322/postgres' \
  >> /opt/quantlab/.env

# Restart service untuk load env baru
sudo systemctl restart quantlab-api

# Verify DB connection
curl http://localhost:8080/v1/health
# Seharusnya: {"supabase": "ok"}

4. Run SQL Migrations

# Di lokal (dari .Production/backend/rust-api)
DATABASE_URL=postgresql://... sqlx migrate run

# Atau copy migration files ke server dan run di sana

🔧 systemd Service Management

Cek Status

# Status service
sudo systemctl status quantlab-api

# Lihat logs real-time
sudo journalctl -u quantlab-api -f

# Lihat 100 baris log terakhir
sudo journalctl -u quantlab-api -n 100

# Lihat logs sejak tadi
sudo journalctl -u quantlab-api --since "1 hour ago"

Service File (jika perlu recreate)

# /etc/systemd/system/quantlab-api.service
[Unit]
Description=QuantLab API Server
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=5
User=ubuntu
WorkingDirectory=/opt/quantlab
EnvironmentFile=/opt/quantlab/.env
ExecStart=/opt/quantlab/quantlab-api

# Resource limits (914 MB RAM server)
LimitNOFILE=65536
MemoryMax=512M

[Install]
WantedBy=multi-user.target
# Reload jika edit service file
sudo systemctl daemon-reload
sudo systemctl enable quantlab-api
sudo systemctl start quantlab-api

🔥 Troubleshooting Guide

Problem 1: Port 8080 Not Accessible

Symptom: curl -v http://54.251.201.70:8080/v1/health → connection timeout

Fix:

# 1. Check EC2 firewall (AWS Console)
# AWS Console → EC2 → Instance → Networking → Firewall
# Add rule: Custom TCP, port 8080, Anywhere (0.0.0.0/0)

# 2. Check Ubuntu UFW
sudo ufw allow 8080/tcp
sudo ufw reload
sudo ufw status

# 3. Check service running
sudo systemctl status quantlab-api

# 4. Check listening port
sudo ss -tlnp | grep 8080

Problem 2: Service Crash Loop

Symptom: systemctl status shows "activating" → "failed" repeatedly

Debug:

sudo journalctl -u quantlab-api -n 50

# Common causes:
# 1. SECRET_KEY too short (min 32 chars)
echo -n "$SECRET_KEY" | wc -c  # harus >= 32

# 2. ALLOWED_ORIGINS format salah (dotenvy issue)
# SALAH: ALLOWED_ORIGINS=["https://example.com"]
# BENAR: ALLOWED_ORIGINS='["https://example.com"]'

# 3. CRLF dari Windows
sed -i 's/\r//' /opt/quantlab/.env

# 4. .env file permission
chmod 600 /opt/quantlab/.env

Problem 3: GitHub Actions CI Gagal

Backend workflow gagal:

# Check: apakah working-directory benar?
# defaults.run.working-directory harus menunjuk ke folder Cargo.toml

# Check: apakah EC2_SSH_KEY format benar?
# Harus include header: -----BEGIN RSA PRIVATE KEY-----
# Harus newline di dalam konten key

# Debug SSH connection:
ssh -i [key.pem] ubuntu@54.251.201.70 "echo Connected"

Frontend workflow gagal (Wrangler):

# Check CLOUDFLARE_API_TOKEN valid:
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

# Check project name:
wrangler pages project list

# Common fix: project name di wrangler.jsonc harus match!

Problem 4: CORS Error di Frontend

Symptom: Browser console: Access-Control-Allow-Origin missing

Check backend ALLOWED_ORIGINS:

# SSH ke server
grep ALLOWED_ORIGINS /opt/quantlab/.env
# Harus ada URL frontend: https://quantlab.bamsbung.com

# Jika tidak ada, tambah dan restart
sudo systemctl restart quantlab-api

Check dev mode:

// main.rs — dev mode harus Any, prod harus strict
if config.app_env == "development" {
    CorsLayer::very_permissive()  // Any origin
} else {
    CorsLayer::new()
        .allow_origin(allowed_origins)  // strict whitelist
}

Problem 5: Supabase Auth Tidak Berfungsi di Production

Symptom: Login berhasil tapi langsung redirect ke /login

Check:

// supabase.ts — isValidAnonKey harus > 100 chars
// Placeholder "your-anon-key-here" tidak diterima!

// Verify di CF Pages env vars:
// PUBLIC_SUPABASE_ANON_KEY harus 200+ chars real JWT

📊 Health Check & Monitoring

Quick Health Check Script

#!/bin/bash
# Save sebagai: scripts/health_check.sh

API_BASE="http://54.251.201.70:8080"

echo "=== QuantLab Health Check ==="
echo "Timestamp: $(date)"
echo ""

# Check endpoint
check_endpoint() {
    local name=$1
    local url=$2
    local response=$(curl -s -w "\n%{http_code}" "$url" 2>/dev/null)
    local http_code=$(echo "$response" | tail -1)
    local body=$(echo "$response" | head -1)
    
    if [ "$http_code" = "200" ]; then
        echo "✅ $name → $http_code"
    else
        echo "❌ $name → $http_code"
        echo "   Body: $body"
    fi
}

check_endpoint "Health" "$API_BASE/v1/health"
check_endpoint "Assets" "$API_BASE/v1/assets"
check_endpoint "Regime BTC D1" "$API_BASE/v1/regime/current/BTCUSDT/D1"
check_endpoint "Dashboard Summary" "$API_BASE/v1/dashboard/summary"

echo ""
echo "=== System Resources ==="
echo "Memory: $(free -m | grep Mem | awk '{print $3"/"$2" MB"}')"
echo "Disk: $(df -h / | tail -1 | awk '{print $3"/"$2" ("$5" used)"}')"
echo "Process: $(ps aux | grep quantlab-api | grep -v grep | awk '{print "CPU:"$3"% MEM:"$4"%"}')"

Monitoring via UptimeRobot (Setup Minimal)

1. uptimerobot.com → Create Monitor
2. Type: HTTP(S)
3. URL: http://54.251.201.70:8080/v1/health
4. Interval: 5 minutes
5. Alert via: Email / Telegram

📋 Production Deployment Checklist

PRE-DEPLOY:
[ ] cargo test → semua PASS
[ ] cargo clippy -- -D warnings → 0 warnings
[ ] npm run build → 0 errors
[ ] playwright test → semua PASS

BACKEND DEPLOY:
[ ] GitHub Secrets dikonfigurasi (EC2_HOST, USER, SSH_KEY)
[ ] push ke main → GitHub Actions green
[ ] curl http://54.251.201.70:8080/v1/health → 200 OK
[ ] journalctl tidak ada errors

FRONTEND DEPLOY:
[ ] CF Pages env vars dikonfigurasi (SUPABASE_*, PUBLIC_API_BASE)
[ ] GitHub Secrets dikonfigurasi (CF_API_TOKEN, CF_ACCOUNT_ID)
[ ] push ke main → build + deploy green
[ ] Verify: https://quantlab.bamsbung.com → load OK
[ ] Login flow bekerja

POST-DEPLOY:
[ ] E2E test vs production URL
[ ] Check WebSocket (live indicator hijau di RegimeExplorer)
[ ] Monitor logs 30 menit pertama (journalctl -f)
[ ] Setup UptimeRobot monitoring

🔑 Environment Variables Reference

Backend EC2 (.env)

APP_ENV=production
AUTH_ENABLED=true
PORT=8080
SECRET_KEY=[min 32 chars! gunakan: openssl rand -hex 32]
SUPABASE_URL=https://supabase.bamsbung.com
SUPABASE_KEY=eyJ...           # anon key
SUPABASE_SERVICE_KEY=eyJ...   # service role key
SUPABASE_JWT_SECRET=[dari Supabase Project Settings → API → JWT Secret]
DATABASE_URL=postgresql://postgres:[pass]@localhost:54322/postgres
# PENTING: JSON arrays HARUS dalam single quotes!
ALLOWED_ORIGINS='["https://quantlab.bamsbung.com","https://quantlab.dedy774741.workers.dev","http://localhost:4321"]'
BINANCE_API_KEY=[key]
BINANCE_API_SECRET=[secret]
# Optional
WS_MAX_CONNECTIONS_FREE=1
WS_MAX_CONNECTIONS_PRO=3
WS_MAX_CONNECTIONS_ENTERPRISE=10
CACHE_TTL_MULTIPLIER=1.0
CACHE_MAX_ENTRIES=1000

Frontend (.env.local)

PUBLIC_SUPABASE_URL=https://supabase.bamsbung.com
PUBLIC_SUPABASE_ANON_KEY=eyJ...  # 200+ chars, REAL token!
PUBLIC_API_BASE=http://localhost:8080  # development
# Production: https://api.quantlab.bamsbung.com
Install via CLI
npx skills add https://github.com/dedy45/QuantLab --skill quantlab-deployment
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator