<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>OnnoWiki  - Recent changes [en]</title>
		<link>https://onnocenter.or.id/wiki/index.php/Special:RecentChanges</link>
		<description>Track the most recent changes to the wiki in this feed.</description>
		<language>en</language>
		<generator>MediaWiki 1.35.4</generator>
		<lastBuildDate>Mon, 27 Jul 2026 08:44:13 GMT</lastBuildDate>
		<item>
			<title>MCP: Reset dari nol, embed semua doc, isi vector database</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Reset_dari_nol,_embed_semua_doc,_isi_vector_database&amp;diff=73727&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Reset_dari_nol,_embed_semua_doc,_isi_vector_database&amp;diff=73727&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# Rekomendasi  **Tidak perlu install ulang AnythingLLM.** Gunakan reset melalui API lalu lakukan **restart normal**, bukan `docker kill` atau force restart.  Menghapus dan mem...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# Rekomendasi&lt;br /&gt;
&lt;br /&gt;
**Tidak perlu install ulang AnythingLLM.** Gunakan reset melalui API lalu lakukan **restart normal**, bukan `docker kill` atau force restart.&lt;br /&gt;
&lt;br /&gt;
Menghapus dan membuat ulang container dengan storage volume yang sama tidak menghapus workspace, dokumen, atau vector database karena data AnythingLLM disimpan di `/app/server/storage` dan memang dirancang tetap ada setelah rebuild atau pull image baru. ([AnythingLLM][1])&lt;br /&gt;
&lt;br /&gt;
Script berikut menggunakan API resmi untuk:&lt;br /&gt;
&lt;br /&gt;
1. Backup seluruh storage AnythingLLM.&lt;br /&gt;
2. Menghapus semua workspace.&lt;br /&gt;
3. Menghapus semua dokumen internal dan cached embedding.&lt;br /&gt;
4. Restart container secara graceful.&lt;br /&gt;
5. Membuat satu workspace baru.&lt;br /&gt;
6. Upload dan embed ulang seluruh file dari `/opt/ai-stack/documents`.&lt;br /&gt;
7. Membuat manifest berisi nama file, hash SHA-256, dan lokasi dokumen internal.&lt;br /&gt;
&lt;br /&gt;
AnythingLLM menyediakan endpoint resmi untuk mendaftar dan menghapus workspace, menghapus dokumen permanen, membuat workspace, serta upload dokumen langsung ke workspace. &lt;br /&gt;
&lt;br /&gt;
[Download reset-rebuild-anythingllm.sh](sandbox:/mnt/data/reset-rebuild-anythingllm.sh)&lt;br /&gt;
&lt;br /&gt;
Script sudah diperiksa dengan `bash -n`.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 1. Copy script ke server&lt;br /&gt;
&lt;br /&gt;
Misalnya file sudah berada di folder Downloads:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mkdir -p /opt/ai-stack/batch&lt;br /&gt;
&lt;br /&gt;
sudo cp ~/Downloads/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  /opt/ai-stack/batch/&lt;br /&gt;
&lt;br /&gt;
sudo chmod 750 \&lt;br /&gt;
  /opt/ai-stack/batch/reset-rebuild-anythingllm.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lh /opt/ai-stack/batch/reset-rebuild-anythingllm.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 2. Periksa nama dan port container&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}' \&lt;br /&gt;
  | grep -i anything&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atau:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker port anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
3001/tcp -&amp;gt; 0.0.0.0:3001&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Berarti:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export ANYTHINGLLM_URL=&amp;quot;http://127.0.0.1:3001&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila AnythingLLM memakai port host `3002`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export ANYTHINGLLM_URL=&amp;quot;http://127.0.0.1:3002&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hal ini penting bila port `3001` sudah digunakan WAHA.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 3. Buat API key AnythingLLM&lt;br /&gt;
&lt;br /&gt;
Masuk ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
AnythingLLM&lt;br /&gt;
→ Settings&lt;br /&gt;
→ Developer API&lt;br /&gt;
→ API Keys&lt;br /&gt;
→ New API Key&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dokumentasi API pada instance tersedia di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:PORT/api/docs&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
API key harus disimpan sebagai rahasia karena siapa pun yang memilikinya dapat mengoperasikan API AnythingLLM. ([AnythingLLM][2])&lt;br /&gt;
&lt;br /&gt;
Set API key:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export ANYTHINGLLM_API_KEY='MASUKKAN_API_KEY_ANDA'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan menyimpan API key langsung di dalam script.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Tentukan konfigurasi&lt;br /&gt;
&lt;br /&gt;
Untuk hanya meng-embed Markdown:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export DOCUMENT_ROOT=&amp;quot;/opt/ai-stack/documents&amp;quot;&lt;br /&gt;
export WORKSPACE_NAME=&amp;quot;Perpustakaan&amp;quot;&lt;br /&gt;
export CONTAINER_NAME=&amp;quot;anythingllm&amp;quot;&lt;br /&gt;
export EMBED_EXTENSIONS=&amp;quot;md&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk Markdown, PDF, DOCX, dan TXT:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export EMBED_EXTENSIONS=&amp;quot;md,pdf,docx,txt&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Saya menyarankan memakai:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export EMBED_EXTENSIONS=&amp;quot;md&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
bila semua PDF sudah dikonversi dan dibersihkan menjadi Markdown untuk RAG. Ini mencegah isi yang sama ter-embed dua kali dari versi PDF dan Markdown.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 5. Pastikan API key bekerja&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl --fail --silent --show-error \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ANYTHINGLLM_API_KEY}&amp;quot; \&lt;br /&gt;
  &amp;quot;${ANYTHINGLLM_URL}/api/v1/auth&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar:&lt;br /&gt;
&lt;br /&gt;
```json&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;authenticated&amp;quot;: true&lt;br /&gt;
}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Jalankan dry-run dahulu&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/ai-stack/batch/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  --dry-run&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dry-run hanya menghitung:&lt;br /&gt;
&lt;br /&gt;
* Jumlah workspace lama.&lt;br /&gt;
* Jumlah dokumen internal lama.&lt;br /&gt;
* Jumlah file sumber yang akan di-embed.&lt;br /&gt;
* Ekstensi yang diproses.&lt;br /&gt;
* Nama workspace baru.&lt;br /&gt;
&lt;br /&gt;
Tidak ada data yang dihapus.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Jalankan reset dan rebuild&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/ai-stack/batch/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  --yes-reset&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika user belum mendapat akses Docker dan direktori backup:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo -E /opt/ai-stack/batch/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  --yes-reset&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Opsi `-E` mempertahankan variabel lingkungan seperti API key dan URL.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Hasil backup&lt;br /&gt;
&lt;br /&gt;
Sebelum menghapus data, script menghentikan container sementara dan membuat backup konsisten:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/backups/anythingllm-storage-YYYYMMDD-HHMMSS.tar.gz&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lh /opt/ai-stack/backups/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
anythingllm-storage-20260726-103000.tar.gz&lt;br /&gt;
anythingllm-rebuild-manifest-20260726-103215.tsv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Manifest berisi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
relative_path    sha256    anythingllm_location&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
AI/RAG/Pengenalan RAG.md    a421...    custom-documents/Pengenalan-RAG.md-uuid.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 9. Pantau proses&lt;br /&gt;
&lt;br /&gt;
Terminal lain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker logs -f anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pantau resource:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker stats anythingllm ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pantau GPU ketika embedding memakai Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
watch -n 1 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Verifikasi setelah selesai&lt;br /&gt;
&lt;br /&gt;
Periksa workspace:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl --fail --silent --show-error \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ANYTHINGLLM_API_KEY}&amp;quot; \&lt;br /&gt;
  &amp;quot;${ANYTHINGLLM_URL}/api/v1/workspaces&amp;quot; \&lt;br /&gt;
  | python3 -m json.tool&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya hanya terdapat satu workspace baru.&lt;br /&gt;
&lt;br /&gt;
Periksa dokumen:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl --fail --silent --show-error \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ANYTHINGLLM_API_KEY}&amp;quot; \&lt;br /&gt;
  &amp;quot;${ANYTHINGLLM_URL}/api/v1/documents&amp;quot; \&lt;br /&gt;
  | python3 -m json.tool&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
AnythingLLM menjelaskan bahwa menghapus dokumen secara permanen dari sistem akan menghapus parsed source, cached embedding, serta mengeluarkannya dari setiap workspace. ([AnythingLLM][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Apakah perlu force restart?&lt;br /&gt;
&lt;br /&gt;
## Pilihan terbaik: reset API + restart normal&lt;br /&gt;
&lt;br /&gt;
Script menggunakan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker restart -t 30 anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ini memberikan waktu sampai 30 detik agar proses berhenti secara normal sebelum Docker mengambil tindakan lanjutan.&lt;br /&gt;
&lt;br /&gt;
**Jangan menggunakan ini kecuali container macet:**&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker kill anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Force restart tidak membersihkan vector database. Ia hanya menghentikan dan menyalakan proses.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Kapan perlu install ulang?&lt;br /&gt;
&lt;br /&gt;
Install ulang atau factory reset hanya diperlukan apabila:&lt;br /&gt;
&lt;br /&gt;
* SQLite AnythingLLM rusak.&lt;br /&gt;
* LanceDB rusak dan API tidak dapat membersihkannya.&lt;br /&gt;
* Container terus crash akibat storage internal.&lt;br /&gt;
* Konfigurasi sistem sudah sangat kacau.&lt;br /&gt;
* Anda benar-benar ingin menghapus user, API key, model settings, MCP, agent skills, chat history, dan seluruh konfigurasi.&lt;br /&gt;
&lt;br /&gt;
Menarik image atau membuat ulang container **tanpa menghapus storage** bukan factory reset karena data tetap persisten. ([AnythingLLM][1])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Factory reset penuh&lt;br /&gt;
&lt;br /&gt;
Ini **bukan pilihan utama**. Perintah berikut menghilangkan seluruh konfigurasi aplikasi, bukan hanya RAG.&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
sudo docker compose stop anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cari lokasi storage:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker inspect anythingllm \&lt;br /&gt;
  --format '{{range .Mounts}}{{println .Source &amp;quot;-&amp;gt;&amp;quot; .Destination}}{{end}}'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Misalnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/anythingllm/storage -&amp;gt; /app/server/storage&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Backup dan ganti nama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mv \&lt;br /&gt;
  /opt/ai-stack/anythingllm/storage \&lt;br /&gt;
  &amp;quot;/opt/ai-stack/anythingllm/storage.factory-reset.$(date +%Y%m%d-%H%M%S)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat storage kosong:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mkdir -p /opt/ai-stack/anythingllm/storage&lt;br /&gt;
sudo chown -R 1000:1000 /opt/ai-stack/anythingllm/storage&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo docker compose up -d anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
AnythingLLM kemudian tampil seperti instalasi pertama. Anda harus mengatur ulang:&lt;br /&gt;
&lt;br /&gt;
* Akun administrator.&lt;br /&gt;
* LLM provider.&lt;br /&gt;
* Embedding provider.&lt;br /&gt;
* Vector database.&lt;br /&gt;
* API key.&lt;br /&gt;
* MCP dan agent skills.&lt;br /&gt;
* Workspace.&lt;br /&gt;
* Dokumen.&lt;br /&gt;
&lt;br /&gt;
Karena tujuan Anda adalah membersihkan workspace dan membangun ulang seluruh embedding, **gunakan script API-reset, bukan factory reset dan bukan install ulang**.&lt;br /&gt;
&lt;br /&gt;
[1]: https://docs.anythingllm.com/installation-docker/local-docker &amp;quot;Local Docker Installation ~ AnythingLLM&amp;quot;&lt;br /&gt;
[2]: https://docs.anythingllm.com/features/api &amp;quot;API Access &amp;amp; Keys ~ AnythingLLM&amp;quot;&lt;br /&gt;
[3]: https://docs.anythingllm.com/features/privacy-and-data-handling &amp;quot;Privacy &amp;amp; Data ~ AnythingLLM&amp;quot;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:54:55 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Reset_dari_nol,_embed_semua_doc,_isi_vector_database</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73726&amp;oldid=73723</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73726&amp;oldid=73723</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:47, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l92&quot; &gt;Line 92:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 92:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Regenerate Vector Database untuk update content documents]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Regenerate Vector Database untuk update content documents]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Reset dari nol, embed semua doc, isi vector database]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:47:25 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>MCP: Regenerate Vector Database untuk update content documents</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73725&amp;oldid=73724</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73725&amp;oldid=73724</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;amp;diff=73725&amp;amp;oldid=73724&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:44:03 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Regenerate_Vector_Database_untuk_update_content_documents</comments>
		</item>
		<item>
			<title>MCP: Regenerate Vector Database untuk update content documents</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73724&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73724&amp;oldid=0</guid>
			<description>&lt;p&gt;Created blank page&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:40:37 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Regenerate_Vector_Database_untuk_update_content_documents</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73723&amp;oldid=73721</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73723&amp;oldid=73721</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:39, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l91&quot; &gt;Line 91:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 91:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Regenerate Vector Database untuk update content documents]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:39:40 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>MCP: Instalasi pip</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi_pip&amp;diff=73722&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi_pip&amp;diff=73722&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Error tersebut berarti Python sudah ada, tetapi modul **pip** belum terpasang. Gunakan virtual environment supaya tidak mengganggu Python sistem Ubuntu. Ubuntu juga merekomend...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Error tersebut berarti Python sudah ada, tetapi modul **pip** belum terpasang. Gunakan virtual environment supaya tidak mengganggu Python sistem Ubuntu. Ubuntu juga merekomendasikan penggunaan `venv` untuk paket yang dipasang melalui pip. ([Ubuntu Documentation][1])&lt;br /&gt;
&lt;br /&gt;
Jalankan sebagai `root`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack/batch&lt;br /&gt;
&lt;br /&gt;
apt update&lt;br /&gt;
apt install -y python3-full python3-venv python3-pip&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat virtual environment:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3 -m venv .venv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Prompt biasanya berubah menjadi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
(.venv) root@server2:/opt/ai-stack/batch#&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan Python sudah memakai virtual environment:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
which python3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/batch/.venv/bin/python3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian instal dependensi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3 -m pip install --upgrade pip&lt;br /&gt;
python3 -m pip install pymupdf pyyaml&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verifikasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3 - &amp;lt;&amp;lt;'PY'&lt;br /&gt;
import pymupdf&lt;br /&gt;
import yaml&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;PyMuPDF berhasil:&amp;quot;, pymupdf.__version__)&lt;br /&gt;
print(&amp;quot;PyYAML berhasil:&amp;quot;, yaml.__version__)&lt;br /&gt;
PY&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah itu jalankan batch converter:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod +x batch_pdf_to_md.sh&lt;br /&gt;
chmod +x pdf_to_rag_md.py&lt;br /&gt;
&lt;br /&gt;
./batch_pdf_to_md.sh /path/folder/pdf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh \&lt;br /&gt;
  /opt/ai-stack/documents \&lt;br /&gt;
  /opt/ai-stack/output&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setiap kali keluar dari terminal atau login ulang, aktifkan kembali environment sebelum menjalankan script:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack/batch&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
./batch_pdf_to_md.sh /opt/ai-stack/documents /opt/ai-stack/output&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan gunakan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
pip install --break-system-packages&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
karena pemasangan langsung ke Python sistem dapat berbenturan dengan paket bawaan Ubuntu.&lt;br /&gt;
&lt;br /&gt;
[1]: https://documentation.ubuntu.com/ubuntu-for-developers/tutorials/python-use/?utm_source=chatgpt.com &amp;quot;Develop with Python on Ubuntu - Ubuntu for Developers&amp;quot;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:04:46 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Instalasi_pip</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73721&amp;oldid=73717</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73721&amp;oldid=73717</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:04, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l90&quot; &gt;Line 90:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 90:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Instalasi pip]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:04:32 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>Batch pdf to md.sh</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Batch_pdf_to_md.sh&amp;diff=73720&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Batch_pdf_to_md.sh&amp;diff=73720&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;&amp;lt;pre&amp;gt;  #!/usr/bin/env bash # Batch wrapper untuk pdf_to_rag_md.py # # Penggunaan: #   ./batch_pdf_to_md.sh /path/folder_pdf #   ./batch_pdf_to_md.sh /path/folder_pdf /path/fol...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
# Batch wrapper untuk pdf_to_rag_md.py&lt;br /&gt;
#&lt;br /&gt;
# Penggunaan:&lt;br /&gt;
#   ./batch_pdf_to_md.sh /path/folder_pdf&lt;br /&gt;
#   ./batch_pdf_to_md.sh /path/folder_pdf /path/folder_output&lt;br /&gt;
#   ./batch_pdf_to_md.sh /path/folder_pdf /path/folder_output /path/pdf_to_rag_md.py&lt;br /&gt;
#&lt;br /&gt;
# Hasil:&lt;br /&gt;
#   OUTPUT_DIR/&amp;lt;path-relatif&amp;gt;/&amp;lt;nama-pdf&amp;gt;/&lt;br /&gt;
#       ├── *.md&lt;br /&gt;
#       └── manifest.json&lt;br /&gt;
&lt;br /&gt;
set -Eeuo pipefail&lt;br /&gt;
IFS=$'\n\t'&lt;br /&gt;
&lt;br /&gt;
PROGRAM_NAME=&amp;quot;$(basename &amp;quot;$0&amp;quot;)&amp;quot;&lt;br /&gt;
SCRIPT_DIR=&amp;quot;$(cd -- &amp;quot;$(dirname -- &amp;quot;${BASH_SOURCE[0]}&amp;quot;)&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
usage() {&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
Penggunaan:&lt;br /&gt;
  $PROGRAM_NAME INPUT_PATH [OUTPUT_DIR] [PYTHON_SCRIPT]&lt;br /&gt;
&lt;br /&gt;
Argumen:&lt;br /&gt;
  INPUT_PATH      Folder yang akan dicari secara rekursif, atau satu file PDF.&lt;br /&gt;
  OUTPUT_DIR      Folder induk hasil konversi.&lt;br /&gt;
                  Default: INPUT_PATH/output untuk input folder,&lt;br /&gt;
                  atau folder_file/output untuk input satu PDF.&lt;br /&gt;
  PYTHON_SCRIPT   Lokasi script Python konverter.&lt;br /&gt;
                  Default: dicari di folder yang sama dengan shell script.&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
  $PROGRAM_NAME /opt/ai-stack/documents&lt;br /&gt;
  $PROGRAM_NAME /opt/ai-stack/documents /opt/ai-stack/output&lt;br /&gt;
  $PROGRAM_NAME ./pdf ./output ./pdf_to_rag_md.py&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
log() {&lt;br /&gt;
    printf '[%s] %s\n' &amp;quot;$(date '+%Y-%m-%d %H:%M:%S')&amp;quot; &amp;quot;$*&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fail() {&lt;br /&gt;
    printf 'ERROR: %s\n' &amp;quot;$*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if [[ ${1:-} == &amp;quot;-h&amp;quot; || ${1:-} == &amp;quot;--help&amp;quot; ]]; then&lt;br /&gt;
    usage&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
[[ $# -ge 1 &amp;amp;&amp;amp; $# -le 3 ]] || {&lt;br /&gt;
    usage &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 2&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
command -v python3 &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || fail &amp;quot;python3 tidak ditemukan.&amp;quot;&lt;br /&gt;
command -v find &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || fail &amp;quot;Perintah find tidak ditemukan.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUT_PATH=&amp;quot;$1&amp;quot;&lt;br /&gt;
[[ -e &amp;quot;$INPUT_PATH&amp;quot; ]] || fail &amp;quot;Path input tidak ditemukan: $INPUT_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Ubah menjadi absolute path tanpa membutuhkan realpath.&lt;br /&gt;
if [[ -d &amp;quot;$INPUT_PATH&amp;quot; ]]; then&lt;br /&gt;
    INPUT_PATH=&amp;quot;$(cd -- &amp;quot;$INPUT_PATH&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
    INPUT_IS_DIR=1&lt;br /&gt;
else&lt;br /&gt;
    INPUT_DIR=&amp;quot;$(cd -- &amp;quot;$(dirname -- &amp;quot;$INPUT_PATH&amp;quot;)&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
    INPUT_PATH=&amp;quot;$INPUT_DIR/$(basename -- &amp;quot;$INPUT_PATH&amp;quot;)&amp;quot;&lt;br /&gt;
    INPUT_IS_DIR=0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [[ $# -ge 2 ]]; then&lt;br /&gt;
    OUTPUT_DIR=&amp;quot;$2&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    if (( INPUT_IS_DIR )); then&lt;br /&gt;
        OUTPUT_DIR=&amp;quot;$INPUT_PATH/output&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        OUTPUT_DIR=&amp;quot;$(dirname -- &amp;quot;$INPUT_PATH&amp;quot;)/output&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
mkdir -p -- &amp;quot;$OUTPUT_DIR&amp;quot;&lt;br /&gt;
OUTPUT_DIR=&amp;quot;$(cd -- &amp;quot;$OUTPUT_DIR&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
[[ &amp;quot;$OUTPUT_DIR&amp;quot; != &amp;quot;$INPUT_PATH&amp;quot; ]] \&lt;br /&gt;
    || fail &amp;quot;OUTPUT_DIR tidak boleh sama persis dengan folder input. Gunakan subfolder, misalnya: $INPUT_PATH/output&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ $# -ge 3 ]]; then&lt;br /&gt;
    PYTHON_SCRIPT=&amp;quot;$3&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    if [[ -f &amp;quot;$SCRIPT_DIR/pdf_to_rag_md.py&amp;quot; ]]; then&lt;br /&gt;
        PYTHON_SCRIPT=&amp;quot;$SCRIPT_DIR/pdf_to_rag_md.py&amp;quot;&lt;br /&gt;
    elif [[ -f &amp;quot;$SCRIPT_DIR/pdf_to_rag_md(2).py&amp;quot; ]]; then&lt;br /&gt;
        PYTHON_SCRIPT=&amp;quot;$SCRIPT_DIR/pdf_to_rag_md(2).py&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        fail &amp;quot;Script Python tidak ditemukan. Letakkan pdf_to_rag_md.py di $SCRIPT_DIR atau berikan argumen PYTHON_SCRIPT.&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
[[ -f &amp;quot;$PYTHON_SCRIPT&amp;quot; ]] || fail &amp;quot;Script Python tidak ditemukan: $PYTHON_SCRIPT&amp;quot;&lt;br /&gt;
PYTHON_SCRIPT=&amp;quot;$(cd -- &amp;quot;$(dirname -- &amp;quot;$PYTHON_SCRIPT&amp;quot;)&amp;quot; &amp;amp;&amp;amp; pwd -P)/$(basename -- &amp;quot;$PYTHON_SCRIPT&amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Pastikan script Python valid dan dependensinya tersedia sebelum batch dimulai.&lt;br /&gt;
python3 -m py_compile &amp;quot;$PYTHON_SCRIPT&amp;quot; \&lt;br /&gt;
    || fail &amp;quot;Script Python gagal diperiksa dengan py_compile.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
python3 - &amp;lt;&amp;lt;'PY' \&lt;br /&gt;
    || fail &amp;quot;Dependensi Python belum lengkap. Instal dengan: python3 -m pip install pymupdf pyyaml&amp;quot;&lt;br /&gt;
try:&lt;br /&gt;
    import pymupdf  # noqa: F401&lt;br /&gt;
except ImportError:&lt;br /&gt;
    import fitz  # noqa: F401&lt;br /&gt;
import yaml  # noqa: F401&lt;br /&gt;
PY&lt;br /&gt;
&lt;br /&gt;
find_input_files() {&lt;br /&gt;
    if [[ &amp;quot;$OUTPUT_DIR&amp;quot; == &amp;quot;$INPUT_PATH/&amp;quot;* ]]; then&lt;br /&gt;
        find &amp;quot;$INPUT_PATH&amp;quot; -path &amp;quot;$OUTPUT_DIR&amp;quot; -prune -o -type f &amp;quot;$@&amp;quot; -print0&lt;br /&gt;
    else&lt;br /&gt;
        find &amp;quot;$INPUT_PATH&amp;quot; -type f &amp;quot;$@&amp;quot; -print0&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
printf '\n=== Daftar semua file pada input ===\n'&lt;br /&gt;
if (( INPUT_IS_DIR )); then&lt;br /&gt;
    while IFS= read -r -d '' file; do&lt;br /&gt;
        printf '%s\n' &amp;quot;$file&amp;quot;&lt;br /&gt;
    done &amp;lt; &amp;lt;(find_input_files | sort -z)&lt;br /&gt;
else&lt;br /&gt;
    printf '%s\n' &amp;quot;$INPUT_PATH&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
printf '=== Akhir daftar file ===\n\n'&lt;br /&gt;
&lt;br /&gt;
PDF_FILES=()&lt;br /&gt;
if (( INPUT_IS_DIR )); then&lt;br /&gt;
    while IFS= read -r -d '' pdf; do&lt;br /&gt;
        PDF_FILES+=(&amp;quot;$pdf&amp;quot;)&lt;br /&gt;
    done &amp;lt; &amp;lt;(find_input_files -iname '*.pdf' | sort -z)&lt;br /&gt;
else&lt;br /&gt;
    [[ &amp;quot;${INPUT_PATH,,}&amp;quot; == *.pdf ]] \&lt;br /&gt;
        || fail &amp;quot;File input bukan PDF: $INPUT_PATH&amp;quot;&lt;br /&gt;
    PDF_FILES+=(&amp;quot;$INPUT_PATH&amp;quot;)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
TOTAL=${#PDF_FILES[@]}&lt;br /&gt;
if (( TOTAL == 0 )); then&lt;br /&gt;
    log &amp;quot;Tidak ada file PDF yang ditemukan.&amp;quot;&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
LOG_FILE=&amp;quot;$OUTPUT_DIR/batch_conversion.log&amp;quot;&lt;br /&gt;
SUMMARY_FILE=&amp;quot;$OUTPUT_DIR/batch_summary.tsv&amp;quot;&lt;br /&gt;
printf 'status\tinput_pdf\toutput_folder\n' &amp;gt; &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
: &amp;gt; &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
log &amp;quot;Ditemukan $TOTAL file PDF.&amp;quot;&lt;br /&gt;
log &amp;quot;Output utama: $OUTPUT_DIR&amp;quot;&lt;br /&gt;
log &amp;quot;Log batch: $LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
SUCCESS=0&lt;br /&gt;
FAILED=0&lt;br /&gt;
INDEX=0&lt;br /&gt;
&lt;br /&gt;
for PDF_FILE in &amp;quot;${PDF_FILES[@]}&amp;quot;; do&lt;br /&gt;
    ((INDEX += 1))&lt;br /&gt;
&lt;br /&gt;
    if (( INPUT_IS_DIR )); then&lt;br /&gt;
        RELATIVE_PATH=&amp;quot;${PDF_FILE#&amp;quot;$INPUT_PATH&amp;quot;/}&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        RELATIVE_PATH=&amp;quot;$(basename -- &amp;quot;$PDF_FILE&amp;quot;)&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    RELATIVE_PARENT=&amp;quot;$(dirname -- &amp;quot;$RELATIVE_PATH&amp;quot;)&amp;quot;&lt;br /&gt;
    PDF_NAME=&amp;quot;$(basename -- &amp;quot;$RELATIVE_PATH&amp;quot;)&amp;quot;&lt;br /&gt;
    PDF_STEM=&amp;quot;${PDF_NAME%.*}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if [[ &amp;quot;$RELATIVE_PARENT&amp;quot; == &amp;quot;.&amp;quot; ]]; then&lt;br /&gt;
        PDF_OUTPUT_DIR=&amp;quot;$OUTPUT_DIR/$PDF_STEM&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        PDF_OUTPUT_DIR=&amp;quot;$OUTPUT_DIR/$RELATIVE_PARENT/$PDF_STEM&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    mkdir -p -- &amp;quot;$PDF_OUTPUT_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    printf '\n[%d/%d] Konversi: %s\n' &amp;quot;$INDEX&amp;quot; &amp;quot;$TOTAL&amp;quot; &amp;quot;$PDF_FILE&amp;quot;&lt;br /&gt;
    printf '        Output   : %s\n' &amp;quot;$PDF_OUTPUT_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    printf '\n===== [%d/%d] %s =====\n' &amp;quot;$INDEX&amp;quot; &amp;quot;$TOTAL&amp;quot; &amp;quot;$PDF_FILE&amp;quot; \&lt;br /&gt;
        | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    set +e&lt;br /&gt;
    python3 &amp;quot;$PYTHON_SCRIPT&amp;quot; \&lt;br /&gt;
        &amp;quot;$PDF_FILE&amp;quot; \&lt;br /&gt;
        --output-dir &amp;quot;$PDF_OUTPUT_DIR&amp;quot; \&lt;br /&gt;
        --overwrite 2&amp;gt;&amp;amp;1 | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
    EXIT_CODE=${PIPESTATUS[0]}&lt;br /&gt;
    set -e&lt;br /&gt;
&lt;br /&gt;
    if (( EXIT_CODE == 0 )); then&lt;br /&gt;
        printf 'SUCCESS\t%s\t%s\n' &amp;quot;$PDF_FILE&amp;quot; &amp;quot;$PDF_OUTPUT_DIR&amp;quot; \&lt;br /&gt;
            &amp;gt;&amp;gt; &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
        ((SUCCESS += 1))&lt;br /&gt;
        log &amp;quot;BERHASIL: $PDF_FILE&amp;quot; | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        printf 'FAILED(%d)\t%s\t%s\n' &amp;quot;$EXIT_CODE&amp;quot; &amp;quot;$PDF_FILE&amp;quot; &amp;quot;$PDF_OUTPUT_DIR&amp;quot; \&lt;br /&gt;
            &amp;gt;&amp;gt; &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
        ((FAILED += 1))&lt;br /&gt;
        log &amp;quot;GAGAL (exit $EXIT_CODE): $PDF_FILE&amp;quot; | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
printf '\n=== Ringkasan batch ===\n'&lt;br /&gt;
printf 'Total PDF : %d\n' &amp;quot;$TOTAL&amp;quot;&lt;br /&gt;
printf 'Berhasil  : %d\n' &amp;quot;$SUCCESS&amp;quot;&lt;br /&gt;
printf 'Gagal     : %d\n' &amp;quot;$FAILED&amp;quot;&lt;br /&gt;
printf 'Output    : %s\n' &amp;quot;$OUTPUT_DIR&amp;quot;&lt;br /&gt;
printf 'Ringkasan : %s\n' &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
printf 'Log       : %s\n' &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(( FAILED == 0 ))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:47:44 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Batch_pdf_to_md.sh</comments>
		</item>
		<item>
			<title>MCP: Convert PDF ke .md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73719&amp;oldid=73718</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73719&amp;oldid=73718</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 01:45, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l4&quot; &gt;Line 4:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 4:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download shell script]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/&lt;/del&gt;batch_pdf_to_md.sh&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download shell script]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[[&lt;/ins&gt;batch_pdf_to_md.sh&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download Python script dengan nama sederhana]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/&lt;/del&gt;pdf_to_rag_md.py&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download Python script dengan nama sederhana]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[[&lt;/ins&gt;pdf_to_rag_md.py&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;### Instalasi&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;### Instalasi&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:45:10 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Convert_PDF_ke_.md</comments>
		</item>
		<item>
			<title>MCP: Convert PDF ke .md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73718&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73718&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Shell script sudah dibuat berdasarkan opsi CLI pada Python terlampir.   ### File  * [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip) * [Download shell s...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Shell script sudah dibuat berdasarkan opsi CLI pada Python terlampir. &lt;br /&gt;
&lt;br /&gt;
### File&lt;br /&gt;
&lt;br /&gt;
* [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip)&lt;br /&gt;
* [Download shell script](sandbox:/mnt/data/batch_pdf_to_md.sh)&lt;br /&gt;
* [Download Python script dengan nama sederhana](sandbox:/mnt/data/pdf_to_rag_md.py)&lt;br /&gt;
&lt;br /&gt;
### Instalasi&lt;br /&gt;
&lt;br /&gt;
Letakkan `batch_pdf_to_md.sh` dan `pdf_to_rag_md.py` dalam folder yang sama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod +x batch_pdf_to_md.sh&lt;br /&gt;
chmod +x pdf_to_rag_md.py&lt;br /&gt;
&lt;br /&gt;
python3 -m pip install pymupdf pyyaml&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### Menjalankan&lt;br /&gt;
&lt;br /&gt;
Output otomatis ditempatkan di subfolder `output`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh /opt/ai-stack/documents&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dengan folder output khusus:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh \&lt;br /&gt;
  /opt/ai-stack/documents \&lt;br /&gt;
  /opt/ai-stack/output&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atau menentukan lokasi Python script secara eksplisit:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh \&lt;br /&gt;
  /opt/ai-stack/documents \&lt;br /&gt;
  /opt/ai-stack/output \&lt;br /&gt;
  /opt/scripts/pdf_to_rag_md.py&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Script akan:&lt;br /&gt;
&lt;br /&gt;
1. Menampilkan semua file dalam path input.&lt;br /&gt;
2. Mencari seluruh PDF secara rekursif, termasuk subfolder.&lt;br /&gt;
3. Menjalankan Python converter untuk setiap PDF.&lt;br /&gt;
4. Membuat folder output terpisah untuk setiap PDF agar `manifest.json` tidak saling menimpa.&lt;br /&gt;
5. Membuat `batch_conversion.log`.&lt;br /&gt;
6. Membuat `batch_summary.tsv` berisi status berhasil atau gagal.&lt;br /&gt;
&lt;br /&gt;
Contoh hasil:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/output/&lt;br /&gt;
├── Buku Pertama/&lt;br /&gt;
│   ├── Buku Pertama 01 Topik.md&lt;br /&gt;
│   ├── Buku Pertama 02 Topik.md&lt;br /&gt;
│   └── manifest.json&lt;br /&gt;
├── AI/&lt;br /&gt;
│   └── Buku Kedua/&lt;br /&gt;
│       ├── Buku Kedua 01 Topik.md&lt;br /&gt;
│       └── manifest.json&lt;br /&gt;
├── batch_conversion.log&lt;br /&gt;
└── batch_summary.tsv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Shell script tersebut sudah diuji dengan beberapa PDF, nama file yang mengandung spasi, dan PDF di dalam subfolder.&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:44:24 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Convert_PDF_ke_.md</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73717&amp;oldid=73709</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73717&amp;oldid=73709</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 01:44, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l89&quot; &gt;Line 89:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 89:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Convert PDF ke .md]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:44:11 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>Pdf to rag md.py</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Pdf_to_rag_md.py&amp;diff=73716&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Pdf_to_rag_md.py&amp;diff=73716&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;&amp;lt;pre&amp;gt; #!/usr/bin/env python3 &amp;quot;&amp;quot;&amp;quot; Convert a text-based PDF into RAG-friendly Markdown files, one file per topic.  Main features ------------- - Uses the PDF table of contents w...&amp;quot;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=Pdf_to_rag_md.py&amp;amp;diff=73716&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Fri, 24 Jul 2026 21:03:25 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Pdf_to_rag_md.py</comments>
		</item>
		<item>
			<title>Requirements-pdf-to-rag-md.txt</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Requirements-pdf-to-rag-md.txt&amp;diff=73715&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Requirements-pdf-to-rag-md.txt&amp;diff=73715&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot; pymupdf&amp;gt;=1.26,&amp;lt;2  pyyaml&amp;gt;=6,&amp;lt;7&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt; pymupdf&amp;gt;=1.26,&amp;lt;2&lt;br /&gt;
 pyyaml&amp;gt;=6,&amp;lt;7&lt;/div&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:57:25 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Requirements-pdf-to-rag-md.txt</comments>
		</item>
		<item>
			<title>RAG: PDF to md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73714&amp;oldid=73712</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73714&amp;oldid=73712</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 20:56, 24 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-multi&quot; lang=&quot;en&quot;&gt;(One intermediate revision by the same user not shown)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot; &gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;## File Python&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;## File Python&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Unduh `&lt;/del&gt;pdf_to_rag_md.py&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;`&lt;/del&gt;]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/pdf_to_rag_md.py)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[&lt;/ins&gt;pdf_to_rag_md.py]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Unduh `&lt;/del&gt;requirements-pdf-to-rag-md.txt&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;`&lt;/del&gt;]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/requirements-pdf-to-rag-md.txt)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[&lt;/ins&gt;requirements-pdf-to-rag-md.txt]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Skrip sudah diperiksa dengan `py_compile` dan diuji pada:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Skrip sudah diperiksa dengan `py_compile` dan diuji pada:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:56:52 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:RAG:_PDF_to_md</comments>
		</item>
		<item>
			<title>RAG: PDF to md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73712&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73712&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;## File Python  * [Unduh `pdf_to_rag_md.py`](sandbox:/mnt/data/pdf_to_rag_md.py) * [Unduh `requirements-pdf-to-rag-md.txt`](sandbox:/mnt/data/requirements-pdf-to-rag-md.txt)...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;## File Python&lt;br /&gt;
&lt;br /&gt;
* [Unduh `pdf_to_rag_md.py`](sandbox:/mnt/data/pdf_to_rag_md.py)&lt;br /&gt;
* [Unduh `requirements-pdf-to-rag-md.txt`](sandbox:/mnt/data/requirements-pdf-to-rag-md.txt)&lt;br /&gt;
&lt;br /&gt;
Skrip sudah diperiksa dengan `py_compile` dan diuji pada:&lt;br /&gt;
&lt;br /&gt;
* PDF dengan bookmark dan struktur heading.&lt;br /&gt;
* PDF tanpa heading, menggunakan fallback setiap lima halaman.&lt;br /&gt;
&lt;br /&gt;
## Instalasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p ~/Apps/pdf-to-rag&lt;br /&gt;
cd ~/Apps/pdf-to-rag&lt;br /&gt;
&lt;br /&gt;
python3 -m venv .venv&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
pip install --upgrade pip&lt;br /&gt;
pip install -r requirements-pdf-to-rag-md.txt&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Menjalankan&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menentukan folder output:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot; \&lt;br /&gt;
    --output-dir hasil-rag&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menambahkan tag metadata:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot; \&lt;br /&gt;
    --tags &amp;quot;RAG,AI,LLM,dokumentasi&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika folder output sudah ada:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot; \&lt;br /&gt;
    --overwrite&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Format filename&lt;br /&gt;
&lt;br /&gt;
Untuk PDF yang memiliki heading:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Judul Buku 01 BAB 1 Pendahuluan.md&lt;br /&gt;
Judul Buku 02 1.1 Latar Belakang.md&lt;br /&gt;
Judul Buku 03 1.2 Tujuan.md&lt;br /&gt;
Judul Buku 04 BAB 2 Metode.md&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika PDF tidak memiliki heading, otomatis fallback per lima halaman:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Judul Buku 01 Bagian Halaman 1-5.md&lt;br /&gt;
Judul Buku 02 Bagian Halaman 6-10.md&lt;br /&gt;
Judul Buku 03 Bagian Halaman 11-15.md&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Judul buku diambil secara berurutan dari:&lt;br /&gt;
&lt;br /&gt;
1. Metadata title PDF.&lt;br /&gt;
2. Teks judul dengan font terbesar pada halaman awal.&lt;br /&gt;
3. Nama file PDF.&lt;br /&gt;
&lt;br /&gt;
## Konten yang dibuang&lt;br /&gt;
&lt;br /&gt;
Secara default, skrip membuang:&lt;br /&gt;
&lt;br /&gt;
* Gambar dan blok nonteks.&lt;br /&gt;
* Caption `Gambar`, `Figure`, atau `Fig`.&lt;br /&gt;
* Baris `Sumber:` dan `Source:` pada caption.&lt;br /&gt;
* Nomor halaman.&lt;br /&gt;
* Header dan footer berulang.&lt;br /&gt;
* Footnote yang terdeteksi di bagian bawah halaman.&lt;br /&gt;
* Daftar isi.&lt;br /&gt;
* Daftar gambar dan daftar tabel.&lt;br /&gt;
* Daftar istilah dan glosarium.&lt;br /&gt;
* Daftar singkatan, simbol, dan nomenklatur.&lt;br /&gt;
* Indeks.&lt;br /&gt;
* Daftar pustaka, bibliography, dan references.&lt;br /&gt;
* Kata pengantar, prakata, dan foreword.&lt;br /&gt;
* Ucapan terima kasih.&lt;br /&gt;
* Tentang penulis.&lt;br /&gt;
* Halaman sampul dan copyright yang terdeteksi.&lt;br /&gt;
* Karakter tersembunyi, soft hyphen, dan spasi berlebihan.&lt;br /&gt;
&lt;br /&gt;
## Metadata pada setiap file Markdown&lt;br /&gt;
&lt;br /&gt;
Setiap file memiliki YAML front matter seperti:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
---&lt;br /&gt;
schema_version: '1.0'&lt;br /&gt;
document_id: pdf-914f553ce7c36f8704e4&lt;br /&gt;
topic_id: pdf-914f553ce7c36f8704e4-topic-0001&lt;br /&gt;
chunk_id: pdf-914f553ce7c36f8704e4-topic-0001&lt;br /&gt;
&lt;br /&gt;
book_title: Buku Uji RAG&lt;br /&gt;
title: BAB 1 Pendahuluan&lt;br /&gt;
topic: BAB 1 Pendahuluan&lt;br /&gt;
topic_index: 1&lt;br /&gt;
&lt;br /&gt;
language: id&lt;br /&gt;
tags:&lt;br /&gt;
  - RAG&lt;br /&gt;
  - AI&lt;br /&gt;
&lt;br /&gt;
source:&lt;br /&gt;
  file: Buku Uji RAG.pdf&lt;br /&gt;
  sha256: 914f553ce7c36f8704e412b1fcb51b90&lt;br /&gt;
  page_start: 3&lt;br /&gt;
  page_end: 8&lt;br /&gt;
  pages:&lt;br /&gt;
    - 3&lt;br /&gt;
    - 4&lt;br /&gt;
    - 5&lt;br /&gt;
    - 6&lt;br /&gt;
    - 7&lt;br /&gt;
    - 8&lt;br /&gt;
  trace: Buku Uji RAG.pdf#page=3-8&lt;br /&gt;
  pdf_title: Buku Uji RAG&lt;br /&gt;
  pdf_author: Nama Penulis&lt;br /&gt;
&lt;br /&gt;
rag:&lt;br /&gt;
  unit: topic&lt;br /&gt;
  filename_pattern: Judul Buku 00 Topik.md&lt;br /&gt;
  topic_detection: pdf_toc&lt;br /&gt;
  word_count: 1450&lt;br /&gt;
  character_count: 9860&lt;br /&gt;
  content_sha256: 76a95b85fe3c9e48882c351138aa5f86&lt;br /&gt;
  suggested_splitter: markdown_headers_then_token_window&lt;br /&gt;
&lt;br /&gt;
extraction:&lt;br /&gt;
  engine: PyMuPDF&lt;br /&gt;
  images: ignored&lt;br /&gt;
  figure_captions: removed&lt;br /&gt;
  junk_sections: removed&lt;br /&gt;
  standalone_page_number_filter: enabled&lt;br /&gt;
  footnote_filter: bottom_position_and_small_font&lt;br /&gt;
&lt;br /&gt;
output_file: Buku Uji RAG 01 BAB 1 Pendahuluan.md&lt;br /&gt;
generated_at: '2026-07-25T03:00:00+00:00'&lt;br /&gt;
---&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Skrip juga menghasilkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
manifest.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Manifest berisi daftar semua topik, filename, rentang halaman, metode pendeteksian topik, hash dokumen, dan halaman nonkonten yang dibuang.&lt;br /&gt;
&lt;br /&gt;
PDF hasil scan yang tidak memiliki selectable text harus menjalani OCR terlebih dahulu.&lt;/div&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:54:35 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:RAG:_PDF_to_md</comments>
		</item>
		<item>
			<title>RAG</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=RAG&amp;diff=73711&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=RAG&amp;diff=73711&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;   ==Pranala Menarik==  * &lt;a href=&quot;/wiki/index.php/RAG:_PDF_to_md&quot; title=&quot;RAG: PDF to md&quot;&gt;RAG: PDF to md&lt;/a&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Pranala Menarik==&lt;br /&gt;
&lt;br /&gt;
* [[RAG: PDF to md]]&lt;/div&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:53:52 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:RAG</comments>
		</item>
		<item>
			<title>MCP: Instalasi</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi&amp;diff=73710&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi&amp;diff=73710&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# PANDUAN INSTALASI LOCAL AI STACK BERBASIS DOCKER  ## Ollama + Open WebUI + AnythingLLM + MCP + n8n  **Perangkat:**  ```text Laptop       : Dell RAM          : 16 GB GPU...&amp;quot;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi&amp;amp;diff=73710&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Fri, 24 Jul 2026 09:56:10 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Instalasi</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73709&amp;oldid=73706</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73709&amp;oldid=73706</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ComfyUI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 03:47, 24 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l85&quot; &gt;Line 85:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 85:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Text to Speech]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Text to Speech]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==MCP==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Instalasi]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Fri, 24 Jul 2026 03:47:33 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>ComfyUI: Text to Speech</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73708&amp;oldid=73707</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73708&amp;oldid=73707</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;amp;diff=73708&amp;amp;oldid=73707&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Fri, 24 Jul 2026 02:38:57 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Text_to_Speech</comments>
		</item>
		<item>
			<title>ComfyUI: Text to Speech</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73707&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73707&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Saya sudah membuat workflow **Text-to-Speech Bahasa Indonesia** paling sederhana:  [Download workflow JSON ComfyUI TTS Indonesia](sandbox:/mnt/data/comfyui_tts_bahasa_indonesi...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Saya sudah membuat workflow **Text-to-Speech Bahasa Indonesia** paling sederhana:&lt;br /&gt;
&lt;br /&gt;
[Download workflow JSON ComfyUI TTS Indonesia](sandbox:/mnt/data/comfyui_tts_bahasa_indonesia_sederhana.json)&lt;br /&gt;
&lt;br /&gt;
Workflow hanya menggunakan dua node:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Edge TTS → Save Audio&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Node menggunakan suara perempuan Indonesia **Gadis**, kecepatan normal, dan menyimpan hasil sebagai WAV. Custom node tersebut juga menyediakan suara laki-laki Indonesia **Ardi**, serta pengaturan kecepatan dan tinggi nada. ([GitHub][1])&lt;br /&gt;
&lt;br /&gt;
## 1. Instal custom node&lt;br /&gt;
&lt;br /&gt;
Pada server:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose exec -u root comfyui bash -lc '&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
cd /opt/ComfyUI/custom_nodes&lt;br /&gt;
&lt;br /&gt;
if [ ! -d ComfyUI-EdgeTTS ]; then&lt;br /&gt;
    git clone https://github.com/1038lab/ComfyUI-EdgeTTS.git&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
python -m pip install --no-cache-dir \&lt;br /&gt;
    -r ComfyUI-EdgeTTS/requirements.txt&lt;br /&gt;
'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Repositori resminya memang mengarahkan instalasi ke folder `custom_nodes`, dilanjutkan dengan pemasangan `requirements.txt`. ([GitHub][2])&lt;br /&gt;
&lt;br /&gt;
Periksa apakah berhasil:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cari apakah node berikut berhasil dimuat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
EdgeTTS&lt;br /&gt;
Save_Audio&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 2. Upload workflow&lt;br /&gt;
&lt;br /&gt;
Buka:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.230:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian seret file berikut ke canvas ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui_tts_bahasa_indonesia_sederhana.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Workflow JSON merupakan format resmi untuk menyimpan graph, node, widget, dan hubungan antar-node ComfyUI. ([ComfyUI][3])&lt;br /&gt;
&lt;br /&gt;
## 3. Jalankan TTS&lt;br /&gt;
&lt;br /&gt;
Pada node **Edge TTS**, ubah teks:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Halo, selamat datang. Ini adalah contoh text to speech sederhana dalam Bahasa Indonesia menggunakan ComfyUI.&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Suara default:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
[Indonesian] id-ID Gadis&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk suara laki-laki, pilih:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
[Indonesian] id-ID Ardi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lalu tekan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ctrl + Enter&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
atau klik **Queue**.&lt;br /&gt;
&lt;br /&gt;
## 4. Lokasi hasil&lt;br /&gt;
&lt;br /&gt;
File akan tersimpan sebagai:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ComfyUI/output/TTS/indonesia-0001.wav&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Nomor akan bertambah otomatis:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
indonesia-0002.wav&lt;br /&gt;
indonesia-0003.wav&lt;br /&gt;
indonesia-0004.wav&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Node `Save_Audio` memang menyimpan keluaran di direktori output ComfyUI dan memberikan nomor urut ketika opsi overwrite dimatikan. ([GitHub][4])&lt;br /&gt;
&lt;br /&gt;
**Catatan:** workflow ini menggunakan layanan Microsoft Edge TTS secara online, sehingga container ComfyUI memerlukan akses internet ketika menghasilkan suara. Tidak memerlukan API key. ([GitHub][5])&lt;br /&gt;
&lt;br /&gt;
[1]: https://github.com/1038lab/ComfyUI-EdgeTTS/blob/main/ailab_edgeTTS.py &amp;quot;ComfyUI-EdgeTTS/ailab_edgeTTS.py at main · 1038lab/ComfyUI-EdgeTTS · GitHub&amp;quot;&lt;br /&gt;
[2]: https://github.com/1038lab/ComfyUI-EdgeTTS &amp;quot;GitHub - 1038lab/ComfyUI-EdgeTTS: ComfyUI-EdgeTTS is a powerful text-to-speech node for ComfyUI, leveraging Microsoft's Edge TTS capabilities. It enables seamless conversion of text into natural-sounding speech, supporting multiple languages and voices. Ideal for enhancing user interactions, this node is easy to integrate and customize, making it perfect for various applications. · GitHub&amp;quot;&lt;br /&gt;
[3]: https://docs.comfy.org/specs/workflow_json_0.4?utm_source=chatgpt.com &amp;quot;Workflow JSON 0.4 - ComfyUI&amp;quot;&lt;br /&gt;
[4]: https://github.com/1038lab/ComfyUI-EdgeTTS/blob/main/ailab_audio.py &amp;quot;ComfyUI-EdgeTTS/ailab_audio.py at main · 1038lab/ComfyUI-EdgeTTS · GitHub&amp;quot;&lt;br /&gt;
[5]: https://github.com/rany2/edge-tts?utm_source=chatgpt.com &amp;quot;GitHub - rany2/edge-tts: Use Microsoft Edge's online text-to-speech service from Python WITHOUT needing Microsoft Edge or Windows or an API key · GitHub&amp;quot;&lt;/div&gt;</description>
			<pubDate>Thu, 23 Jul 2026 23:43:35 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Text_to_Speech</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73706&amp;oldid=73704</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73706&amp;oldid=73704</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ComfyUI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 23:43, 23 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l84&quot; &gt;Line 84:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 84:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[ComfyUI: Text to Speech]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Thu, 23 Jul 2026 23:43:30 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + ComfyUI docker</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM:_Ubuntu_26.04_server_Ollama_GPU_%2B_Open-WebUI_%2B_n8n_%2B_WAHA_%2B_ComfyUI_docker&amp;diff=73705&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM:_Ubuntu_26.04_server_Ollama_GPU_%2B_Open-WebUI_%2B_n8n_%2B_WAHA_%2B_ComfyUI_docker&amp;diff=73705&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# Instalasi AI Stack di Ubuntu Server 26.04  Target perangkat:  * Laptop Dell * NVIDIA GeForce RTX 4060 Laptop GPU 8 GB * Ubuntu Server 26.04 * Docker Engine + Docker Compose...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# Instalasi AI Stack di Ubuntu Server 26.04&lt;br /&gt;
&lt;br /&gt;
Target perangkat:&lt;br /&gt;
&lt;br /&gt;
* Laptop Dell&lt;br /&gt;
* NVIDIA GeForce RTX 4060 Laptop GPU 8 GB&lt;br /&gt;
* Ubuntu Server 26.04&lt;br /&gt;
* Docker Engine + Docker Compose&lt;br /&gt;
* Ollama memakai GPU&lt;br /&gt;
* ComfyUI memakai GPU&lt;br /&gt;
* Open WebUI **tanpa GPU**&lt;br /&gt;
* n8n tanpa GPU&lt;br /&gt;
* WAHA tanpa GPU&lt;br /&gt;
&lt;br /&gt;
Karena bagian “gunakan folder awal …” belum lengkap, panduan ini memakai:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Docker secara resmi sudah mencantumkan Ubuntu 26.04 LTS sebagai sistem yang didukung. ([Docker Documentation][1])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 1. Arsitektur akhir&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/&lt;br /&gt;
├── .env&lt;br /&gt;
├── compose.yaml&lt;br /&gt;
├── ollama/&lt;br /&gt;
├── open-webui/&lt;br /&gt;
├── n8n/&lt;br /&gt;
├── waha/&lt;br /&gt;
│   ├── .env&lt;br /&gt;
│   ├── sessions/&lt;br /&gt;
│   └── media/&lt;br /&gt;
└── comfyui/&lt;br /&gt;
    ├── Dockerfile&lt;br /&gt;
    ├── models/&lt;br /&gt;
    │   ├── checkpoints/&lt;br /&gt;
    │   ├── vae/&lt;br /&gt;
    │   ├── loras/&lt;br /&gt;
    │   ├── clip/&lt;br /&gt;
    │   ├── controlnet/&lt;br /&gt;
    │   └── upscale_models/&lt;br /&gt;
    ├── input/&lt;br /&gt;
    ├── output/&lt;br /&gt;
    ├── custom_nodes/&lt;br /&gt;
    └── user/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Port yang digunakan:&lt;br /&gt;
&lt;br /&gt;
| Aplikasi   |  Port | Alamat                              |&lt;br /&gt;
| ---------- | ----: | ----------------------------------- |&lt;br /&gt;
| Open WebUI |  3000 | `http://IP-SERVER:3000`             |&lt;br /&gt;
| n8n        |  5678 | `http://IP-SERVER:5678`             |&lt;br /&gt;
| WAHA       |  3001 | `http://IP-SERVER:3001/dashboard`   |&lt;br /&gt;
| ComfyUI    |  8188 | `http://IP-SERVER:8188`             |&lt;br /&gt;
| Ollama     | 11434 | Hanya localhost dan jaringan Docker |&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN A — PERSIAPAN UBUNTU&lt;br /&gt;
&lt;br /&gt;
## 2. Update Ubuntu Server&lt;br /&gt;
&lt;br /&gt;
Masuk melalui terminal atau SSH, kemudian jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt full-upgrade -y&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Instal paket dasar:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y \&lt;br /&gt;
  ca-certificates \&lt;br /&gt;
  curl \&lt;br /&gt;
  gnupg \&lt;br /&gt;
  git \&lt;br /&gt;
  openssl \&lt;br /&gt;
  ubuntu-drivers-common \&lt;br /&gt;
  ufw&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Reboot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo reboot&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah server hidup kembali, login lagi melalui SSH.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN B — DRIVER NVIDIA RTX 4060&lt;br /&gt;
&lt;br /&gt;
## 3. Pastikan GPU terdeteksi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
lspci | grep -i nvidia&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh hasil:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NVIDIA Corporation AD107M [GeForce RTX 4060 Max-Q / Mobile]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat driver yang tersedia:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ubuntu-drivers list --gpgpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk server AI/headless, instal driver komputasi yang direkomendasikan otomatis:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ubuntu-drivers install --gpgpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ubuntu merekomendasikan `ubuntu-drivers` karena alat ini memilih paket driver yang sesuai dan mendukung penggunaan Secure Boot melalui modul yang ditandatangani. ([Ubuntu][2])&lt;br /&gt;
&lt;br /&gt;
Reboot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo reboot&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Periksa driver NVIDIA&lt;br /&gt;
&lt;br /&gt;
Setelah login kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar kurang lebih seperti:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NVIDIA-SMI ...&lt;br /&gt;
Driver Version: ...&lt;br /&gt;
CUDA Version: ...&lt;br /&gt;
NVIDIA GeForce RTX 4060 Laptop GPU&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan lanjut ke instalasi Docker GPU sebelum `nvidia-smi` berhasil.&lt;br /&gt;
&lt;br /&gt;
Apabila muncul:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa Secure Boot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mokutil --sb-state&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pada beberapa laptop, Secure Boot harus dinonaktifkan melalui BIOS atau kunci MOK driver harus dikonfirmasi ketika boot.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN C — INSTALASI DOCKER&lt;br /&gt;
&lt;br /&gt;
## 5. Hapus paket Docker lama yang mungkin konflik&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
for pkg in \&lt;br /&gt;
  docker.io \&lt;br /&gt;
  docker-doc \&lt;br /&gt;
  docker-compose \&lt;br /&gt;
  docker-compose-v2 \&lt;br /&gt;
  podman-docker \&lt;br /&gt;
  containerd \&lt;br /&gt;
  runc&lt;br /&gt;
do&lt;br /&gt;
  sudo apt remove -y &amp;quot;$pkg&amp;quot; 2&amp;gt;/dev/null || true&lt;br /&gt;
done&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Docker menyarankan menghapus paket distribusi yang dapat bertabrakan dengan Docker Engine resmi. ([Docker Documentation][1])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Tambahkan repository resmi Docker&lt;br /&gt;
&lt;br /&gt;
Buat direktori keyring:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ambil kunci resmi Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo curl -fsSL \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur agar kunci dapat dibaca APT:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tambahkan repository Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;gt;/dev/null &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Update repository:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Instal Docker Engine dan Docker Compose&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y \&lt;br /&gt;
  docker-ce \&lt;br /&gt;
  docker-ce-cli \&lt;br /&gt;
  containerd.io \&lt;br /&gt;
  docker-buildx-plugin \&lt;br /&gt;
  docker-compose-plugin&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan Docker saat boot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl enable --now docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa status:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl status docker --no-pager&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo docker run --rm hello-world&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Izinkan user menjalankan Docker tanpa sudo&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo usermod -aG docker &amp;quot;$USER&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Arti opsi:&lt;br /&gt;
&lt;br /&gt;
* `-a` berarti menambahkan user tanpa menghapus grup yang sudah dimiliki.&lt;br /&gt;
* `-G docker` berarti menambahkan user ke grup Docker.&lt;br /&gt;
&lt;br /&gt;
Logout dari SSH:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
exit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Login kembali, kemudian periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker version&lt;br /&gt;
docker compose version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji kembali tanpa `sudo`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm hello-world&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN D — NVIDIA CONTAINER TOOLKIT&lt;br /&gt;
&lt;br /&gt;
## 9. Tambahkan repository NVIDIA Container Toolkit&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \&lt;br /&gt;
  | sudo gpg --dearmor \&lt;br /&gt;
  -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tambahkan repository:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -fsSL \&lt;br /&gt;
  https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \&lt;br /&gt;
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \&lt;br /&gt;
  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Update APT:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Instal NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasikan Docker agar mengenali NVIDIA Runtime:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Restart Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Langkah tersebut mengikuti prosedur NVIDIA untuk mengaktifkan GPU di dalam container Docker. ([NVIDIA Docs][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Uji GPU dari dalam Docker&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm --gpus all ubuntu:24.04 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan RTX 4060 muncul di hasil perintah.&lt;br /&gt;
&lt;br /&gt;
Ollama juga menyarankan pengujian GPU Docker sebelum mencoba menjalankan model. Ollama membutuhkan NVIDIA Container Toolkit untuk akselerasi NVIDIA di Docker. ([Ollama][4])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN E — MEMBUAT STRUKTUR FOLDER&lt;br /&gt;
&lt;br /&gt;
## 11. Buat folder utama&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mkdir -p /opt/ai-stack&lt;br /&gt;
sudo chown -R &amp;quot;$USER&amp;quot;:&amp;quot;$USER&amp;quot; /opt/ai-stack&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat folder data:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p \&lt;br /&gt;
  ollama \&lt;br /&gt;
  open-webui \&lt;br /&gt;
  n8n \&lt;br /&gt;
  waha/sessions \&lt;br /&gt;
  waha/media \&lt;br /&gt;
  comfyui/input \&lt;br /&gt;
  comfyui/output \&lt;br /&gt;
  comfyui/custom_nodes \&lt;br /&gt;
  comfyui/user&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat folder model ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p \&lt;br /&gt;
  comfyui/models/checkpoints \&lt;br /&gt;
  comfyui/models/vae \&lt;br /&gt;
  comfyui/models/loras \&lt;br /&gt;
  comfyui/models/clip \&lt;br /&gt;
  comfyui/models/controlnet \&lt;br /&gt;
  comfyui/models/upscale_models&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur kepemilikan folder n8n. Container resmi n8n berjalan dengan UID `1000`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chown -R 1000:1000 /opt/ai-stack/n8n&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat struktur:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
find /opt/ai-stack -maxdepth 3 -type d | sort&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN F — KONFIGURASI RAHASIA&lt;br /&gt;
&lt;br /&gt;
## 12. Cari IP server&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
SERVER_IP=$(ip route get 1.1.1.1 | awk '{print $7; exit}')&lt;br /&gt;
echo &amp;quot;$SERVER_IP&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa juga dengan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
hostname -I&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila ada beberapa IP, gunakan IP LAN yang dipakai komputer lain untuk mengakses server.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 13. Buat file `.env` utama&lt;br /&gt;
&lt;br /&gt;
Pastikan sedang di:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat konfigurasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
SERVER_IP=$(ip route get 1.1.1.1 | awk '{print $7; exit}')&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; .env &amp;lt;&amp;lt;EOF&lt;br /&gt;
SERVER_IP=${SERVER_IP}&lt;br /&gt;
WEBUI_SECRET_KEY=$(openssl rand -hex 32)&lt;br /&gt;
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Amankan file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod 600 .env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat .env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
SERVER_IP=192.168.0.100&lt;br /&gt;
WEBUI_SECRET_KEY=...&lt;br /&gt;
N8N_ENCRYPTION_KEY=...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN G — KONFIGURASI WAHA&lt;br /&gt;
&lt;br /&gt;
## 14. Generate konfigurasi WAHA&lt;br /&gt;
&lt;br /&gt;
WAHA menyediakan perintah `init-waha` untuk membuat username, password dashboard, dan API key secara acak. ([GitHub][5])&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
docker run --rm \&lt;br /&gt;
  -v &amp;quot;$PWD/waha:/app/env&amp;quot; \&lt;br /&gt;
  devlikeapro/waha:latest \&lt;br /&gt;
  init-waha /app/env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Biasanya terdapat variabel seperti:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
WAHA_API_KEY=...&lt;br /&gt;
WAHA_DASHBOARD_USERNAME=...&lt;br /&gt;
WAHA_DASHBOARD_PASSWORD=...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Amankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod 600 waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur alamat eksternal WAHA agar menggunakan port host `3001`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
SERVER_IP=$(grep '^SERVER_IP=' .env | cut -d= -f2)&lt;br /&gt;
&lt;br /&gt;
if grep -q '^WAHA_BASE_URL=' waha/.env; then&lt;br /&gt;
  sed -i \&lt;br /&gt;
    &amp;quot;s#^WAHA_BASE_URL=.*#WAHA_BASE_URL=http://${SERVER_IP}:3001#&amp;quot; \&lt;br /&gt;
    waha/.env&lt;br /&gt;
else&lt;br /&gt;
  echo &amp;quot;WAHA_BASE_URL=http://${SERVER_IP}:3001&amp;quot; &amp;gt;&amp;gt; waha/.env&lt;br /&gt;
fi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
grep -E 'WAHA_BASE_URL|WAHA_DASHBOARD_USERNAME|WAHA_API_KEY' waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
WAHA menyimpan sesi pada `/app/.sessions` dan media pada `/app/.media`; kedua lokasi ini akan dipetakan ke folder host agar tidak hilang saat container dibuat ulang. ([GitHub][6])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN H — DOCKERFILE COMFYUI&lt;br /&gt;
&lt;br /&gt;
## 15. Buat Dockerfile ComfyUI&lt;br /&gt;
&lt;br /&gt;
Panduan ini membangun image dari repository resmi ComfyUI dan memasang PyTorch CUDA. Repository resmi ComfyUI berada di organisasi Comfy-Org. ([GitHub][7])&lt;br /&gt;
&lt;br /&gt;
Buat file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; comfyui/Dockerfile &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
FROM nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04&lt;br /&gt;
&lt;br /&gt;
ENV DEBIAN_FRONTEND=noninteractive&lt;br /&gt;
ENV PIP_NO_CACHE_DIR=1&lt;br /&gt;
ENV PYTHONUNBUFFERED=1&lt;br /&gt;
ENV PATH=&amp;quot;/opt/venv/bin:${PATH}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends \&lt;br /&gt;
    ca-certificates \&lt;br /&gt;
    git \&lt;br /&gt;
    curl \&lt;br /&gt;
    ffmpeg \&lt;br /&gt;
    build-essential \&lt;br /&gt;
    python3 \&lt;br /&gt;
    python3-dev \&lt;br /&gt;
    python3-pip \&lt;br /&gt;
    python3-venv \&lt;br /&gt;
    libgl1 \&lt;br /&gt;
    libglib2.0-0 \&lt;br /&gt;
    libsm6 \&lt;br /&gt;
    libxext6 \&lt;br /&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;br /&gt;
&lt;br /&gt;
RUN python3 -m venv /opt/venv \&lt;br /&gt;
    &amp;amp;&amp;amp; pip install --upgrade pip setuptools wheel&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt&lt;br /&gt;
&lt;br /&gt;
RUN git clone --depth 1 \&lt;br /&gt;
    https://github.com/Comfy-Org/ComfyUI.git \&lt;br /&gt;
    /opt/ComfyUI&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt/ComfyUI&lt;br /&gt;
&lt;br /&gt;
RUN pip install \&lt;br /&gt;
    torch \&lt;br /&gt;
    torchvision \&lt;br /&gt;
    torchaudio \&lt;br /&gt;
    --index-url https://download.pytorch.org/whl/cu128&lt;br /&gt;
&lt;br /&gt;
RUN pip install -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
EXPOSE 8188&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;main.py&amp;quot;, \&lt;br /&gt;
     &amp;quot;--listen&amp;quot;, &amp;quot;0.0.0.0&amp;quot;, \&lt;br /&gt;
     &amp;quot;--port&amp;quot;, &amp;quot;8188&amp;quot;, \&lt;br /&gt;
     &amp;quot;--preview-method&amp;quot;, &amp;quot;auto&amp;quot;]&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
PyTorch menyediakan paket CUDA untuk Linux melalui indeks wheel CUDA yang sesuai. ([PyTorch Documentation][8])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN I — DOCKER COMPOSE&lt;br /&gt;
&lt;br /&gt;
## 16. Buat file `compose.yaml`&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; compose.yaml &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
name: ai-stack&lt;br /&gt;
&lt;br /&gt;
services:&lt;br /&gt;
&lt;br /&gt;
  ollama:&lt;br /&gt;
    image: ollama/ollama:latest&lt;br /&gt;
    container_name: ollama&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;127.0.0.1:11434:11434&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./ollama:/root/.ollama&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      OLLAMA_HOST: &amp;quot;0.0.0.0:11434&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      # Lepaskan model dari VRAM setelah tidak digunakan.&lt;br /&gt;
      OLLAMA_KEEP_ALIVE: &amp;quot;5m&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      # RTX 4060 Laptop hanya memiliki VRAM 8 GB.&lt;br /&gt;
      OLLAMA_MAX_LOADED_MODELS: &amp;quot;1&amp;quot;&lt;br /&gt;
      OLLAMA_NUM_PARALLEL: &amp;quot;1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    deploy:&lt;br /&gt;
      resources:&lt;br /&gt;
        reservations:&lt;br /&gt;
          devices:&lt;br /&gt;
            - driver: nvidia&lt;br /&gt;
              count: all&lt;br /&gt;
              capabilities:&lt;br /&gt;
                - gpu&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  open-webui:&lt;br /&gt;
    image: ghcr.io/open-webui/open-webui:main&lt;br /&gt;
    container_name: open-webui&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - ollama&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3000:8080&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./open-webui:/app/backend/data&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      OLLAMA_BASE_URL: &amp;quot;http://ollama:11434&amp;quot;&lt;br /&gt;
      WEBUI_SECRET_KEY: &amp;quot;${WEBUI_SECRET_KEY}&amp;quot;&lt;br /&gt;
      TZ: &amp;quot;Asia/Jakarta&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  n8n:&lt;br /&gt;
    image: docker.n8n.io/n8nio/n8n:latest&lt;br /&gt;
    container_name: n8n&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;5678:5678&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./n8n:/home/node/.n8n&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      N8N_HOST: &amp;quot;${SERVER_IP}&amp;quot;&lt;br /&gt;
      N8N_PORT: &amp;quot;5678&amp;quot;&lt;br /&gt;
      N8N_PROTOCOL: &amp;quot;http&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      N8N_EDITOR_BASE_URL: &amp;quot;http://${SERVER_IP}:5678/&amp;quot;&lt;br /&gt;
      WEBHOOK_URL: &amp;quot;http://${SERVER_IP}:5678/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      N8N_ENCRYPTION_KEY: &amp;quot;${N8N_ENCRYPTION_KEY}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      # Diperlukan karena akses masih menggunakan HTTP lokal.&lt;br /&gt;
      # Ubah menjadi true setelah memakai HTTPS.&lt;br /&gt;
      N8N_SECURE_COOKIE: &amp;quot;false&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: &amp;quot;true&amp;quot;&lt;br /&gt;
      N8N_DIAGNOSTICS_ENABLED: &amp;quot;false&amp;quot;&lt;br /&gt;
      N8N_PERSONALIZATION_ENABLED: &amp;quot;false&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      GENERIC_TIMEZONE: &amp;quot;Asia/Jakarta&amp;quot;&lt;br /&gt;
      TZ: &amp;quot;Asia/Jakarta&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  waha:&lt;br /&gt;
    image: devlikeapro/waha:latest&lt;br /&gt;
    container_name: waha&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3001:3000&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    env_file:&lt;br /&gt;
      - ./waha/.env&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./waha/sessions:/app/.sessions&lt;br /&gt;
      - ./waha/media:/app/.media&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  comfyui:&lt;br /&gt;
    build:&lt;br /&gt;
      context: ./comfyui&lt;br /&gt;
      dockerfile: Dockerfile&lt;br /&gt;
&lt;br /&gt;
    image: local/comfyui:cu128&lt;br /&gt;
    container_name: comfyui&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;8188:8188&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./comfyui/models:/opt/ComfyUI/models&lt;br /&gt;
      - ./comfyui/input:/opt/ComfyUI/input&lt;br /&gt;
      - ./comfyui/output:/opt/ComfyUI/output&lt;br /&gt;
      - ./comfyui/custom_nodes:/opt/ComfyUI/custom_nodes&lt;br /&gt;
      - ./comfyui/user:/opt/ComfyUI/user&lt;br /&gt;
&lt;br /&gt;
    shm_size: &amp;quot;4gb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    deploy:&lt;br /&gt;
      resources:&lt;br /&gt;
        reservations:&lt;br /&gt;
          devices:&lt;br /&gt;
            - driver: nvidia&lt;br /&gt;
              count: all&lt;br /&gt;
              capabilities:&lt;br /&gt;
                - gpu&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  ai-net:&lt;br /&gt;
    name: ai-net&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasi tersebut memastikan:&lt;br /&gt;
&lt;br /&gt;
* Ollama memperoleh akses GPU.&lt;br /&gt;
* ComfyUI memperoleh akses GPU.&lt;br /&gt;
* Open WebUI memakai image `main`, bukan image `cuda`.&lt;br /&gt;
* Open WebUI tidak mendapat reservasi perangkat GPU.&lt;br /&gt;
* n8n dan WAHA tidak mendapat reservasi perangkat GPU.&lt;br /&gt;
* Semua aplikasi dapat berkomunikasi melalui jaringan `ai-net`.&lt;br /&gt;
&lt;br /&gt;
Open WebUI mendokumentasikan image `main` untuk instalasi biasa dan koneksi ke Ollama menggunakan `OLLAMA_BASE_URL`; image `cuda` hanya diperlukan bila Open WebUI sendiri membutuhkan GPU. ([Open WebUI][9])&lt;br /&gt;
&lt;br /&gt;
n8n merekomendasikan Docker untuk sebagian besar instalasi self-hosted karena dependensi aplikasi dapat diisolasi dari sistem operasi. ([n8n Documentation][10])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 17. Validasi Docker Compose&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose config&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila tidak muncul pesan error, konfigurasi YAML valid.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN J — MENJALANKAN STACK&lt;br /&gt;
&lt;br /&gt;
## 18. Download image aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose pull&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Perintah ini menarik image:&lt;br /&gt;
&lt;br /&gt;
* Ollama&lt;br /&gt;
* Open WebUI&lt;br /&gt;
* n8n&lt;br /&gt;
* WAHA&lt;br /&gt;
&lt;br /&gt;
ComfyUI akan dibangun secara lokal.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 19. Build ComfyUI&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose build --pull comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa image yang dibuat:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker images | grep comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
local/comfyui    cu128&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 20. Jalankan semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa container:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NAME          STATUS&lt;br /&gt;
ollama        Up&lt;br /&gt;
open-webui    Up&lt;br /&gt;
n8n           Up&lt;br /&gt;
waha          Up&lt;br /&gt;
comfyui       Up&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 21. Periksa log&lt;br /&gt;
&lt;br /&gt;
Semua aplikasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Open WebUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 open-webui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
n8n:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 n8n&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
WAHA:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 waha&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log secara langsung:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs -f comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tekan `Ctrl+C` untuk keluar dari tampilan log. Container tetap berjalan.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN K — PENGUJIAN&lt;br /&gt;
&lt;br /&gt;
## 22. Uji Ollama&lt;br /&gt;
&lt;br /&gt;
Periksa API:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl http://127.0.0.1:11434/api/tags&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa GPU dari container Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec ollama nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Download contoh model ringan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec -it ollama ollama pull llama3.2:3b&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan model:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec -it ollama ollama run llama3.2:3b&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ollama mendokumentasikan penggunaan container resmi `ollama/ollama`, akses GPU NVIDIA, dan perintah `docker exec ... ollama run`. ([Ollama][11])&lt;br /&gt;
&lt;br /&gt;
Keluar dari chat Ollama dengan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/bye&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa model:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec ollama ollama list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 23. Buka Open WebUI&lt;br /&gt;
&lt;br /&gt;
Dari komputer lain pada jaringan yang sama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:3000&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.100:3000&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Akun pertama yang dibuat akan menjadi administrator.&lt;br /&gt;
&lt;br /&gt;
Open WebUI sudah diarahkan ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://ollama:11434&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jadi tidak perlu memasukkan alamat Ollama secara manual.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 24. Buka n8n&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:5678&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.100:5678&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat akun administrator n8n melalui halaman awal.&lt;br /&gt;
&lt;br /&gt;
Dari node HTTP Request di n8n, alamat internal yang dapat digunakan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ollama:&lt;br /&gt;
http://ollama:11434&lt;br /&gt;
&lt;br /&gt;
WAHA:&lt;br /&gt;
http://waha:3000&lt;br /&gt;
&lt;br /&gt;
Open WebUI:&lt;br /&gt;
http://open-webui:8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh endpoint Ollama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://ollama:11434/api/generate&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh endpoint WAHA:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://waha:3000/api/sendText&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 25. Buka WAHA&lt;br /&gt;
&lt;br /&gt;
Dashboard:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:3001/dashboard&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Swagger/API:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:3001&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat username dan password:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
grep -E \&lt;br /&gt;
  'WAHA_DASHBOARD_USERNAME|WAHA_DASHBOARD_PASSWORD|WAHA_API_KEY' \&lt;br /&gt;
  /opt/ai-stack/waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Masuk ke dashboard, buat sesi `default`, kemudian scan QR menggunakan WhatsApp pada telepon.&lt;br /&gt;
&lt;br /&gt;
WAHA menggunakan QR untuk menghubungkan sesi dan menyediakan endpoint HTTP untuk mengirim pesan. ([GitHub][5])&lt;br /&gt;
&lt;br /&gt;
**Catatan penting:** WAHA merupakan klien otomatisasi tidak resmi. Dokumentasi WAHA sendiri menjelaskan bahwa WhatsApp tidak mengizinkan bot atau klien tidak resmi sehingga penggunaannya tidak sepenuhnya aman dari pemblokiran akun. Gunakan nomor pengujian atau nomor nonkritis dan jangan melakukan spam. ([WAHA][12])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 26. Buka ComfyUI&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.100:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa apakah PyTorch mendeteksi GPU:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec comfyui python -c \&lt;br /&gt;
'import torch; print(&amp;quot;CUDA:&amp;quot;, torch.cuda.is_available()); print(&amp;quot;GPU:&amp;quot;, torch.cuda.get_device_name(0) if torch.cuda.is_available() else &amp;quot;Tidak terdeteksi&amp;quot;)'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
CUDA: True&lt;br /&gt;
GPU: NVIDIA GeForce RTX 4060 Laptop GPU&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN L — MEMASUKKAN MODEL COMFYUI&lt;br /&gt;
&lt;br /&gt;
## 27. Copy checkpoint Stable Diffusion&lt;br /&gt;
&lt;br /&gt;
Misalnya model berada pada:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
~/Downloads/DreamShaper_8_pruned.safetensors&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Copy:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cp \&lt;br /&gt;
  ~/Downloads/DreamShaper_8_pruned.safetensors \&lt;br /&gt;
  /opt/ai-stack/comfyui/models/checkpoints/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lh /opt/ai-stack/comfyui/models/checkpoints/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Restart ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lokasi umum model:&lt;br /&gt;
&lt;br /&gt;
| Jenis      | Folder                           |&lt;br /&gt;
| ---------- | -------------------------------- |&lt;br /&gt;
| Checkpoint | `comfyui/models/checkpoints/`    |&lt;br /&gt;
| LoRA       | `comfyui/models/loras/`          |&lt;br /&gt;
| VAE        | `comfyui/models/vae/`            |&lt;br /&gt;
| CLIP       | `comfyui/models/clip/`           |&lt;br /&gt;
| ControlNet | `comfyui/models/controlnet/`     |&lt;br /&gt;
| Upscaler   | `comfyui/models/upscale_models/` |&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN M — PENGELOLAAN GPU 8 GB&lt;br /&gt;
&lt;br /&gt;
## 28. Hindari Ollama dan ComfyUI memakai VRAM berat bersamaan&lt;br /&gt;
&lt;br /&gt;
RTX 4060 memiliki VRAM 8 GB. Ollama dan ComfyUI boleh hidup bersamaan, tetapi model baru memakai banyak VRAM ketika sedang dimuat.&lt;br /&gt;
&lt;br /&gt;
Konfigurasi berikut sudah membantu Ollama melepaskan model setelah lima menit:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
OLLAMA_KEEP_ALIVE: &amp;quot;5m&amp;quot;&lt;br /&gt;
OLLAMA_MAX_LOADED_MODELS: &amp;quot;1&amp;quot;&lt;br /&gt;
OLLAMA_NUM_PARALLEL: &amp;quot;1&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa pemakaian GPU:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
watch -n 1 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Keluar dengan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ctrl+C&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila ComfyUI mengalami `CUDA out of memory`, hentikan Ollama sementara:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose stop ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali setelah selesai memakai ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sebaliknya, untuk memberikan GPU sepenuhnya kepada Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN N — FIREWALL&lt;br /&gt;
&lt;br /&gt;
## 29. Batasi akses hanya dari jaringan lokal&lt;br /&gt;
&lt;br /&gt;
Contoh jaringan lokal:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
192.168.0.0/24&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan SSH terlebih dahulu:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow OpenSSH&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan Open WebUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 3000 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan n8n:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 5678 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan WAHA:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 3001 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 8188 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan firewall:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw enable&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw status numbered&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Port Ollama tidak perlu dibuka karena dipetakan hanya ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
127.0.0.1:11434&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Open WebUI dan n8n tetap dapat mengakses Ollama melalui jaringan internal Docker.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN O — PERINTAH OPERASIONAL&lt;br /&gt;
&lt;br /&gt;
## 30. Start semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 31. Stop semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose stop&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 32. Start kembali&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 33. Restart semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 34. Hapus container tanpa menghapus data&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose down&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Folder data tetap berada di `/opt/ai-stack`.&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 35. Periksa status&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 36. Periksa penggunaan resource&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker stats&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN P — UPDATE&lt;br /&gt;
&lt;br /&gt;
## 37. Update Ollama, Open WebUI, n8n, dan WAHA&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Open WebUI menyarankan memakai tag versi tertentu untuk lingkungan produksi daripada selalu memakai tag bergerak seperti `main`. Setelah sistem stabil, image sebaiknya dipasangi nomor versi agar update tidak mendadak mengubah perilaku aplikasi. ([Open WebUI][9])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 38. Update ComfyUI&lt;br /&gt;
&lt;br /&gt;
Karena source ComfyUI diambil saat proses build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
docker compose build \&lt;br /&gt;
  --pull \&lt;br /&gt;
  --no-cache \&lt;br /&gt;
  comfyui&lt;br /&gt;
&lt;br /&gt;
docker compose up -d comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN Q — TROUBLESHOOTING&lt;br /&gt;
&lt;br /&gt;
## 39. Docker tidak mendeteksi GPU&lt;br /&gt;
&lt;br /&gt;
Pesan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
could not select device driver &amp;quot;nvidia&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm --gpus all ubuntu:24.04 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 40. n8n mengalami `permission denied`&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chown -R 1000:1000 /opt/ai-stack/n8n&lt;br /&gt;
docker compose restart n8n&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 41. Open WebUI tidak menemukan Ollama&lt;br /&gt;
&lt;br /&gt;
Periksa Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps ollama&lt;br /&gt;
docker compose logs --tail=100 ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji melalui jaringan Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm \&lt;br /&gt;
  --network ai-net \&lt;br /&gt;
  curlimages/curl:latest \&lt;br /&gt;
  http://ollama:11434/api/tags&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa konfigurasi Open WebUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker inspect open-webui \&lt;br /&gt;
  --format '{{range .Config.Env}}{{println .}}{{end}}' \&lt;br /&gt;
  | grep OLLAMA&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OLLAMA_BASE_URL=http://ollama:11434&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 42. ComfyUI kehabisan VRAM&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hentikan Ollama sementara:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop ollama&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Gunakan model lebih ringan atau kurangi resolusi gambar.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 43. WAHA kehilangan sesi setelah restart&lt;br /&gt;
&lt;br /&gt;
Periksa pemetaan volume:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker inspect waha \&lt;br /&gt;
  --format '{{json .Mounts}}' \&lt;br /&gt;
  | python3 -m json.tool&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan terdapat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/waha/sessions -&amp;gt; /app/.sessions&lt;br /&gt;
/opt/ai-stack/waha/media    -&amp;gt; /app/.media&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa folder:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lah /opt/ai-stack/waha/sessions&lt;br /&gt;
ls -lah /opt/ai-stack/waha/media&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Checklist akhir&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
nvidia-smi&lt;br /&gt;
docker version&lt;br /&gt;
docker compose version&lt;br /&gt;
docker compose ps&lt;br /&gt;
curl http://127.0.0.1:11434/api/tags&lt;br /&gt;
docker exec comfyui python -c 'import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil akhir yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ollama      : GPU RTX 4060&lt;br /&gt;
ComfyUI     : GPU RTX 4060&lt;br /&gt;
Open WebUI  : CPU, terhubung ke Ollama&lt;br /&gt;
n8n         : CPU&lt;br /&gt;
WAHA        : CPU&lt;br /&gt;
Data        : tersimpan di /opt/ai-stack&lt;br /&gt;
Timezone    : Asia/Jakarta&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
[1]: https://docs.docker.com/engine/install/ubuntu/ &amp;quot;Install Docker Engine on Ubuntu | Docker Docs&amp;quot;&lt;br /&gt;
[2]: https://ubuntu.com/server/docs/how-to/graphics/install-nvidia-drivers/ &amp;quot;NVIDIA drivers installation - Ubuntu Server documentation&amp;quot;&lt;br /&gt;
[3]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html &amp;quot;Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit&amp;quot;&lt;br /&gt;
[4]: https://docs.ollama.com/troubleshooting?utm_source=chatgpt.com &amp;quot;Troubleshooting - Ollama&amp;quot;&lt;br /&gt;
[5]: https://github.com/devlikeapro/waha-docs/blob/main/content//docs/overview/quick-start/index.md &amp;quot;waha-docs/content/docs/overview/quick-start/index.md at main · devlikeapro/waha-docs · GitHub&amp;quot;&lt;br /&gt;
[6]: https://github.com/devlikeapro/waha/blob/core/docker-compose.yaml &amp;quot;waha/docker-compose.yaml at core · devlikeapro/waha · GitHub&amp;quot;&lt;br /&gt;
[7]: https://github.com/comfyanonymous &amp;quot;comfyanonymous (comfyanonymous) · GitHub&amp;quot;&lt;br /&gt;
[8]: https://docs.pytorch.org/get-started/locally/?utm_source=chatgpt.com &amp;quot;Start Locally | PyTorch&amp;quot;&lt;br /&gt;
[9]: https://docs.openwebui.com/getting-started/quick-start/ &amp;quot;Quick Start / Open WebUI&amp;quot;&lt;br /&gt;
[10]: https://docs.n8n.io/deploy/host-n8n/install-options/install-with-docker?utm_source=chatgpt.com &amp;quot;Install with Docker | Deploy&amp;quot;&lt;br /&gt;
[11]: https://docs.ollama.com/docker?utm_source=chatgpt.com &amp;quot;Docker - Ollama&amp;quot;&lt;br /&gt;
[12]: https://waha.devlike.pro/docs/overview/introduction/?utm_source=chatgpt.com &amp;quot;📖 Introduction | WAHA&amp;quot;&lt;/div&gt;</description>
			<pubDate>Thu, 23 Jul 2026 18:10:39 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM:_Ubuntu_26.04_server_Ollama_GPU_%2B_Open-WebUI_%2B_n8n_%2B_WAHA_%2B_ComfyUI_docker</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73704&amp;oldid=73701</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73704&amp;oldid=73701</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Pranala Menarik&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:10, 23 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l44&quot; &gt;Line 44:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 44:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: docker shell access]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: docker shell access]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + ComfyUI docker]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh docker]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh docker]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh + Webmail docker]] '''NOT RECOMMEND'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh + Webmail docker]] '''NOT RECOMMEND'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Thu, 23 Jul 2026 18:10:23 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>ComfyUI: Instalasi via docker compose</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73703&amp;oldid=73702</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73703&amp;oldid=73702</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;amp;diff=73703&amp;amp;oldid=73702&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Tue, 21 Jul 2026 11:39:13 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Instalasi_via_docker_compose</comments>
		</item>
		<item>
			<title>ComfyUI: Instalasi via docker compose</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73702&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73702&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;## Menambahkan ComfyUI ke Docker Compose yang sudah ada  Cara yang relatif aman adalah **membangun image ComfyUI sendiri dari repositori resmi**, bukan memakai image komunitas...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;## Menambahkan ComfyUI ke Docker Compose yang sudah ada&lt;br /&gt;
&lt;br /&gt;
Cara yang relatif aman adalah **membangun image ComfyUI sendiri dari repositori resmi**, bukan memakai image komunitas yang isinya tidak selalu jelas. Instalasi resmi ComfyUI menggunakan repositori `Comfy-Org/ComfyUI`, memasang PyTorch dan `requirements.txt`, lalu menjalankan `main.py`. ComfyUI-Manager sekarang diaktifkan melalui `manager_requirements.txt` dan parameter `--enable-manager`. ([GitHub][1])&lt;br /&gt;
&lt;br /&gt;
Struktur akhirnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
local-ai/&lt;br /&gt;
├── compose.yaml&lt;br /&gt;
└── comfyui/&lt;br /&gt;
    ├── Dockerfile&lt;br /&gt;
    ├── .dockerignore&lt;br /&gt;
    └── data/&lt;br /&gt;
        ├── models/&lt;br /&gt;
        ├── input/&lt;br /&gt;
        ├── output/&lt;br /&gt;
        ├── custom_nodes/&lt;br /&gt;
        ├── user/&lt;br /&gt;
        └── cache/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### 1. Pastikan GPU NVIDIA dapat digunakan Docker&lt;br /&gt;
&lt;br /&gt;
Periksa driver:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dpkg -l | grep nvidia-container-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika belum terpasang:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \&lt;br /&gt;
  | sudo gpg --dearmor \&lt;br /&gt;
  -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \&lt;br /&gt;
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \&lt;br /&gt;
  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasikan runtime NVIDIA:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Itu adalah prosedur resmi NVIDIA untuk Debian dan Ubuntu. ([NVIDIA Docs][2])&lt;br /&gt;
&lt;br /&gt;
Tes akses GPU dari container:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm --gpus all \&lt;br /&gt;
  nvidia/cuda:12.9.0-base-ubuntu22.04 \&lt;br /&gt;
  nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Walaupun host memakai Ubuntu 24.04, container boleh menggunakan basis Ubuntu 22.04.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 2. Buat direktori ComfyUI&lt;br /&gt;
&lt;br /&gt;
Masuk ke direktori tempat `compose.yaml` berada:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd ~/Apps/LocalAI&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sesuaikan apabila lokasi compose berbeda.&lt;br /&gt;
&lt;br /&gt;
Buat struktur folder:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p comfyui/data/{input,output,custom_nodes,user,cache}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p comfyui/data/models/{checkpoints,vae,loras,controlnet,clip,clip_vision,diffusion_models,text_encoders,unet,upscale_models,embeddings}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
find comfyui -maxdepth 3 -type d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 3. Buat Dockerfile ComfyUI&lt;br /&gt;
&lt;br /&gt;
Buat file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nano comfyui/Dockerfile&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
```dockerfile&lt;br /&gt;
FROM python:3.12-slim-bookworm&lt;br /&gt;
&lt;br /&gt;
ENV DEBIAN_FRONTEND=noninteractive \&lt;br /&gt;
    PYTHONUNBUFFERED=1 \&lt;br /&gt;
    PIP_NO_CACHE_DIR=1&lt;br /&gt;
&lt;br /&gt;
# Paket sistem yang diperlukan ComfyUI dan berbagai custom node.&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends \&lt;br /&gt;
    git \&lt;br /&gt;
    ca-certificates \&lt;br /&gt;
    curl \&lt;br /&gt;
    ffmpeg \&lt;br /&gt;
    build-essential \&lt;br /&gt;
    libgl1 \&lt;br /&gt;
    libglib2.0-0 \&lt;br /&gt;
    libgomp1 \&lt;br /&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt&lt;br /&gt;
&lt;br /&gt;
# Mengambil ComfyUI dari repositori resmi.&lt;br /&gt;
RUN git clone --depth 1 https://github.com/Comfy-Org/ComfyUI.git&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt/ComfyUI&lt;br /&gt;
&lt;br /&gt;
# Memasang PyTorch dengan dukungan NVIDIA CUDA 12.8.&lt;br /&gt;
RUN python -m pip install --upgrade pip setuptools wheel \&lt;br /&gt;
    &amp;amp;&amp;amp; python -m pip install \&lt;br /&gt;
       torch torchvision torchaudio \&lt;br /&gt;
       --index-url https://download.pytorch.org/whl/cu128 \&lt;br /&gt;
    &amp;amp;&amp;amp; python -m pip install -r requirements.txt \&lt;br /&gt;
    &amp;amp;&amp;amp; python -m pip install -r manager_requirements.txt&lt;br /&gt;
&lt;br /&gt;
EXPOSE 8188&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;main.py&amp;quot;, \&lt;br /&gt;
     &amp;quot;--listen&amp;quot;, &amp;quot;0.0.0.0&amp;quot;, \&lt;br /&gt;
     &amp;quot;--port&amp;quot;, &amp;quot;8188&amp;quot;, \&lt;br /&gt;
     &amp;quot;--enable-manager&amp;quot;, \&lt;br /&gt;
     &amp;quot;--preview-method&amp;quot;, &amp;quot;auto&amp;quot;]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
CUDA 12.8 dipilih karena cocok untuk keluarga GPU NVIDIA modern seperti Turing, Ampere, dan Blackwell, termasuk RTX 20, RTX 30, RTX 40, dan RTX 50. PyTorch masih menyediakan wheel CUDA 12.8 secara terpisah. ([GitHub][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Buat `.dockerignore`&lt;br /&gt;
&lt;br /&gt;
Ini penting agar file model yang ukurannya puluhan gigabyte tidak ikut dikirim sebagai Docker build context.&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nano comfyui/.dockerignore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
data/&lt;br /&gt;
__pycache__/&lt;br /&gt;
*.pyc&lt;br /&gt;
*.pyo&lt;br /&gt;
.git/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 5. Tambahkan service ComfyUI ke `compose.yaml`&lt;br /&gt;
&lt;br /&gt;
Tambahkan bagian berikut **setelah service `waha` tetapi sebelum bagian paling bawah `volumes:`**:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
  ################################&lt;br /&gt;
  # 5. COMFYUI (Image Generation)&lt;br /&gt;
  ################################&lt;br /&gt;
  comfyui:&lt;br /&gt;
    build:&lt;br /&gt;
      context: ./comfyui&lt;br /&gt;
      dockerfile: Dockerfile&lt;br /&gt;
    image: local/comfyui:cu128&lt;br /&gt;
    container_name: comfyui&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;192.168.0.230:8188:8188&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      - TZ=Asia/Jakarta&lt;br /&gt;
      - NVIDIA_VISIBLE_DEVICES=all&lt;br /&gt;
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./comfyui/data/models:/opt/ComfyUI/models&lt;br /&gt;
      - ./comfyui/data/input:/opt/ComfyUI/input&lt;br /&gt;
      - ./comfyui/data/output:/opt/ComfyUI/output&lt;br /&gt;
      - ./comfyui/data/custom_nodes:/opt/ComfyUI/custom_nodes&lt;br /&gt;
      - ./comfyui/data/user:/opt/ComfyUI/user&lt;br /&gt;
      - ./comfyui/data/cache:/root/.cache&lt;br /&gt;
&lt;br /&gt;
    shm_size: &amp;quot;8gb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    deploy:&lt;br /&gt;
      resources:&lt;br /&gt;
        reservations:&lt;br /&gt;
          devices:&lt;br /&gt;
            - driver: nvidia&lt;br /&gt;
              count: all&lt;br /&gt;
              capabilities: [&amp;quot;gpu&amp;quot;]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Bagian akhir compose tetap seperti sebelumnya:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
volumes:&lt;br /&gt;
  ollama_data:&lt;br /&gt;
  openwebui_data:&lt;br /&gt;
  n8n_data:&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tidak perlu menambahkan `comfyui_data` karena ComfyUI menggunakan bind mount ke direktori `./comfyui/data`.&lt;br /&gt;
&lt;br /&gt;
Docker Compose memang mendukung reservasi GPU melalui `deploy.resources.reservations.devices`, dan `capabilities: [&amp;quot;gpu&amp;quot;]` wajib dicantumkan. ([Docker Documentation][4])&lt;br /&gt;
&lt;br /&gt;
### Tentang pengaturan port&lt;br /&gt;
&lt;br /&gt;
Baris ini:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
ports:&lt;br /&gt;
  - &amp;quot;192.168.0.230:8188:8188&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
berarti ComfyUI hanya mendengarkan melalui alamat LAN server `192.168.0.230`.&lt;br /&gt;
&lt;br /&gt;
Apabila alamat server berbeda, ubah IP tersebut. Untuk membuka melalui seluruh interface, gunakan:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
ports:&lt;br /&gt;
  - &amp;quot;8188:8188&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Namun ComfyUI sebaiknya tidak langsung dibuka ke internet, terutama ketika Manager aktif karena Manager dapat memasang dan menjalankan kode dari custom node.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Validasi YAML&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose config&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika tidak ada pesan kesalahan, build hanya service ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose build comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose up -d comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Keterangan:&lt;br /&gt;
&lt;br /&gt;
* `up` membuat dan menjalankan container.&lt;br /&gt;
* `-d` menjalankan container di belakang layar.&lt;br /&gt;
* `comfyui` berarti hanya service ComfyUI yang dijalankan.&lt;br /&gt;
&lt;br /&gt;
Periksa status:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya terdapat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui    running    192.168.0.230:8188-&amp;gt;8188/tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Periksa log ComfyUI&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs -f --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cari informasi seperti:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Device: cuda:0&lt;br /&gt;
Using pytorch attention&lt;br /&gt;
Starting server&lt;br /&gt;
To see the GUI go to: http://0.0.0.0:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tekan `Ctrl+C` untuk keluar dari tampilan log. Container tetap berjalan.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Verifikasi PyTorch dan GPU&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec comfyui python -c \&lt;br /&gt;
'import torch; print(&amp;quot;CUDA tersedia:&amp;quot;, torch.cuda.is_available()); print(&amp;quot;PyTorch:&amp;quot;, torch.__version__); print(&amp;quot;CUDA:&amp;quot;, torch.version.cuda); print(&amp;quot;GPU:&amp;quot;, torch.cuda.get_device_name(0) if torch.cuda.is_available() else &amp;quot;Tidak ada&amp;quot;)'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
CUDA tersedia: True&lt;br /&gt;
PyTorch: 2.x.x&lt;br /&gt;
CUDA: 12.8&lt;br /&gt;
GPU: NVIDIA GeForce RTX ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 9. Buka ComfyUI&lt;br /&gt;
&lt;br /&gt;
Dari komputer dalam jaringan yang sama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.230:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
ComfyUI tidak menyertakan checkpoint model secara otomatis. Tempatkan file model `*.safetensors` di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui/data/models/checkpoints/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
VAE ditempatkan di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui/data/models/vae/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
LoRA ditempatkan di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui/data/models/loras/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lokasi checkpoint dan VAE tersebut sesuai struktur model resmi ComfyUI. ([GitHub][1])&lt;br /&gt;
&lt;br /&gt;
Setelah memasukkan model, restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Perintah operasional&lt;br /&gt;
&lt;br /&gt;
Menghentikan ComfyUI saja:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menjalankannya kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menghapus container tanpa menghapus model dan hasil gambar:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose rm -sf comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Membangun ulang ComfyUI versi terbaru:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose build --no-cache comfyui&lt;br /&gt;
docker compose up -d comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
`--no-cache` memaksa Docker mengambil ulang kode dan memasang ulang dependency, bukan menggunakan layer build lama.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Jika VRAM tidak cukup&lt;br /&gt;
&lt;br /&gt;
Ollama dan ComfyUI memakai GPU NVIDIA yang sama. Ketika model Ollama masih berada di VRAM, ComfyUI dapat mengalami:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
CUDA out of memory&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk pengujian, hentikan Ollama sementara:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah selesai membuat gambar:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Terakhir, sebaiknya pindahkan `WHATSAPP_API_KEY`, password dashboard WAHA, dan password Swagger dari YAML ke file `.env`, serta ganti nilai password yang saat ini masih sederhana sebelum server dapat diakses pengguna lain.&lt;br /&gt;
&lt;br /&gt;
[1]: https://github.com/comfy-org/ComfyUI &amp;quot;GitHub - Comfy-Org/ComfyUI: The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface. · GitHub&amp;quot;&lt;br /&gt;
[2]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/1.17.7/install-guide.html &amp;quot;Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit&amp;quot;&lt;br /&gt;
[3]: https://github.com/pytorch/pytorch/releases?utm_source=chatgpt.com &amp;quot;Releases · pytorch/pytorch&amp;quot;&lt;br /&gt;
[4]: https://docs.docker.com/compose/how-tos/gpu-support/ &amp;quot;Run Docker Compose services with GPU access | Docker Docs&amp;quot;&lt;/div&gt;</description>
			<pubDate>Tue, 21 Jul 2026 09:17:44 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Instalasi_via_docker_compose</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73701&amp;oldid=73666</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73701&amp;oldid=73666</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ComfyUI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 09:13, 21 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l82&quot; &gt;Line 82:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 82:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 21 Jul 2026 09:13:23 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
</channel></rss>