fpAI-komposin / setup.sh
rafi-adly's picture
Deployment
b942eae
Raw
History Blame Contribute Delete
10.1 kB
#!/usr/bin/env bash
# ╔══════════════════════════════════════════════════════════════╗
# β•‘ KomposIn β€” Non-Docker Setup untuk Azure VM β•‘
# β•‘ Instalasi: Python backend + Next.js frontend + Nginx β•‘
# β•‘ Jalankan: bash setup-nondocker.sh β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m'
log() { echo -e "${BLUE}[$(date +'%H:%M:%S')]${NC} $*"; }
ok() { echo -e " ${GREEN}βœ”${NC} $*"; }
warn() { echo -e " ${YELLOW}⚠${NC} $*"; }
err() { echo -e " ${RED}✘ $*${NC}"; exit 1; }
echo -e "\n${BOLD}${BLUE}╔════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${BLUE}β•‘ πŸ—‘οΈ KomposIn Setup β•‘${NC}"
echo -e "${BOLD}${BLUE}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${NC}\n"
# ── 0. Cek privilege ────────────────────────────────────────
[ "$EUID" -eq 0 ] || err "Script ini harus dijalankan dengan sudo"
# ── 1. System update ────────────────────────────────────────
log "Update sistem..."
apt-get update && apt-get upgrade -y
# ── 2. Install dependencies ─────────────────────────────────
log "Menginstall system libraries..."
apt-get install -y \
python3.11 python3.11-venv python3-pip \
nodejs npm \
nginx \
git git-lfs \
curl wget \
build-essential libssl-dev
ok "System packages terinstall"
# ── 3. Setup user & direktori ───────────────────────────────
log "Setup user dan direktori..."
getent passwd komposin >/dev/null 2>&1 || {
useradd -m -s /bin/bash -d /home/komposin komposin
ok "User komposin dibuat"
}
mkdir -p /opt/komposin /var/log/komposin
chown -R komposin:komposin /opt/komposin /var/log/komposin
chmod 0755 /opt/komposin /var/log/komposin
# ── 4. Clone dan setup backend ──────────────────────────────
log "Setup FastAPI backend..."
cd /opt/komposin
# Jika folder sudah ada, pull terbaru; jika belum, clone
if [ -d "fpAI-komposin" ]; then
cd fpAI-komposin
git pull hf main 2>/dev/null || warn "git pull gagal"
else
git clone https://huggingface.co/KomposIn-Team/fpAI-komposin fpAI-komposin
cd fpAI-komposin
fi
git lfs pull
# Buat virtual environment Python
cd /opt/komposin/fpAI-komposin/be
[ -d "venv" ] && rm -rf venv
python3.11 -m venv venv
source venv/bin/activate
# Install Python dependencies (CPU-only torch)
pip install --upgrade pip
pip install --extra-index-url https://download.pytorch.org/whl/cpu torch torchvision
pip install -r requirements.txt
ok "FastAPI backend ready"
# ── 5. Setup frontend ───────────────────────────────────────
log "Setup Next.js frontend..."
cd /opt/komposin/fpAI-komposin/fe
# Cek dan set next.config.ts jika belum ada output: standalone
if ! grep -q "output.*standalone" next.config.ts 2>/dev/null; then
warn "next.config.ts belum punya output: 'standalone'"
warn "Tambahkan baris ini ke next.config.ts:"
warn " output: 'standalone',"
fi
npm install
npm run build
ok "Next.js frontend build selesai"
# ── 6. Setup Nginx ──────────────────────────────────────────
log "Setup Nginx..."
cat > /etc/nginx/sites-available/komposin <<'EOF'
upstream backend {
server 127.0.0.1:8000;
keepalive 16;
}
upstream frontend {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80 default_server;
server_name _;
client_max_body_size 20M;
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=web:10m rate=30r/s;
# API proxy
location /api/ {
limit_req zone=api burst=30 nodelay;
rewrite ^/api/(.*) /$1 break;
proxy_pass http://backend;
proxy_http_version 1.1;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 180s;
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
}
# Frontend proxy
location / {
limit_req zone=web burst=50 nodelay;
proxy_pass http://frontend;
proxy_http_version 1.1;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 60s;
}
}
EOF
# Enable site dan disable default
ln -sf /etc/nginx/sites-available/komposin /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# Test & restart
nginx -t || err "Nginx config error"
systemctl enable nginx
systemctl restart nginx
ok "Nginx configured dan running"
# ── 7. Buat systemd units ──────────────────────────────────
log "Setup systemd services..."
# Backend unit
cat > /etc/systemd/system/komposin-backend.service <<EOF
[Unit]
Description=KomposIn FastAPI Backend
After=network.target
Wants=komposin-backend.service
[Service]
Type=simple
User=komposin
Group=komposin
WorkingDirectory=/opt/komposin/fpAI-komposin/be
Environment="PATH=/opt/komposin/fpAI-komposin/be/venv/bin"
Environment="PYTHONDONTWRITEBYTECODE=1"
Environment="MODEL_PATH=/opt/komposin/fpAI-komposin/model/waste_segmentor_yolo26/waste_yolo26seg_best.pt"
ExecStart=/opt/komposin/fpAI-komposin/be/venv/bin/uvicorn main:app \
--host 127.0.0.1 \
--port 8000 \
--workers 1 \
--access-log
StandardOutput=journal
StandardError=journal
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
EOF
# Frontend unit
cat > /etc/systemd/system/komposin-frontend.service <<EOF
[Unit]
Description=KomposIn Next.js Frontend
After=network.target
[Service]
Type=simple
User=komposin
Group=komposin
WorkingDirectory=/opt/komposin/fpAI-komposin/fe
Environment="NODE_ENV=production"
Environment="PORT=3000"
Environment="HOSTNAME=127.0.0.1"
ExecStart=/usr/bin/node /opt/komposin/fpAI-komposin/fe/.next/standalone/server.js
StandardOutput=journal
StandardError=journal
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd & enable
systemctl daemon-reload
systemctl enable komposin-backend.service komposin-frontend.service
ok "Systemd units created"
# ── 8. Start services ──────────────────────────────────────
log "Memulai services..."
systemctl start komposin-backend.service
systemctl start komposin-frontend.service
sleep 5
# Check status
echo ""
log "Status service:"
systemctl status komposin-backend.service --no-pager | grep -E "Active|Main PID"
systemctl status komposin-frontend.service --no-pager | grep -E "Active|Main PID"
# ── 9. Verify ──────────────────────────────────────────────
log "Verifying setup..."
sleep 3
BACKEND_OK=false
FRONTEND_OK=false
curl -f http://127.0.0.1:8000/health >/dev/null 2>&1 && BACKEND_OK=true || true
curl -f http://127.0.0.1:3000 >/dev/null 2>&1 && FRONTEND_OK=true || true
[ "$BACKEND_OK" = true ] && ok "Backend responding" || warn "Backend tidak respond"
[ "$FRONTEND_OK" = true ] && ok "Frontend responding" || warn "Frontend tidak respond"
# ── Final status ───────────────────────────────────────────
PUBLIC_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null || \
curl -s --max-time 5 api.ipify.org 2>/dev/null || \
hostname -I | awk '{print $1}')
echo ""
echo -e "\n${GREEN}${BOLD}════════════════════════════════════════════${NC}"
echo -e "${GREEN}${BOLD} βœ… KomposIn Non-Docker siap!${NC}"
echo -e "${GREEN}${BOLD}════════════════════════════════════════════${NC}\n"
echo -e " 🌐 Aplikasi : ${GREEN}http://${PUBLIC_IP}${NC}"
echo -e " πŸ“‘ API Docs : ${GREEN}http://${PUBLIC_IP}/api/docs${NC}"
echo -e " πŸ“ Project dir : ${GREEN}/opt/komposin/fpAI-komposin${NC}"
echo -e " πŸ” Backend log : journalctl -u komposin-backend.service -f"
echo -e " πŸ” Frontend log: journalctl -u komposin-frontend.service -f"
echo -e " πŸ”„ Restart : systemctl restart komposin-{backend,frontend}.service"
echo -e " πŸ›‘ Stop : systemctl stop komposin-{backend,frontend}.service\n"
echo -e "${YELLOW}Pastikan port 80 sudah dibuka di Azure NSG (Network Security Group)!${NC}"
echo -e "${YELLOW}Buka: portal.azure.com β†’ VM β†’ Networking β†’ Add inbound rule β†’ Port 80${NC}\n"