Search Operations Center menyatukan pencarian informasi publik UNAIR yang tersebar di website utama, direktorat, pusat, unit penunjang, repository, scholar, dan sumber resmi lainnya. Platform menyediakan crawler terkontrol, indeks Meilisearch, local fallback, REST API, widget pencarian, serta portal tata kelola sumber informasi.
Distribusi publik: repository ini sengaja tidak menyertakan raw crawl JSON, database SQLite/Meilisearch, SQL dump, maupun state runtime. Dataset produksi harus dipasok melalui penyimpanan privat dan tidak boleh dimasukkan ke repository publik.
- Pencarian terpadu dengan filter unit dan delapan kategori konten canonical.
- Crawler asynchronous aiohttp dengan robots.txt, deduplikasi, rate limit, checkpoint, dan resume.
- Full reindex manual ke Meilisearch serta local fallback saat layanan indeks tidak tersedia.
- Push API berbasis API key dan pull API publik untuk integrasi website unit.
- Portal admin untuk registry sumber, permintaan crawling/indexing, audit, dan monitoring.
- Bootstrap administrator deployment melalui environment tanpa akun default.
- Password admin menggunakan bcrypt; hash lama dimigrasikan setelah login sukses.
- Widget JavaScript siap semat untuk website UNAIR, termasuk WordPress.
flowchart LR
U["Pengguna / Website Unit"] -->|Search API atau Widget| A["Go HTTP Service"]
P["Portal Administrator"] --> A
A -->|Query utama| M["Meilisearch"]
A -->|Fallback| J["Dataset privat"]
C["Crawler aiohttp"] --> H["JSON per-host"]
H --> X["Compaction & Deduplication"]
X --> J
J --> I["Go Indexer"]
I --> M
S["Push API Unit"] -->|X-API-Key| A
A --> R["Runtime state privat"]
MySQL bukan service runtime aktif. Export SQL dan dataset mentah tidak disertakan dalam distribusi publik.
| Area | Teknologi |
|---|---|
| Backend dan REST API | Go 1.23, net/http |
| Search engine | Meilisearch 1.49 |
| Crawler | Python 3.12, aiohttp, Beautiful Soup |
| Frontend | HTML5, CSS3, Vanilla JavaScript |
| Auth | Session cookie HTTP-only, bcrypt |
| Runtime | Docker Compose |
| Storage aplikasi | SQLite/Meilisearch privat dan state runtime lokal |
| Export data | JSON/SQL privat, tidak disimpan di repository publik |
- Windows 10/11, Linux, atau macOS.
- Git dan Git LFS.
- Go 1.23+.
- Python 3.12+.
- Docker Desktop atau Docker Engine dengan Compose v2.
- 4 CPU core.
- RAM sistem 16 GB.
- Alokasi RAM Docker sekitar 8 GB.
- Disk kosong minimal 30 GB.
Sediakan 40-50 GB disk kosong sebelum build atau full reindex. Proses ini dapat menyimpan image, build cache, dataset sumber, dan indeks Meilisearch secara bersamaan.
Dependency Python canonical tersedia di requirements.txt. requirements-crawler.txt hanya merujuk file tersebut agar instalasi lokal dan Docker konsisten.
Angka di bawah adalah referensi audit deployment privat, bukan data yang disertakan dalam repository publik.
Audit lokal 16 Juli 2026:
| Komponen | Ukuran | Peran |
|---|---|---|
| Dataset gabungan | 1,61 GB | Dataset privat runtime dan fallback |
| Crawl per-host | 1,44 GB | Checkpoint privat crawler |
| SQL dump | 2,60 GB | Export/arsip privat |
| Docker volume Meilisearch | 11,41 GB | Indeks pencarian aktif |
| App image | 568 MB | Runtime Go + Python crawler |
| Meilisearch image | 252 MB | Search engine |
| Docker build cache | 1,16 GB | Cache build |
| data/meili_data/ lokal lama | 10,27 GB | Indeks lokal lama, tidak di-mount Compose |
| Volume MySQL orphan | sekitar 582 MB | Sisa stack lama, bukan runtime aktif |
| Docker VHDX | 56,33 GB | Disk virtual historis Docker Desktop |
Ukuran VHDX tidak sama dengan data aktif karena file virtual dapat tetap besar setelah isi Docker dibersihkan.
- Buat konfigurasi lokal.
Copy-Item .env.example .env- Isi secret acak dan bootstrap admin di .env. Jangan commit file ini.
MEILI_MASTER_KEY=<random-secret>
SESSION_SECRET=<random-secret>
BOOTSTRAP_ADMIN_NAME=Administrator Platform UNAIR
BOOTSTRAP_ADMIN_EMAIL=<admin-email>
BOOTSTRAP_ADMIN_PASSWORD=<strong-password>
SESSION_COOKIE_SECURE=falseGunakan SESSION_COOKIE_SECURE=true pada deployment HTTPS.
- Build dan jalankan service.
docker compose up -d --build
docker compose ps- Buka:
- Portal publik: http://localhost:8080
- Pencarian: http://localhost:8080/search
- Login pengelola: http://localhost:8080/login
- Health API: http://localhost:8080/api/v1/health
- Meilisearch lokal: http://localhost:7700
Tidak ada akun admin default. Jika environment bootstrap kosong, pencarian publik tetap berjalan tetapi portal admin tidak memiliki akun bawaan.
Startup tidak melakukan reindex otomatis. Ini mencegah penggunaan RAM dan disk berulang setiap container restart.
docker compose run --rm --entrypoint unair-search-indexer appVerifikasi jumlah dokumen:
Invoke-RestMethod http://localhost:8080/api/v1/healthReindex diperlukan setelah dataset gabungan berubah, hasil auto-crawl baru selesai di-compact, atau konfigurasi indeks diganti.
Jalankan Meilisearch terpisah, lalu:
python -m pip install -r requirements.txt
$env:MEILI_URL="http://localhost:7700"
$env:COMBINED_CRAWL_FILE="./data/combined_crawl.json"
go run ./cmd/serverJika Meilisearch tidak tersedia, endpoint pencarian memakai local fallback dari combined_crawl.json. Fallback membantu pengembangan, tetapi Meilisearch direkomendasikan untuk deployment dan dataset besar.
Konfigurasi target berada di config/crawl_targets.json.
python -m pip install -r requirements.txt
python -u crawl.pyMelihat log container crawler:
docker logs -f unair_subdomain_crawlerSetelah crawling selesai:
python compact_crawls.py
docker compose run --rm --entrypoint unair-search-indexer appCrawler menghormati robots.txt, hanya mengambil HTML publik, mengecualikan domain fakultas sesuai konfigurasi branch, dan menyimpan checkpoint atomically.
GET /api/search?q=beasiswa&limit=10&page=1Endpoint ini tidak memberikan file JSON mentah. Konsumen hanya menerima hasil pencarian sesuai query.
POST /api/v1/documents/bulk
Content-Type: application/json
X-API-Key: <source-api-key>{
"documents": [
{
"id": "unit-001",
"title": "Judul informasi",
"url": "https://unit.unair.ac.id/informasi",
"content": "Isi ringkas informasi",
"category": "Pendidikan"
}
]
}API key diterbitkan per sumber melalui portal admin dan tidak boleh ditulis di repository.
Dokumentasi detail:
cmd/ entrypoint server dan indexer
internal/ auth, bootstrap, store, crawler manager, search, HTTP API
static/ homepage, search page, portal admin, widget
config/ konfigurasi crawler
data/app.json state registry/audit/request
data/combined_crawl.json dataset gabungan dan local fallback
data/crawls/ output incremental per host
dummy_db/ SQL export/arsip
docs/ dokumentasi teknis dan screenshot
crawl.py crawler asynchronous
compact_crawls.py compaction dan deduplikasi
docker-compose.yml stack app + Meilisearch
- Ganti seluruh placeholder di .env.
- Gunakan HTTPS dan SESSION_COOKIE_SECURE=true.
- Batasi ALLOWED_ORIGINS ke domain deployment.
- Jangan publish port Meilisearch ke internet tanpa firewall/reverse proxy.
- Jangan commit .env, API key, password, atau dump yang mengandung secret.
- Akun demo lama dinonaktifkan saat startup.
- Bootstrap admin dibuat dari environment dan disimpan dengan bcrypt.
- Rotasi SESSION_SECRET dan MEILI_MASTER_KEY sesuai kebijakan operasional.
- Backup data/app.json, dataset gabungan, serta volume Meilisearch sebelum migrasi.
Periksa pemakaian tanpa menghapus data:
docker system df -v
docker volume ls
Get-ChildItem data,dummy_db -Recurse -File |
Measure-Object Length -SumKandidat cleanup yang perlu diverifikasi terlebih dahulu adalah build cache, container/image tidak terpakai, data/meili_data lokal lama, dan volume MySQL orphan. Jangan hapus data/combined_crawl.json, data/crawls, SQL dump, atau volume Meilisearch aktif tanpa backup tervalidasi.
Docker Desktop dapat mengecilkan pemakaian logis tanpa langsung mengecilkan ukuran VHDX. Optimasi VHDX dilakukan terpisah setelah Docker dihentikan dan backup tersedia.
Proyek ini tersedia dengan MIT License.
Copyright (c) 2026 Universitas Airlangga.

