<?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>Tue, 04 Aug 2026 01:09:18 GMT</lastBuildDate>
		<item>
			<title>LLM: Ubuntu 24.04 desktop pull ollama model</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM:_Ubuntu_24.04_desktop_pull_ollama_model&amp;diff=73731&amp;oldid=73515</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM:_Ubuntu_24.04_desktop_pull_ollama_model&amp;diff=73731&amp;oldid=73515</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 13:10, 2 August 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;(2 intermediate revisions 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-l41&quot; &gt;Line 41:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 41:&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;  # hacking &amp;amp; security&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;  # hacking &amp;amp; security&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;  docker exec -it ollama ollama pull llama2-uncensored:7b&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;  docker exec -it ollama ollama pull llama2-uncensored:7b&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;  docker exec -it ollama ollama ruturaj04/ruturajai:latest&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;  docker exec -it ollama ollama &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;pull &lt;/ins&gt;ruturaj04/ruturajai:latest&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;  docker exec -it ollama ollama xploiter/the-xploiter:latest&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;  docker exec -it &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;ai-&lt;/ins&gt;ollama ollama &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;pull tinyllama&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;  docker exec -it ollama ollama xploiter/pentester:latest&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; docker exec -it ai-ollama ollama pull &lt;/ins&gt;xploiter/the-xploiter:latest&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;  docker exec -it ollama ollama OpenNix/wazuh-llama-3.1-8B-v1:latest&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;  docker exec -it &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;ai-&lt;/ins&gt;ollama ollama &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;pull &lt;/ins&gt;xploiter/pentester:latest&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;  docker exec -it ollama ollama &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;pull &lt;/ins&gt;OpenNix/wazuh-llama-3.1-8B-v1:latest&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;==Pranala Menarik==&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;==Pranala Menarik==&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;* [[LLM]]&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]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 02 Aug 2026 13:10:23 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM:_Ubuntu_24.04_desktop_pull_ollama_model</comments>
		</item>
		<item>
			<title>Onno W. Purbo</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Onno_W._Purbo&amp;diff=73728&amp;oldid=72990</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Onno_W._Purbo&amp;diff=73728&amp;oldid=72990</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Penghargaan&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 20:39, 28 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-l201&quot; &gt;Line 201:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 201:&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;* 2023, Penerima &amp;quot;ICTWATCH Internet Literacy Life Time Achivement Awards&amp;quot; dari ictwatch.id.&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;* 2023, Penerima &amp;quot;ICTWATCH Internet Literacy Life Time Achivement Awards&amp;quot; dari ictwatch.id.&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;* 2025, Penerima &amp;quot;Gizmotalk Person of the Year: Onno W. Purbo&amp;quot; dari Gizmologi dan GadgetDiva&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;* 2025, Penerima &amp;quot;Gizmotalk Person of the Year: Onno W. Purbo&amp;quot; dari Gizmologi dan GadgetDiva&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;* 2026, Member of the Global Jury Council of Global CIO Forum&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;==Distro Linux / Sistem Operasi Yang Pernah Dibuat==&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;==Distro Linux / Sistem Operasi Yang Pernah Dibuat==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 28 Jul 2026 20:39:43 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Onno_W._Purbo</comments>
		</item>
		<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>
		<item>
			<title>Internet OFFLINE: Ubuntu 26.04 install asterisk</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Internet_OFFLINE:_Ubuntu_26.04_install_asterisk&amp;diff=73700&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Internet_OFFLINE:_Ubuntu_26.04_install_asterisk&amp;diff=73700&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# Instalasi Asterisk Ubuntu Server 26.04  ## Extension SIP 1000–1100  Panduan berikut mengadaptasi pendekatan buku *VoIP Desa Menggunakan Asterisk*: instalasi melalui APT, p...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# Instalasi Asterisk Ubuntu Server 26.04&lt;br /&gt;
&lt;br /&gt;
## Extension SIP 1000–1100&lt;br /&gt;
&lt;br /&gt;
Panduan berikut mengadaptasi pendekatan buku *VoIP Desa Menggunakan Asterisk*: instalasi melalui APT, penggunaan PJSIP, dialplan lokal, firewall, pengujian, dan dokumentasi akun. Buku menggunakan struktur satu akun PJSIP yang terdiri atas **endpoint, authentication, dan AOR**, serta menyarankan server memakai alamat IP statis. &lt;br /&gt;
&lt;br /&gt;
Ubuntu 26.04 LTS menyediakan paket **Asterisk 22.5.2** melalui komponen `universe`, sehingga tidak perlu melakukan kompilasi dari source code. ([Ubuntu Packages][1])&lt;br /&gt;
&lt;br /&gt;
Hasil akhir:&lt;br /&gt;
&lt;br /&gt;
* Asterisk aktif otomatis saat server hidup.&lt;br /&gt;
* SIP menggunakan PJSIP dan UDP port 5060.&lt;br /&gt;
* RTP menggunakan UDP port 10000–20000.&lt;br /&gt;
* Tersedia **101 akun**, dari 1000 sampai 1100.&lt;br /&gt;
* Setiap extension memiliki password acak berbeda.&lt;br /&gt;
* Semua extension dapat saling menelepon.&lt;br /&gt;
* Daftar username dan password tersimpan dalam CSV yang hanya dapat dibaca root.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 1. Siapkan informasi jaringan&lt;br /&gt;
&lt;br /&gt;
Contoh yang digunakan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Hostname server : asterisk-desa&lt;br /&gt;
IP server       : 192.168.10.10&lt;br /&gt;
Gateway         : 192.168.10.1&lt;br /&gt;
Jaringan LAN    : 192.168.10.0/24&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sesuaikan dengan jaringan yang sebenarnya.&lt;br /&gt;
&lt;br /&gt;
Periksa jaringan server:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
hostnamectl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur hostname:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo hostnamectl set-hostname asterisk-desa&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tambahkan hostname ke `/etc/hosts`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nano /etc/hosts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan terdapat baris:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
127.0.1.1 asterisk-desa&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Server Asterisk sebaiknya menggunakan **IP statis** atau DHCP reservation agar alamat server tidak berubah.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 2. Perbarui Ubuntu Server&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt full-upgrade -y&lt;br /&gt;
sudo reboot&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah server hidup kembali, masuk melalui SSH:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ssh namauser@192.168.10.10&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa versi Ubuntu:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
lsb_release -a&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
atau:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 3. Instal Asterisk dan perangkat bantu&lt;br /&gt;
&lt;br /&gt;
Aktifkan repository `universe`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo add-apt-repository universe&lt;br /&gt;
sudo apt update&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Instal Asterisk:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y \&lt;br /&gt;
    asterisk \&lt;br /&gt;
    asterisk-core-sounds-en \&lt;br /&gt;
    ufw \&lt;br /&gt;
    fail2ban \&lt;br /&gt;
    sngrep \&lt;br /&gt;
    tcpdump \&lt;br /&gt;
    openssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
APT merupakan mekanisme resmi Ubuntu untuk memasang dan memelihara paket perangkat lunak. ([Ubuntu][2])&lt;br /&gt;
&lt;br /&gt;
Aktifkan layanan Asterisk:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl enable --now asterisk&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa status:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl status asterisk --no-pager&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa versi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;core show version&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa modul PJSIP:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;module show like pjsip&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
PJSIP menghubungkan sebuah endpoint dengan objek autentikasi dan AOR; endpoint harus memiliki AOR agar Asterisk mengetahui kontak tujuan panggilan. ([Asterisk Documentation][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Backup konfigurasi bawaan&lt;br /&gt;
&lt;br /&gt;
Jangan langsung menghapus konfigurasi asli.&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
BACKUP_DIR=&amp;quot;/root/asterisk-config-$(date +%Y%m%d-%H%M%S)&amp;quot;&lt;br /&gt;
sudo mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;&lt;br /&gt;
sudo cp -a /etc/asterisk/. &amp;quot;$BACKUP_DIR/&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa hasil backup:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ls -lah &amp;quot;$BACKUP_DIR&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 5. Membuat konfigurasi utama PJSIP&lt;br /&gt;
&lt;br /&gt;
Buat ulang `/etc/asterisk/pjsip.conf`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tee /etc/asterisk/pjsip.conf &amp;gt;/dev/null &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
;==========================================================&lt;br /&gt;
; Konfigurasi PJSIP Asterisk Desa&lt;br /&gt;
; Ubuntu Server 26.04&lt;br /&gt;
; Extension 1000-1100&lt;br /&gt;
;==========================================================&lt;br /&gt;
&lt;br /&gt;
[global]&lt;br /&gt;
type=global&lt;br /&gt;
user_agent=Asterisk-Desa&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Transport SIP&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[transport-udp]&lt;br /&gt;
type=transport&lt;br /&gt;
protocol=udp&lt;br /&gt;
bind=0.0.0.0:5060&lt;br /&gt;
&lt;br /&gt;
; Apabila seluruh perangkat hanya berada di LAN,&lt;br /&gt;
; external_media_address dan external_signaling_address&lt;br /&gt;
; tidak diperlukan.&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Template endpoint&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[endpoint-template](!)&lt;br /&gt;
type=endpoint&lt;br /&gt;
transport=transport-udp&lt;br /&gt;
context=internal&lt;br /&gt;
disallow=all&lt;br /&gt;
allow=ulaw&lt;br /&gt;
allow=alaw&lt;br /&gt;
&lt;br /&gt;
; DTMF untuk IVR dan layanan berbasis tombol telepon&lt;br /&gt;
dtmf_mode=rfc4733&lt;br /&gt;
&lt;br /&gt;
; Pengaturan yang membantu client Wi-Fi/NAT&lt;br /&gt;
direct_media=no&lt;br /&gt;
rtp_symmetric=yes&lt;br /&gt;
force_rport=yes&lt;br /&gt;
rewrite_contact=yes&lt;br /&gt;
&lt;br /&gt;
; Jangan izinkan pemanggilan tanpa autentikasi&lt;br /&gt;
allow_subscribe=yes&lt;br /&gt;
language=en&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Template autentikasi&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[auth-template](!)&lt;br /&gt;
type=auth&lt;br /&gt;
auth_type=userpass&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Template Address of Record&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[aor-template](!)&lt;br /&gt;
type=aor&lt;br /&gt;
&lt;br /&gt;
; Satu extension hanya boleh dipakai satu perangkat&lt;br /&gt;
max_contacts=1&lt;br /&gt;
&lt;br /&gt;
; Hapus registrasi lama bila perangkat berganti alamat&lt;br /&gt;
remove_existing=yes&lt;br /&gt;
&lt;br /&gt;
; Pemeriksaan berkala perangkat&lt;br /&gt;
qualify_frequency=60&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Akun extension dibuat otomatis di file berikut&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;pjsip-extensions.conf&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasi sengaja menggunakan template agar 101 extension tidak harus memiliki seluruh parameter yang ditulis berulang kali.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Membuat extension 1000–1100 otomatis&lt;br /&gt;
&lt;br /&gt;
Buat skrip generator:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tee /usr/local/sbin/generate-asterisk-extensions.sh &amp;gt;/dev/null &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
&lt;br /&gt;
set -euo pipefail&lt;br /&gt;
&lt;br /&gt;
CONFIG_FILE=&amp;quot;/etc/asterisk/pjsip-extensions.conf&amp;quot;&lt;br /&gt;
PASSWORD_FILE=&amp;quot;/root/asterisk-extension-passwords.csv&amp;quot;&lt;br /&gt;
TEMP_CONFIG=&amp;quot;$(mktemp)&amp;quot;&lt;br /&gt;
TEMP_PASSWORD=&amp;quot;$(mktemp)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cleanup() {&lt;br /&gt;
    rm -f &amp;quot;$TEMP_CONFIG&amp;quot; &amp;quot;$TEMP_PASSWORD&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trap cleanup EXIT&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; &amp;quot;$TEMP_CONFIG&amp;quot; &amp;lt;&amp;lt;'HEADER'&lt;br /&gt;
;==========================================================&lt;br /&gt;
; Dibuat otomatis oleh generate-asterisk-extensions.sh&lt;br /&gt;
; Jangan menyimpan file password ke repository publik.&lt;br /&gt;
;==========================================================&lt;br /&gt;
&lt;br /&gt;
HEADER&lt;br /&gt;
&lt;br /&gt;
printf '%s\n' '&amp;quot;extension&amp;quot;,&amp;quot;username&amp;quot;,&amp;quot;password&amp;quot;,&amp;quot;server&amp;quot;,&amp;quot;transport&amp;quot;' \&lt;br /&gt;
    &amp;gt; &amp;quot;$TEMP_PASSWORD&amp;quot;&lt;br /&gt;
&lt;br /&gt;
SERVER_IP=&amp;quot;$(hostname -I | awk '{print $1}')&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ -z &amp;quot;$SERVER_IP&amp;quot; ]]; then&lt;br /&gt;
    SERVER_IP=&amp;quot;GANTI_DENGAN_IP_SERVER&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
for EXTENSION in $(seq 1000 1100); do&lt;br /&gt;
    PASSWORD=&amp;quot;$(openssl rand -hex 16)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    cat &amp;gt;&amp;gt; &amp;quot;$TEMP_CONFIG&amp;quot; &amp;lt;&amp;lt;EOF_CONFIG&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Extension ${EXTENSION}&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[${EXTENSION}](endpoint-template)&lt;br /&gt;
auth=auth-${EXTENSION}&lt;br /&gt;
aors=aor-${EXTENSION}&lt;br /&gt;
callerid=&amp;quot;Extension ${EXTENSION}&amp;quot; &amp;lt;${EXTENSION}&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[auth-${EXTENSION}](auth-template)&lt;br /&gt;
username=${EXTENSION}&lt;br /&gt;
password=${PASSWORD}&lt;br /&gt;
&lt;br /&gt;
[aor-${EXTENSION}](aor-template)&lt;br /&gt;
&lt;br /&gt;
EOF_CONFIG&lt;br /&gt;
&lt;br /&gt;
    printf '&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;UDP&amp;quot;\n' \&lt;br /&gt;
        &amp;quot;$EXTENSION&amp;quot; \&lt;br /&gt;
        &amp;quot;$EXTENSION&amp;quot; \&lt;br /&gt;
        &amp;quot;$PASSWORD&amp;quot; \&lt;br /&gt;
        &amp;quot;$SERVER_IP&amp;quot; &amp;gt;&amp;gt; &amp;quot;$TEMP_PASSWORD&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
install -o root -g asterisk -m 0640 \&lt;br /&gt;
    &amp;quot;$TEMP_CONFIG&amp;quot; &amp;quot;$CONFIG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
install -o root -g root -m 0600 \&lt;br /&gt;
    &amp;quot;$TEMP_PASSWORD&amp;quot; &amp;quot;$PASSWORD_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Berhasil membuat extension 1000 sampai 1100.&amp;quot;&lt;br /&gt;
echo &amp;quot;Konfigurasi : $CONFIG_FILE&amp;quot;&lt;br /&gt;
echo &amp;quot;Password    : $PASSWORD_FILE&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jadikan executable:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chmod 750 /usr/local/sbin/generate-asterisk-extensions.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo /usr/local/sbin/generate-asterisk-extensions.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa jumlah extension:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo grep -Ec '^\[[0-9]{4}\]\(endpoint-template\)$' \&lt;br /&gt;
    /etc/asterisk/pjsip-extensions.conf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Output seharusnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
101&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa beberapa konfigurasi awal:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo sed -n '1,80p' /etc/asterisk/pjsip-extensions.conf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat daftar akun:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo column -s, -t &amp;lt; /root/asterisk-extension-passwords.csv | head&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan membagikan seluruh file CSV secara terbuka karena berisi password semua pengguna.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Membuat dialplan panggilan&lt;br /&gt;
&lt;br /&gt;
Buat `/etc/asterisk/extensions.conf`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tee /etc/asterisk/extensions.conf &amp;gt;/dev/null &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
;==========================================================&lt;br /&gt;
; Dialplan Asterisk Desa&lt;br /&gt;
; Extension yang diizinkan: 1000-1100&lt;br /&gt;
;==========================================================&lt;br /&gt;
&lt;br /&gt;
[general]&lt;br /&gt;
static=yes&lt;br /&gt;
writeprotect=no&lt;br /&gt;
clearglobalvars=no&lt;br /&gt;
&lt;br /&gt;
[globals]&lt;br /&gt;
RINGTIME=30&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Panggilan internal&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[internal]&lt;br /&gt;
&lt;br /&gt;
; Extension 1000 sampai 1099&lt;br /&gt;
exten =&amp;gt; _10XX,1,NoOp(Panggilan internal ${CALLERID(num)} ke ${EXTEN})&lt;br /&gt;
 same =&amp;gt; n,Dial(PJSIP/${EXTEN},${RINGTIME})&lt;br /&gt;
 same =&amp;gt; n,Hangup()&lt;br /&gt;
&lt;br /&gt;
; Extension 1100&lt;br /&gt;
exten =&amp;gt; 1100,1,NoOp(Panggilan internal ${CALLERID(num)} ke 1100)&lt;br /&gt;
 same =&amp;gt; n,Dial(PJSIP/1100,${RINGTIME})&lt;br /&gt;
 same =&amp;gt; n,Hangup()&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
; Nomor pengujian&lt;br /&gt;
;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
; 600 - Echo test&lt;br /&gt;
exten =&amp;gt; 600,1,Answer()&lt;br /&gt;
 same =&amp;gt; n,Wait(1)&lt;br /&gt;
 same =&amp;gt; n,Echo()&lt;br /&gt;
 same =&amp;gt; n,Hangup()&lt;br /&gt;
&lt;br /&gt;
; 601 - Menyebutkan nomor extension pemanggil&lt;br /&gt;
exten =&amp;gt; 601,1,Answer()&lt;br /&gt;
 same =&amp;gt; n,Playback(your)&lt;br /&gt;
 same =&amp;gt; n,Playback(extension)&lt;br /&gt;
 same =&amp;gt; n,SayDigits(${CALLERID(num)})&lt;br /&gt;
 same =&amp;gt; n,Hangup()&lt;br /&gt;
&lt;br /&gt;
; Nomor tidak dikenal&lt;br /&gt;
exten =&amp;gt; i,1,Playback(invalid)&lt;br /&gt;
 same =&amp;gt; n,Hangup()&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dialplan `_10XX` hanya menerima nomor 1000–1099, sementara 1100 dibuat secara eksplisit. Dengan demikian, nomor 1101 dan seterusnya tidak dapat dipanggil.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Memastikan rentang RTP&lt;br /&gt;
&lt;br /&gt;
Periksa konfigurasi RTP:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo grep -Ev '^[[:space:]]*(;|$)' /etc/asterisk/rtp.conf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Bila belum jelas, buat konfigurasi berikut:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tee /etc/asterisk/rtp.conf &amp;gt;/dev/null &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
[general]&lt;br /&gt;
rtpstart=10000&lt;br /&gt;
rtpend=20000&lt;br /&gt;
strictrtp=yes&lt;br /&gt;
icesupport=yes&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
SIP dipakai untuk mengatur sesi dan registrasi, sedangkan suara dikirim melalui RTP. Konsep ini juga menjadi dasar konfigurasi pada buku. &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 9. Atur kepemilikan dan permission&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chown root:asterisk \&lt;br /&gt;
    /etc/asterisk/pjsip.conf \&lt;br /&gt;
    /etc/asterisk/pjsip-extensions.conf \&lt;br /&gt;
    /etc/asterisk/extensions.conf \&lt;br /&gt;
    /etc/asterisk/rtp.conf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chmod 640 \&lt;br /&gt;
    /etc/asterisk/pjsip.conf \&lt;br /&gt;
    /etc/asterisk/pjsip-extensions.conf \&lt;br /&gt;
    /etc/asterisk/extensions.conf \&lt;br /&gt;
    /etc/asterisk/rtp.conf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan file password hanya dapat dibaca root:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chmod 600 /root/asterisk-extension-passwords.csv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Validasi lalu restart Asterisk&lt;br /&gt;
&lt;br /&gt;
Restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl restart asterisk&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa layanan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl status asterisk --no-pager&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa log jika gagal:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo journalctl -u asterisk -n 100 --no-pager&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Masuk CLI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rvvv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Di dalam CLI, jalankan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
core show version&lt;br /&gt;
pjsip show transports&lt;br /&gt;
pjsip show endpoints&lt;br /&gt;
dialplan show internal&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Keluar:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
exit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa jumlah endpoint dari shell:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show endpoints&amp;quot; |&lt;br /&gt;
    grep -E 'Endpoint: +[0-9]{4}/' |&lt;br /&gt;
    wc -l&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Targetnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
101&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 11. Konfigurasi firewall&lt;br /&gt;
&lt;br /&gt;
Ubuntu menggunakan `ufw` sebagai perangkat firewall host yang mudah dikelola. ([Ubuntu][4])&lt;br /&gt;
&lt;br /&gt;
**Sangat penting:** izinkan SSH sebelum mengaktifkan firewall agar koneksi administrator tidak terputus.&lt;br /&gt;
&lt;br /&gt;
Contoh untuk LAN `192.168.10.0/24`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw default deny incoming&lt;br /&gt;
sudo ufw default allow outgoing&lt;br /&gt;
sudo ufw allow OpenSSH&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan SIP hanya dari jaringan LAN:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.10.0/24 to any port 5060 proto udp \&lt;br /&gt;
    comment 'Asterisk SIP dari LAN'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan RTP hanya dari LAN:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.10.0/24 to any port 10000:20000 proto udp \&lt;br /&gt;
    comment 'Asterisk RTP dari LAN'&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;
Jangan membuka UDP 5060 dan 10000–20000 ke seluruh Internet kecuali benar-benar diperlukan. Untuk akses antarlokasi, pendekatan yang lebih aman adalah membawa SIP dan RTP melalui VPN seperti WireGuard. Buku juga merekomendasikan komunikasi antar-Asterisk melalui WireGuard daripada mengekspos SIP langsung ke Internet. &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 12. Registrasi Linphone&lt;br /&gt;
&lt;br /&gt;
Ambil satu akun uji:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo grep '^&amp;quot;1000&amp;quot;' /root/asterisk-extension-passwords.csv&lt;br /&gt;
sudo grep '^&amp;quot;1001&amp;quot;' /root/asterisk-extension-passwords.csv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh pengaturan perangkat pertama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Display name : Extension 1000&lt;br /&gt;
Username     : 1000&lt;br /&gt;
Password     : password dari CSV&lt;br /&gt;
Domain       : 192.168.10.10&lt;br /&gt;
SIP server   : sip:192.168.10.10&lt;br /&gt;
Transport    : UDP&lt;br /&gt;
Port         : 5060&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Perangkat kedua:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Display name : Extension 1001&lt;br /&gt;
Username     : 1001&lt;br /&gt;
Password     : password dari CSV&lt;br /&gt;
Domain       : 192.168.10.10&lt;br /&gt;
Transport    : UDP&lt;br /&gt;
Port         : 5060&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pada beberapa versi Linphone, identitas SIP ditulis:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
sip:1000@192.168.10.10&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Proxy/server:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
sip:192.168.10.10;transport=udp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan smartphone dan server berada dalam jaringan yang dapat saling menjangkau.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 13. Pengujian&lt;br /&gt;
&lt;br /&gt;
### Periksa registrasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show contacts&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
atau:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show endpoint 1000&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Endpoint belum terdaftar biasanya terlihat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Unavailable&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah registrasi berhasil, akan muncul alamat kontak perangkat.&lt;br /&gt;
&lt;br /&gt;
### Uji panggilan&lt;br /&gt;
&lt;br /&gt;
Lakukan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
1000 → 1001&lt;br /&gt;
1001 → 1000&lt;br /&gt;
1000 → 1100&lt;br /&gt;
1100 → 1000&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji juga nomor yang tidak tersedia:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
1101&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Panggilan ke 1101 seharusnya ditolak karena berada di luar numbering plan.&lt;br /&gt;
&lt;br /&gt;
### Uji suara&lt;br /&gt;
&lt;br /&gt;
Hubungi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
600&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Bicaralah ke mikrofon. Suara seharusnya dikirim kembali melalui aplikasi `Echo()`.&lt;br /&gt;
&lt;br /&gt;
### Monitor panggilan langsung&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rvvv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
core show channels&lt;br /&gt;
pjsip show contacts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan SIP logger hanya ketika troubleshooting:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
pjsip set logger on&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Matikan kembali setelah selesai:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
pjsip set logger off&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dokumentasi resmi Asterisk juga menyarankan pemeriksaan hubungan `auth`, endpoint, dan AOR ketika registrasi PJSIP gagal. ([Asterisk Documentation][5])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 14. Troubleshooting cepat&lt;br /&gt;
&lt;br /&gt;
### Asterisk tidak dapat dijalankan&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl status asterisk&lt;br /&gt;
sudo journalctl -u asterisk -b --no-pager&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa konfigurasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show endpoints&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### Client tidak dapat register&lt;br /&gt;
&lt;br /&gt;
Periksa port:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ss -lunp | grep ':5060'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya terdapat proses Asterisk yang mendengarkan pada:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
0.0.0.0:5060&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa firewall:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw status verbose&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa log:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tail -f /var/log/asterisk/full&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika `/var/log/asterisk/full` belum tersedia, gunakan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo journalctl -u asterisk -f&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### Username atau password ditolak&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show endpoint 1000&amp;quot;&lt;br /&gt;
sudo grep -A4 '\[auth-1000\]' \&lt;br /&gt;
    /etc/asterisk/pjsip-extensions.conf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan client menggunakan username **1000**, bukan `auth-1000`.&lt;br /&gt;
&lt;br /&gt;
### Telepon berdering tetapi suara tidak terdengar&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw status&lt;br /&gt;
sudo ss -lunp | grep asterisk&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pantau RTP:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tcpdump -ni any udp portrange 10000-20000&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Penyebab umum:&lt;br /&gt;
&lt;br /&gt;
* Firewall RTP tertutup.&lt;br /&gt;
* Client berada pada jaringan NAT berbeda.&lt;br /&gt;
* Wi-Fi memiliki client isolation.&lt;br /&gt;
* Router memblokir komunikasi antarklien.&lt;br /&gt;
* Alamat server yang dimasukkan salah.&lt;br /&gt;
&lt;br /&gt;
### Melihat paket SIP dengan sngrep&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo sngrep&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Gunakan tombol:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Enter : membuka call flow&lt;br /&gt;
F10   : keluar&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 15. Backup setelah konfigurasi berhasil&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tar \&lt;br /&gt;
    --create \&lt;br /&gt;
    --gzip \&lt;br /&gt;
    --preserve-permissions \&lt;br /&gt;
    --file=&amp;quot;/root/asterisk-ready-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
    /etc/asterisk \&lt;br /&gt;
    /root/asterisk-extension-passwords.csv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ls -lh /root/asterisk-ready-*.tar.gz&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Backup tersebut mengandung seluruh password extension. Simpan secara terenkripsi dan jangan diletakkan di web server atau repository Git publik.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 16. Checklist hasil akhir&lt;br /&gt;
&lt;br /&gt;
Jalankan seluruh pemeriksaan berikut:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
systemctl is-enabled asterisk&lt;br /&gt;
systemctl is-active asterisk&lt;br /&gt;
sudo asterisk -rx &amp;quot;core show version&amp;quot;&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show transports&amp;quot;&lt;br /&gt;
sudo asterisk -rx &amp;quot;pjsip show endpoints&amp;quot;&lt;br /&gt;
sudo asterisk -rx &amp;quot;dialplan show internal&amp;quot;&lt;br /&gt;
sudo ufw status&lt;br /&gt;
sudo ss -lunp | grep -E ':5060|asterisk'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kondisi yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Asterisk service       : active&lt;br /&gt;
Start saat boot        : enabled&lt;br /&gt;
Transport SIP          : UDP 0.0.0.0:5060&lt;br /&gt;
Jumlah extension       : 101&lt;br /&gt;
Nomor pertama          : 1000&lt;br /&gt;
Nomor terakhir         : 1100&lt;br /&gt;
Dialplan               : internal&lt;br /&gt;
RTP                    : UDP 10000-20000&lt;br /&gt;
Password akun          : berbeda untuk setiap extension&lt;br /&gt;
Firewall               : hanya membuka SIP/RTP dari LAN&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasi ini sudah cukup untuk **telepon internal 1000–1100**. Layanan lanjutan seperti voicemail, ring group, IVR, ConfBridge, paging, queue, SIP trunk, dan WireGuard dapat ditambahkan setelah registrasi serta panggilan dasar stabil.&lt;br /&gt;
&lt;br /&gt;
[1]: https://packages.ubuntu.com/resolute/asterisk?utm_source=chatgpt.com &amp;quot;Details of package asterisk in resolute&amp;quot;&lt;br /&gt;
[2]: https://ubuntu.com/server/docs/how-to/software/package-management/?utm_source=chatgpt.com &amp;quot;Install and manage packages - Ubuntu Server documentation&amp;quot;&lt;br /&gt;
[3]: https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/PJSIP-Configuration-Sections-and-Relationships/?utm_source=chatgpt.com &amp;quot;PJSIP Configuration Sections and Relationships&amp;quot;&lt;br /&gt;
[4]: https://ubuntu.com/server/docs/how-to/security/firewalls/?utm_source=chatgpt.com &amp;quot;Firewall - Ubuntu Server documentation&amp;quot;&lt;br /&gt;
[5]: https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/Asterisk-PJSIP-Troubleshooting-Guide/?utm_source=chatgpt.com &amp;quot;Asterisk PJSIP Troubleshooting Guide&amp;quot;&lt;/div&gt;</description>
			<pubDate>Mon, 20 Jul 2026 02:41:55 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Internet_OFFLINE:_Ubuntu_26.04_install_asterisk</comments>
		</item>
		<item>
			<title>Internet offline</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Internet_offline&amp;diff=73699&amp;oldid=73081</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Internet_offline&amp;diff=73699&amp;oldid=73081</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Ubuntu 24.04&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:41, 20 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-l147&quot; &gt;Line 147:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 147:&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;* [[USB OFFLINE: Ubuntu 24.04 Webmin]]&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;* [[USB OFFLINE: Ubuntu 24.04 Webmin]]&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;* [[USB OFFLINE: Password dll]]&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;* [[USB OFFLINE: Password dll]]&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;===Ubuntu 26.04===&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;* [[Internet OFFLINE: Ubuntu 26.04 install asterisk]]&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;===SLiMS===&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;===SLiMS===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Mon, 20 Jul 2026 02:41:21 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Internet_offline</comments>
		</item>
		<item>
			<title>Epub</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Epub&amp;diff=73698&amp;oldid=40246</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Epub&amp;diff=73698&amp;oldid=40246</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Membuka epub&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:59, 14 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-l16&quot; &gt;Line 16:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 16:&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;  sudo apt-get update&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;  sudo apt-get update&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;  sudo apt-get install calibre&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;  sudo apt-get install calibre&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;==Convert epub satu folder==&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; for file in ./*.epub&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; do&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;     ebook-convert &amp;quot;$file&amp;quot; &amp;quot;${file%.epub}.pdf&amp;quot; \&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;         --paper-size a4&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; done&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;==Referensi==&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;==Referensi==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 14 Jul 2026 18:59:43 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Epub</comments>
		</item>
</channel></rss>