feat: update deployment configuration and enhance VITE_API_BASE_URL handling

This commit is contained in:
Asep Haryana Saputra
2026-05-22 21:53:01 +00:00
parent 39039b4d27
commit 1d421ee948
5 changed files with 260 additions and 297 deletions
Submodule .claude/worktrees/agent-a0c0d2ca3329a16b7 deleted from fbd85c7e3a
+3
View File
@@ -8,6 +8,7 @@ on:
env: env:
REGISTRY: ghcr.io REGISTRY: ghcr.io
VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL || 'https://api.zeavisedu.asepharyana.tech' }}
jobs: jobs:
build: build:
@@ -59,6 +60,8 @@ jobs:
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
build-args: |
VITE_API_BASE_URL=${{ env.VITE_API_BASE_URL }}
cache-from: type=gha,scope=${{ matrix.service.name }} cache-from: type=gha,scope=${{ matrix.service.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.service.name }} cache-to: type=gha,mode=max,scope=${{ matrix.service.name }}
+239 -285
View File
@@ -1,382 +1,336 @@
# ZeaVis Edu # ZeaVis Edu
ZeaVis Edu adalah aplikasi fullstack untuk klasifikasi penyakit daun jagung menggunakan machine learning. Sistem ini terdiri dari tiga layanan utama: web frontend, API backend, dan layanan ML, yang dapat dijalankan secara lokal atau di-deploy dengan Docker. ZeaVis Edu adalah aplikasi edukasi untuk membantu mengenali penyakit daun jagung melalui klasifikasi gambar berbasis machine learning. Repositori ini menggabungkan aplikasi web, API backend, layanan inferensi ML, serta pipeline pelatihan dan ekspor model EfficientNetV2B0.
## Fitur ## Fitur Utama
- **Klasifikasi Penyakit Daun Jagung**: Mengidentifikasi 4 jenis penyakit daun jagung - Aplikasi web untuk pengalaman pengguna dan interaksi edukatif.
- **Antarmuka Web Modern**: Dibangun dengan React, Vite, dan TypeScript - API backend untuk status layanan, integrasi data, dan komunikasi dengan layanan ML.
- **API RESTful**: Backend Elysia dengan Drizzle ORM untuk PostgreSQL - ML service berbasis FastAPI untuk inferensi penyakit daun jagung dari gambar.
- **Layanan ML Terpisah**: FastAPI dengan model TensorFlow EfficientNetV2B0 - Pipeline machine learning untuk preprocessing dataset, training di Google Colab, dan ekspor model produksi.
- **Docker Deployment**: Containerized dengan docker-compose dan Traefik reverse proxy - Dukungan Docker untuk deployment web, API, dan ML service.
- **Workflow ML Lengkap**: Dari preprocessing data hingga export model produksi - Workspace monorepo berbasis Bun dan Moon untuk menjalankan task development, typecheck, dan build secara terpusat.
## Kelas Penyakit yang Dideteksi ## Kelas Penyakit
Model machine learning dapat mengklasifikasikan 4 kondisi daun jagung: Model klasifikasi menargetkan empat label berbahasa Indonesia:
1. **Bercak Daun** — Gray Leaf Spot | Label | Deskripsi |
2. **Hawar Daun** — Northern/Southern Leaf Blight |---|---|
3. **Karat Daun** — Common Rust | Bercak Daun | Gray Leaf Spot |
4. **Daun Sehat** — healthy corn leaf | Hawar Daun | Northern/Southern Leaf Blight |
| Karat Daun | Common Rust |
| Daun Sehat | Daun jagung tanpa gejala penyakit |
## Struktur Proyek ## Struktur Proyek
``` ```text
ZeaVis-Edu/ .
├── apps/ ├── apps/
│ ├── web/ # Frontend React + Vite + TypeScript │ ├── api/ # Backend Elysia/Bun
│ ├── api/ # Backend Elysia + Drizzle + PostgreSQL │ ├── ml-service/ # Layanan inferensi FastAPI + TensorFlow
│ └── ml-service/ # FastAPI + TensorFlow ML service │ └── web/ # Frontend React + Vite
├── Machine_Learning/ # Pipeline dataset, training, dan ekspor model
├── packages/ ├── packages/
│ └── shared/ # Shared TypeScript types dan utilities │ └── shared/ # Tipe dan utilitas bersama TypeScript
├── Machine_Learning/ # Pipeline ML: preprocessing, training, export ├── docker-compose.yml # Konfigurasi deployment container
├── docker-compose.yml ├── package.json # Script dan workspace root Bun
└── package.json # Root workspace dengan Moon tasks └── README.md # Dokumentasi utama proyek
``` ```
## Tech Stack ## Tech Stack
### Frontend (apps/web) ### Frontend
- **React 18** dengan TypeScript
- **Vite** untuk build tool
- **React Router** untuk routing
- **TanStack Query** untuk data fetching
- **Zustand** untuk state management
- **Tailwind CSS** untuk styling
- **shadcn/ui** untuk komponen UI
### Backend (apps/api) - React
- **Bun** runtime - Vite
- **Elysia** framework web - TypeScript
- **Drizzle ORM** dengan PostgreSQL - React Router
- **TypeScript** - TanStack Query
- Zustand
- Tailwind CSS
### ML Service (apps/ml-service) ### Backend API
- **FastAPI** dengan Python
- **TensorFlow** untuk inferensi model
- **EfficientNetV2B0** arsitektur model
- **Pydantic** untuk validasi data
### ML Pipeline (Machine_Learning/) - Bun
- **Python** dengan TensorFlow/Keras - Elysia
- **EfficientNetV2B0** untuk training - Drizzle ORM
- **Google Colab** untuk training dengan GPU - PostgreSQL
- **TensorFlow SavedModel, TFLite, TensorFlow.js** untuk export
### Infrastruktur ### Machine Learning
- **Docker** dan **docker-compose** untuk containerization
- **Traefik** sebagai reverse proxy - Python
- **PostgreSQL** database - TensorFlow/Keras
- **Moon** sebagai task runner untuk monorepo - EfficientNetV2B0
- FastAPI
- Uvicorn
- TFLite
- TensorFlow.js
### Tooling & Deployment
- Bun workspaces
- Moon task runner
- Docker
- Docker Compose
- GitHub Container Registry
- Traefik labels untuk routing deployment
## Prasyarat ## Prasyarat
- **Node.js 18+** atau **Bun** (direkomendasikan) Untuk menjalankan seluruh project secara lokal, siapkan:
- **Python 3.9+** dengan pip
- **Docker** dan **docker-compose** (untuk deployment)
- **Git**
## Instalasi - Bun
- Python 3.93.11 untuk pipeline ML
- Python 3.10+ untuk `apps/ml-service`
- Docker dan Docker Compose jika ingin menjalankan/deploy via container
- PostgreSQL jika fitur backend yang membutuhkan database digunakan
- File model `Machine_Learning/best_model/best_model.keras` untuk inferensi ML lokal
### 1. Clone Repository ## Instalasi Root Workspace
```bash
git clone https://github.com/mytheclipse/ZeaVis-Edu.git Jalankan dari root repository:
cd ZeaVis-Edu
```
### 2. Install Dependencies
```bash ```bash
bun install bun install
``` ```
### 3. Setup Environment Variables ## Menjalankan Project Lokal
Salin file `.env.example` ke `.env` dan sesuaikan nilai-nilainya:
### Menjalankan Semua Task Development
```bash ```bash
cp .env.example .env bun run dev
``` ```
## Menjalankan Secara Lokal Script ini menjalankan task `dev` melalui Moon untuk workspace yang tersedia.
### Type Check
### Perintah Root (Menggunakan Moon)
```bash ```bash
# Development mode (semua layanan)
bun run dev
# Build production
bun run build
# Type checking
bun run typecheck bun run typecheck
``` ```
### Web App (apps/web) ### Build Produksi
```bash
bun run build
```
## Menjalankan Service Secara Terpisah
### Web App
```bash ```bash
cd apps/web cd apps/web
bun run dev bun run dev
``` ```
Akses di: http://localhost:5173
### API (apps/api) Secara default Vite akan menjalankan server development dan menampilkan URL lokal di terminal.
### API Backend
```bash ```bash
cd apps/api cd apps/api
bun run start bun run start
``` ```
Akses di: http://localhost:3000
### ML Service (apps/ml-service) API membaca konfigurasi dari file `.env` di root repository melalui script Bun.
Script lain yang tersedia:
```bash
bun run db:generate
bun run db:migrate
bun run db:seed
bun run typecheck
```
### ML Service
```bash ```bash
cd apps/ml-service cd apps/ml-service
# Install dependencies Python python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
# Jalankan service uvicorn main:app --host 0.0.0.0 --port 8001
uvicorn main:app --reload --port 8000
```
Akses di: http://localhost:8000
## Endpoint ML Service
### 1. GET /health
**Deskripsi**: Health check endpoint
**Response**:
```json
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00Z"
}
``` ```
### 2. GET /metadata Default path model adalah:
**Deskripsi**: Mendapatkan metadata model
**Response**: ```text
```json ../../Machine_Learning/best_model/best_model.keras
{
"model_name": "EfficientNetV2B0",
"input_size": 224,
"classes": ["Bercak Daun", "Hawar Daun", "Karat Daun", "Daun Sehat"],
"version": "1.0.0"
}
``` ```
### 3. POST /predict Jika model berada di lokasi lain, gunakan environment variable `MODEL_PATH`.
**Deskripsi**: Prediksi gambar daun jagung
**Request Body**:
```json
{
"image": "base64_encoded_image_string"
}
```
**Response**:
```json
{
"predictions": [
{
"class": "Bercak Daun",
"confidence": 0.95
},
{
"class": "Hawar Daun",
"confidence": 0.03
},
{
"class": "Karat Daun",
"confidence": 0.01
},
{
"class": "Daun Sehat",
"confidence": 0.01
}
],
"top_prediction": {
"class": "Bercak Daun",
"confidence": 0.95
}
}
```
## Deployment dengan Docker ## Endpoint Penting
### ML Service
| Method | Endpoint | Fungsi |
|---|---|---|
| GET | `/health` | Mengecek status service dan status model |
| GET | `/metadata` | Melihat metadata service, label, input size, dan path model |
| POST | `/predict` | Mengunggah gambar daun jagung untuk klasifikasi |
Contoh verifikasi lokal:
### 1. Build dan Jalankan dengan docker-compose
```bash ```bash
docker-compose up -d curl http://localhost:8001/health
curl http://localhost:8001/metadata
curl -X POST http://localhost:8001/predict -F "file=@/path/to/corn-leaf.jpg"
``` ```
### 2. Services dalam docker-compose.yml ## Docker Deployment
- **web**: Frontend React app (port 80 dalam container)
- **api**: Backend API (port 3000 dalam container)
- **ml**: ML service (port 8000 dalam container)
- **Network**: `app-shared-net` untuk komunikasi antar service
### 3. Environment Variables untuk Docker File `docker-compose.yml` di root menyiapkan tiga service produksi:
Pastikan file `.env` berisi:
```env - `web` untuk frontend
DATABASE_URL=postgresql://user:password@postgres:5432/zeavis - `api` untuk backend
API_PORT=3000 - `ml` untuk layanan inferensi machine learning
WEB_APP_URL=https://zeavisedu.asepharyana.tech
ML_SERVICE_URL=https://ml.zeavisedu.asepharyana.tech Konfigurasi compose menggunakan image dari GitHub Container Registry:
MODEL_PATH=/app/model/best_model.keras
MODEL_INPUT_SIZE=224 ```text
ghcr.io/${GITHUB_REPOSITORY:-mytheclipse/zeavis-edu}/web:main
ghcr.io/${GITHUB_REPOSITORY:-mytheclipse/zeavis-edu}/api:main
ghcr.io/${GITHUB_REPOSITORY:-mytheclipse/zeavis-edu}/ml:main
```
Compose juga mengasumsikan network eksternal bernama `app-shared-net` dan routing Traefik untuk domain produksi. Service `ml` berjalan pada port `8000` di dalam container.
Contoh menjalankan compose setelah environment dan network siap:
```bash
docker compose up -d
``` ```
## Workflow Machine Learning ## Workflow Machine Learning
### 1. Preprocessing Data Detail lengkap tersedia di [`Machine_Learning/README.md`](Machine_Learning/README.md). Ringkasnya:
```bash
cd Machine_Learning
python preprocessing.py
```
Membutuhkan file `dataset_1.zip`, `dataset_2.zip`, `dataset_3.zip` di direktori yang sama.
### 2. Training di Google Colab 1. Unduh `dataset_1.zip`, `dataset_2.zip`, dan `dataset_3.zip` lalu letakkan di `Machine_Learning/`.
- Buka `notebook.ipynb` di Google Colab dengan GPU enabled 2. Jalankan preprocessing lokal:
- Upload `dataset.zip` yang dihasilkan dari preprocessing
- Jalankan notebook untuk training model EfficientNetV2B0
- Model terbaik akan disimpan sebagai `best_model.keras`
### 3. Export Model untuk Produksi ```bash
```bash cd Machine_Learning
cd Machine_Learning python preprocessing.py
python save_model.py ```
```
Menghasilkan:
- `model/saved_model/` (TensorFlow SavedModel)
- `model/model.tflite` (TFLite format)
### 4. Convert ke TensorFlow.js 3. Upload `dataset.zip` ke Google Drive.
```bash 4. Jalankan `notebook.ipynb` di Google Colab dengan GPU.
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python 5. Download model terbaik sebagai `best_model/best_model.keras`.
tensorflowjs_converter \ 6. Ekspor model produksi:
--input_format=tf_saved_model \
--output_format=tfjs_graph_model \
--signature_name=serving_default \
--saved_model_tags=serve \
model/saved_model \
model/tfjs_model
```
## Artifak yang Dihasilkan ```bash
python save_model.py
```
### File/Direktori yang Dihasilkan (tidak termasuk dalam repo) 7. Konversi TensorFlow.js via CLI:
- `Machine_Learning/dataset_1.zip`, `dataset_2.zip`, `dataset_3.zip` — dataset sumber
- `Machine_Learning/dataset/` dan `dataset.zip` — hasil preprocessing
- `Machine_Learning/best_model/best_model.keras` — model terlatih dari Colab
- `Machine_Learning/model/saved_model/`, `model/model.tflite`, `model/tfjs_model/` — export produksi
## Environment Variables ```bash
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
tensorflowjs_converter \
--input_format=tf_saved_model \
--output_format=tfjs_graph_model \
--signature_name=serving_default \
--saved_model_tags=serve \
model/saved_model \
model/tfjs_model
```
### Umum Output utama pipeline ML:
```env
NODE_ENV=development|production
```
### Database | Path | Kegunaan |
```env |---|---|
DATABASE_URL=postgresql://user:password@host:5432/database | `Machine_Learning/dataset.zip` | Dataset siap upload ke Colab |
``` | `Machine_Learning/best_model/best_model.keras` | Model Keras hasil training |
| `Machine_Learning/model/saved_model/` | TensorFlow SavedModel |
| `Machine_Learning/model/model.tflite` | Model untuk mobile/TFLite |
| `Machine_Learning/model/tfjs_model/` | Model untuk TensorFlow.js |
### API ## Artifact Lokal dan Generated Files
```env
API_PORT=3000
WEB_APP_URL=http://localhost:5173
ML_SERVICE_URL=http://localhost:8000
```
### ML Service Beberapa file tidak tersedia di fresh clone karena berukuran besar, dihasilkan lokal, atau berasal dari sumber eksternal:
```env
MODEL_PATH=/path/to/best_model.keras - `Machine_Learning/dataset_1.zip`
MODEL_INPUT_SIZE=224 - `Machine_Learning/dataset_2.zip`
``` - `Machine_Learning/dataset_3.zip`
- `Machine_Learning/dataset/`
- `Machine_Learning/dataset.zip`
- `Machine_Learning/best_model/best_model.keras`
- `Machine_Learning/model/saved_model/`
- `Machine_Learning/model/model.tflite`
- `Machine_Learning/model/tfjs_model/`
## Environment Variable Penting
| Variable | Digunakan oleh | Keterangan |
|---|---|---|
| `DATABASE_URL` | API | URL koneksi PostgreSQL untuk Drizzle |
| `API_PORT` | API | Port backend produksi |
| `WEB_APP_URL` | API | URL frontend untuk konfigurasi CORS/integrasi |
| `ML_SERVICE_URL` | API | URL layanan ML |
| `MODEL_PATH` | ML Service | Lokasi file model Keras |
| `MODEL_INPUT_SIZE` | ML Service | Ukuran input model, default produksi `224` |
## Troubleshooting ## Troubleshooting
### 1. Bun Install Error ### `bun run dev` gagal karena dependency belum tersedia
Jalankan ulang instalasi dari root repository:
```bash ```bash
# Jika bun tidak terinstall bun install
curl -fsSL https://bun.sh/install | bash
``` ```
### 2. Python Dependencies Error ### API membutuhkan database
```bash
cd apps/ml-service Pastikan `DATABASE_URL` tersedia di `.env` root dan PostgreSQL dapat diakses oleh aplikasi.
python -m venv venv
source venv/bin/activate ### ML service gagal memuat model
pip install -r requirements.txt
Pastikan file model tersedia di path default:
```text
Machine_Learning/best_model/best_model.keras
``` ```
### 3. Docker Network Error Atau set path khusus:
```bash
MODEL_PATH=/path/to/best_model.keras uvicorn main:app --host 0.0.0.0 --port 8001
```
### Docker Compose gagal karena network tidak ditemukan
`docker-compose.yml` menggunakan network eksternal `app-shared-net`. Buat network tersebut jika belum ada:
```bash ```bash
# Buat network jika belum ada
docker network create app-shared-net docker network create app-shared-net
``` ```
### 4. ML Model Not Found ### Konversi TensorFlow.js gagal karena konflik protobuf
Pastikan file `best_model.keras` ada di:
- `Machine_Learning/best_model/best_model.keras` (untuk local)
- `/app/model/best_model.keras` (untuk Docker container)
## Workflow Development Jalankan konversi melalui CLI dan set environment variable berikut:
### 1. Setup Development Environment
```bash ```bash
git clone <repository> export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
cd ZeaVis-Edu
bun install
cp .env.example .env
``` ```
### 2. Jalankan Layanan Secara Terpisah ## Pengembangan
```bash
# Terminal 1: Web app
cd apps/web && bun run dev
# Terminal 2: API Alur umum pengembangan:
cd apps/api && bun run start
# Terminal 3: ML service 1. Install dependency dengan `bun install`.
cd apps/ml-service && uvicorn main:app --reload --port 8000 2. Jalankan service yang dibutuhkan secara lokal.
``` 3. Jalankan `bun run typecheck` sebelum membuat commit.
4. Jalankan `bun run build` untuk memverifikasi build produksi.
### 3. Testing 5. Untuk perubahan ML, ikuti dokumentasi detail di `Machine_Learning/README.md`.
```bash 6. Untuk perubahan ML service, cek juga `apps/ml-service/README.md`.
# Type checking
bun run typecheck
# Build production
bun run build
```
### 4. Docker Testing
```bash
# Build dan jalankan
docker-compose up --build
# Hentikan services
docker-compose down
```
## Dokumentasi Terkait ## Dokumentasi Terkait
- `Machine_Learning/README.md` — Dokumentasi workflow machine learning - [`Machine_Learning/README.md`](Machine_Learning/README.md) — panduan lengkap dataset, training, dan ekspor model.
- `CLAUDE.md`Panduan untuk Claude Code - [`apps/ml-service/README.md`](apps/ml-service/README.md)panduan menjalankan dan memverifikasi layanan inferensi ML.
- `docker-compose.yml` — Konfigurasi Docker deployment
- `apps/web/package.json` — Dependencies frontend
- `apps/api/package.json` — Dependencies backend
- `apps/ml-service/requirements.txt` — Dependencies ML service
## Kontribusi
1. Fork repository
2. Buat branch fitur (`git checkout -b feature/amazing-feature`)
3. Commit perubahan (`git commit -m 'Add amazing feature'`)
4. Push ke branch (`git push origin feature/amazing-feature`)
5. Buat Pull Request
## Lisensi
Distributed under the MIT License. See `LICENSE` for more information.
## Kontak
Asep Haryana Saputra - [GitHub](https://github.com/mytheclipse)
Project Link: [https://github.com/mytheclipse/ZeaVis-Edu](https://github.com/mytheclipse/ZeaVis-Edu)
+2
View File
@@ -9,6 +9,8 @@ RUN bun install --frozen-lockfile
COPY packages/shared packages/shared COPY packages/shared packages/shared
COPY apps/web apps/web COPY apps/web apps/web
ARG VITE_API_BASE_URL
ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
RUN bun run --cwd packages/shared build RUN bun run --cwd packages/shared build
RUN bun run --cwd apps/web build RUN bun run --cwd apps/web build
+16 -11
View File
@@ -1,17 +1,22 @@
import react from '@vitejs/plugin-react'; import react from '@vitejs/plugin-react';
import path from 'node:path'; import path from 'node:path';
import { defineConfig } from 'vite'; import { defineConfig, loadEnv } from 'vite';
export default defineConfig({ export default defineConfig(({ mode }) => {
plugins: [react()], const env = loadEnv(mode, process.cwd(), '');
server: { const apiProxyTarget = env.VITE_API_PROXY_TARGET || 'http://localhost:3000';
proxy: {
'/api': 'http://localhost:3000', return {
plugins: [react()],
server: {
proxy: {
'/api': apiProxyTarget,
},
}, },
}, resolve: {
resolve: { alias: {
alias: { '@': path.resolve(__dirname, './src'),
'@': path.resolve(__dirname, './src'), },
}, },
}, };
}); });