<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>OnnoWiki  - Recent changes [en]</title>
		<link>https://onnocenter.or.id/wiki/index.php/Special:RecentChanges</link>
		<description>Track the most recent changes to the wiki in this feed.</description>
		<language>en</language>
		<generator>MediaWiki 1.35.4</generator>
		<lastBuildDate>Mon, 27 Jul 2026 08:45:47 GMT</lastBuildDate>
		<item>
			<title>MCP: Reset dari nol, embed semua doc, isi vector database</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Reset_dari_nol,_embed_semua_doc,_isi_vector_database&amp;diff=73727&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Reset_dari_nol,_embed_semua_doc,_isi_vector_database&amp;diff=73727&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# Rekomendasi  **Tidak perlu install ulang AnythingLLM.** Gunakan reset melalui API lalu lakukan **restart normal**, bukan `docker kill` atau force restart.  Menghapus dan mem...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# Rekomendasi&lt;br /&gt;
&lt;br /&gt;
**Tidak perlu install ulang AnythingLLM.** Gunakan reset melalui API lalu lakukan **restart normal**, bukan `docker kill` atau force restart.&lt;br /&gt;
&lt;br /&gt;
Menghapus dan membuat ulang container dengan storage volume yang sama tidak menghapus workspace, dokumen, atau vector database karena data AnythingLLM disimpan di `/app/server/storage` dan memang dirancang tetap ada setelah rebuild atau pull image baru. ([AnythingLLM][1])&lt;br /&gt;
&lt;br /&gt;
Script berikut menggunakan API resmi untuk:&lt;br /&gt;
&lt;br /&gt;
1. Backup seluruh storage AnythingLLM.&lt;br /&gt;
2. Menghapus semua workspace.&lt;br /&gt;
3. Menghapus semua dokumen internal dan cached embedding.&lt;br /&gt;
4. Restart container secara graceful.&lt;br /&gt;
5. Membuat satu workspace baru.&lt;br /&gt;
6. Upload dan embed ulang seluruh file dari `/opt/ai-stack/documents`.&lt;br /&gt;
7. Membuat manifest berisi nama file, hash SHA-256, dan lokasi dokumen internal.&lt;br /&gt;
&lt;br /&gt;
AnythingLLM menyediakan endpoint resmi untuk mendaftar dan menghapus workspace, menghapus dokumen permanen, membuat workspace, serta upload dokumen langsung ke workspace. &lt;br /&gt;
&lt;br /&gt;
[Download reset-rebuild-anythingllm.sh](sandbox:/mnt/data/reset-rebuild-anythingllm.sh)&lt;br /&gt;
&lt;br /&gt;
Script sudah diperiksa dengan `bash -n`.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 1. Copy script ke server&lt;br /&gt;
&lt;br /&gt;
Misalnya file sudah berada di folder Downloads:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mkdir -p /opt/ai-stack/batch&lt;br /&gt;
&lt;br /&gt;
sudo cp ~/Downloads/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  /opt/ai-stack/batch/&lt;br /&gt;
&lt;br /&gt;
sudo chmod 750 \&lt;br /&gt;
  /opt/ai-stack/batch/reset-rebuild-anythingllm.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lh /opt/ai-stack/batch/reset-rebuild-anythingllm.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 2. Periksa nama dan port container&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}' \&lt;br /&gt;
  | grep -i anything&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atau:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker port anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
3001/tcp -&amp;gt; 0.0.0.0:3001&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Berarti:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export ANYTHINGLLM_URL=&amp;quot;http://127.0.0.1:3001&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila AnythingLLM memakai port host `3002`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export ANYTHINGLLM_URL=&amp;quot;http://127.0.0.1:3002&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hal ini penting bila port `3001` sudah digunakan WAHA.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 3. Buat API key AnythingLLM&lt;br /&gt;
&lt;br /&gt;
Masuk ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
AnythingLLM&lt;br /&gt;
→ Settings&lt;br /&gt;
→ Developer API&lt;br /&gt;
→ API Keys&lt;br /&gt;
→ New API Key&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dokumentasi API pada instance tersedia di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:PORT/api/docs&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
API key harus disimpan sebagai rahasia karena siapa pun yang memilikinya dapat mengoperasikan API AnythingLLM. ([AnythingLLM][2])&lt;br /&gt;
&lt;br /&gt;
Set API key:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export ANYTHINGLLM_API_KEY='MASUKKAN_API_KEY_ANDA'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan menyimpan API key langsung di dalam script.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Tentukan konfigurasi&lt;br /&gt;
&lt;br /&gt;
Untuk hanya meng-embed Markdown:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export DOCUMENT_ROOT=&amp;quot;/opt/ai-stack/documents&amp;quot;&lt;br /&gt;
export WORKSPACE_NAME=&amp;quot;Perpustakaan&amp;quot;&lt;br /&gt;
export CONTAINER_NAME=&amp;quot;anythingllm&amp;quot;&lt;br /&gt;
export EMBED_EXTENSIONS=&amp;quot;md&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk Markdown, PDF, DOCX, dan TXT:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export EMBED_EXTENSIONS=&amp;quot;md,pdf,docx,txt&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Saya menyarankan memakai:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export EMBED_EXTENSIONS=&amp;quot;md&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
bila semua PDF sudah dikonversi dan dibersihkan menjadi Markdown untuk RAG. Ini mencegah isi yang sama ter-embed dua kali dari versi PDF dan Markdown.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 5. Pastikan API key bekerja&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl --fail --silent --show-error \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ANYTHINGLLM_API_KEY}&amp;quot; \&lt;br /&gt;
  &amp;quot;${ANYTHINGLLM_URL}/api/v1/auth&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar:&lt;br /&gt;
&lt;br /&gt;
```json&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;authenticated&amp;quot;: true&lt;br /&gt;
}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Jalankan dry-run dahulu&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/ai-stack/batch/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  --dry-run&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dry-run hanya menghitung:&lt;br /&gt;
&lt;br /&gt;
* Jumlah workspace lama.&lt;br /&gt;
* Jumlah dokumen internal lama.&lt;br /&gt;
* Jumlah file sumber yang akan di-embed.&lt;br /&gt;
* Ekstensi yang diproses.&lt;br /&gt;
* Nama workspace baru.&lt;br /&gt;
&lt;br /&gt;
Tidak ada data yang dihapus.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Jalankan reset dan rebuild&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/ai-stack/batch/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  --yes-reset&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika user belum mendapat akses Docker dan direktori backup:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo -E /opt/ai-stack/batch/reset-rebuild-anythingllm.sh \&lt;br /&gt;
  --yes-reset&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Opsi `-E` mempertahankan variabel lingkungan seperti API key dan URL.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Hasil backup&lt;br /&gt;
&lt;br /&gt;
Sebelum menghapus data, script menghentikan container sementara dan membuat backup konsisten:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/backups/anythingllm-storage-YYYYMMDD-HHMMSS.tar.gz&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lh /opt/ai-stack/backups/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
anythingllm-storage-20260726-103000.tar.gz&lt;br /&gt;
anythingllm-rebuild-manifest-20260726-103215.tsv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Manifest berisi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
relative_path    sha256    anythingllm_location&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
AI/RAG/Pengenalan RAG.md    a421...    custom-documents/Pengenalan-RAG.md-uuid.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 9. Pantau proses&lt;br /&gt;
&lt;br /&gt;
Terminal lain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker logs -f anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pantau resource:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker stats anythingllm ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pantau GPU ketika embedding memakai Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
watch -n 1 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Verifikasi setelah selesai&lt;br /&gt;
&lt;br /&gt;
Periksa workspace:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl --fail --silent --show-error \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ANYTHINGLLM_API_KEY}&amp;quot; \&lt;br /&gt;
  &amp;quot;${ANYTHINGLLM_URL}/api/v1/workspaces&amp;quot; \&lt;br /&gt;
  | python3 -m json.tool&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya hanya terdapat satu workspace baru.&lt;br /&gt;
&lt;br /&gt;
Periksa dokumen:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl --fail --silent --show-error \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ANYTHINGLLM_API_KEY}&amp;quot; \&lt;br /&gt;
  &amp;quot;${ANYTHINGLLM_URL}/api/v1/documents&amp;quot; \&lt;br /&gt;
  | python3 -m json.tool&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
AnythingLLM menjelaskan bahwa menghapus dokumen secara permanen dari sistem akan menghapus parsed source, cached embedding, serta mengeluarkannya dari setiap workspace. ([AnythingLLM][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Apakah perlu force restart?&lt;br /&gt;
&lt;br /&gt;
## Pilihan terbaik: reset API + restart normal&lt;br /&gt;
&lt;br /&gt;
Script menggunakan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker restart -t 30 anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ini memberikan waktu sampai 30 detik agar proses berhenti secara normal sebelum Docker mengambil tindakan lanjutan.&lt;br /&gt;
&lt;br /&gt;
**Jangan menggunakan ini kecuali container macet:**&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker kill anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Force restart tidak membersihkan vector database. Ia hanya menghentikan dan menyalakan proses.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Kapan perlu install ulang?&lt;br /&gt;
&lt;br /&gt;
Install ulang atau factory reset hanya diperlukan apabila:&lt;br /&gt;
&lt;br /&gt;
* SQLite AnythingLLM rusak.&lt;br /&gt;
* LanceDB rusak dan API tidak dapat membersihkannya.&lt;br /&gt;
* Container terus crash akibat storage internal.&lt;br /&gt;
* Konfigurasi sistem sudah sangat kacau.&lt;br /&gt;
* Anda benar-benar ingin menghapus user, API key, model settings, MCP, agent skills, chat history, dan seluruh konfigurasi.&lt;br /&gt;
&lt;br /&gt;
Menarik image atau membuat ulang container **tanpa menghapus storage** bukan factory reset karena data tetap persisten. ([AnythingLLM][1])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Factory reset penuh&lt;br /&gt;
&lt;br /&gt;
Ini **bukan pilihan utama**. Perintah berikut menghilangkan seluruh konfigurasi aplikasi, bukan hanya RAG.&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
sudo docker compose stop anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cari lokasi storage:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker inspect anythingllm \&lt;br /&gt;
  --format '{{range .Mounts}}{{println .Source &amp;quot;-&amp;gt;&amp;quot; .Destination}}{{end}}'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Misalnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/anythingllm/storage -&amp;gt; /app/server/storage&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Backup dan ganti nama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mv \&lt;br /&gt;
  /opt/ai-stack/anythingllm/storage \&lt;br /&gt;
  &amp;quot;/opt/ai-stack/anythingllm/storage.factory-reset.$(date +%Y%m%d-%H%M%S)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat storage kosong:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mkdir -p /opt/ai-stack/anythingllm/storage&lt;br /&gt;
sudo chown -R 1000:1000 /opt/ai-stack/anythingllm/storage&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo docker compose up -d anythingllm&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
AnythingLLM kemudian tampil seperti instalasi pertama. Anda harus mengatur ulang:&lt;br /&gt;
&lt;br /&gt;
* Akun administrator.&lt;br /&gt;
* LLM provider.&lt;br /&gt;
* Embedding provider.&lt;br /&gt;
* Vector database.&lt;br /&gt;
* API key.&lt;br /&gt;
* MCP dan agent skills.&lt;br /&gt;
* Workspace.&lt;br /&gt;
* Dokumen.&lt;br /&gt;
&lt;br /&gt;
Karena tujuan Anda adalah membersihkan workspace dan membangun ulang seluruh embedding, **gunakan script API-reset, bukan factory reset dan bukan install ulang**.&lt;br /&gt;
&lt;br /&gt;
[1]: https://docs.anythingllm.com/installation-docker/local-docker &amp;quot;Local Docker Installation ~ AnythingLLM&amp;quot;&lt;br /&gt;
[2]: https://docs.anythingllm.com/features/api &amp;quot;API Access &amp;amp; Keys ~ AnythingLLM&amp;quot;&lt;br /&gt;
[3]: https://docs.anythingllm.com/features/privacy-and-data-handling &amp;quot;Privacy &amp;amp; Data ~ AnythingLLM&amp;quot;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:54:55 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Reset_dari_nol,_embed_semua_doc,_isi_vector_database</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73726&amp;oldid=73723</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73726&amp;oldid=73723</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:47, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l92&quot; &gt;Line 92:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 92:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Regenerate Vector Database untuk update content documents]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Regenerate Vector Database untuk update content documents]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Reset dari nol, embed semua doc, isi vector database]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:47:25 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>MCP: Regenerate Vector Database untuk update content documents</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73725&amp;oldid=73724</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73725&amp;oldid=73724</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;amp;diff=73725&amp;amp;oldid=73724&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:44:03 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Regenerate_Vector_Database_untuk_update_content_documents</comments>
		</item>
		<item>
			<title>MCP: Regenerate Vector Database untuk update content documents</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73724&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Regenerate_Vector_Database_untuk_update_content_documents&amp;diff=73724&amp;oldid=0</guid>
			<description>&lt;p&gt;Created blank page&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:40:37 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Regenerate_Vector_Database_untuk_update_content_documents</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73723&amp;oldid=73721</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73723&amp;oldid=73721</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:39, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l91&quot; &gt;Line 91:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 91:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi pip]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Regenerate Vector Database untuk update content documents]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:39:40 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>MCP: Instalasi pip</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi_pip&amp;diff=73722&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi_pip&amp;diff=73722&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Error tersebut berarti Python sudah ada, tetapi modul **pip** belum terpasang. Gunakan virtual environment supaya tidak mengganggu Python sistem Ubuntu. Ubuntu juga merekomend...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Error tersebut berarti Python sudah ada, tetapi modul **pip** belum terpasang. Gunakan virtual environment supaya tidak mengganggu Python sistem Ubuntu. Ubuntu juga merekomendasikan penggunaan `venv` untuk paket yang dipasang melalui pip. ([Ubuntu Documentation][1])&lt;br /&gt;
&lt;br /&gt;
Jalankan sebagai `root`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack/batch&lt;br /&gt;
&lt;br /&gt;
apt update&lt;br /&gt;
apt install -y python3-full python3-venv python3-pip&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat virtual environment:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3 -m venv .venv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Prompt biasanya berubah menjadi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
(.venv) root@server2:/opt/ai-stack/batch#&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan Python sudah memakai virtual environment:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
which python3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/batch/.venv/bin/python3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian instal dependensi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3 -m pip install --upgrade pip&lt;br /&gt;
python3 -m pip install pymupdf pyyaml&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verifikasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3 - &amp;lt;&amp;lt;'PY'&lt;br /&gt;
import pymupdf&lt;br /&gt;
import yaml&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;PyMuPDF berhasil:&amp;quot;, pymupdf.__version__)&lt;br /&gt;
print(&amp;quot;PyYAML berhasil:&amp;quot;, yaml.__version__)&lt;br /&gt;
PY&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah itu jalankan batch converter:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod +x batch_pdf_to_md.sh&lt;br /&gt;
chmod +x pdf_to_rag_md.py&lt;br /&gt;
&lt;br /&gt;
./batch_pdf_to_md.sh /path/folder/pdf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh \&lt;br /&gt;
  /opt/ai-stack/documents \&lt;br /&gt;
  /opt/ai-stack/output&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setiap kali keluar dari terminal atau login ulang, aktifkan kembali environment sebelum menjalankan script:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack/batch&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
./batch_pdf_to_md.sh /opt/ai-stack/documents /opt/ai-stack/output&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan gunakan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
pip install --break-system-packages&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
karena pemasangan langsung ke Python sistem dapat berbenturan dengan paket bawaan Ubuntu.&lt;br /&gt;
&lt;br /&gt;
[1]: https://documentation.ubuntu.com/ubuntu-for-developers/tutorials/python-use/?utm_source=chatgpt.com &amp;quot;Develop with Python on Ubuntu - Ubuntu for Developers&amp;quot;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:04:46 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Instalasi_pip</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73721&amp;oldid=73717</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73721&amp;oldid=73717</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:04, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l90&quot; &gt;Line 90:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 90:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Convert PDF ke .md]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Instalasi pip]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 02:04:32 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>Batch pdf to md.sh</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Batch_pdf_to_md.sh&amp;diff=73720&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Batch_pdf_to_md.sh&amp;diff=73720&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;&amp;lt;pre&amp;gt;  #!/usr/bin/env bash # Batch wrapper untuk pdf_to_rag_md.py # # Penggunaan: #   ./batch_pdf_to_md.sh /path/folder_pdf #   ./batch_pdf_to_md.sh /path/folder_pdf /path/fol...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
# Batch wrapper untuk pdf_to_rag_md.py&lt;br /&gt;
#&lt;br /&gt;
# Penggunaan:&lt;br /&gt;
#   ./batch_pdf_to_md.sh /path/folder_pdf&lt;br /&gt;
#   ./batch_pdf_to_md.sh /path/folder_pdf /path/folder_output&lt;br /&gt;
#   ./batch_pdf_to_md.sh /path/folder_pdf /path/folder_output /path/pdf_to_rag_md.py&lt;br /&gt;
#&lt;br /&gt;
# Hasil:&lt;br /&gt;
#   OUTPUT_DIR/&amp;lt;path-relatif&amp;gt;/&amp;lt;nama-pdf&amp;gt;/&lt;br /&gt;
#       ├── *.md&lt;br /&gt;
#       └── manifest.json&lt;br /&gt;
&lt;br /&gt;
set -Eeuo pipefail&lt;br /&gt;
IFS=$'\n\t'&lt;br /&gt;
&lt;br /&gt;
PROGRAM_NAME=&amp;quot;$(basename &amp;quot;$0&amp;quot;)&amp;quot;&lt;br /&gt;
SCRIPT_DIR=&amp;quot;$(cd -- &amp;quot;$(dirname -- &amp;quot;${BASH_SOURCE[0]}&amp;quot;)&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
usage() {&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
Penggunaan:&lt;br /&gt;
  $PROGRAM_NAME INPUT_PATH [OUTPUT_DIR] [PYTHON_SCRIPT]&lt;br /&gt;
&lt;br /&gt;
Argumen:&lt;br /&gt;
  INPUT_PATH      Folder yang akan dicari secara rekursif, atau satu file PDF.&lt;br /&gt;
  OUTPUT_DIR      Folder induk hasil konversi.&lt;br /&gt;
                  Default: INPUT_PATH/output untuk input folder,&lt;br /&gt;
                  atau folder_file/output untuk input satu PDF.&lt;br /&gt;
  PYTHON_SCRIPT   Lokasi script Python konverter.&lt;br /&gt;
                  Default: dicari di folder yang sama dengan shell script.&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
  $PROGRAM_NAME /opt/ai-stack/documents&lt;br /&gt;
  $PROGRAM_NAME /opt/ai-stack/documents /opt/ai-stack/output&lt;br /&gt;
  $PROGRAM_NAME ./pdf ./output ./pdf_to_rag_md.py&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
log() {&lt;br /&gt;
    printf '[%s] %s\n' &amp;quot;$(date '+%Y-%m-%d %H:%M:%S')&amp;quot; &amp;quot;$*&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fail() {&lt;br /&gt;
    printf 'ERROR: %s\n' &amp;quot;$*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if [[ ${1:-} == &amp;quot;-h&amp;quot; || ${1:-} == &amp;quot;--help&amp;quot; ]]; then&lt;br /&gt;
    usage&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
[[ $# -ge 1 &amp;amp;&amp;amp; $# -le 3 ]] || {&lt;br /&gt;
    usage &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 2&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
command -v python3 &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || fail &amp;quot;python3 tidak ditemukan.&amp;quot;&lt;br /&gt;
command -v find &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || fail &amp;quot;Perintah find tidak ditemukan.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUT_PATH=&amp;quot;$1&amp;quot;&lt;br /&gt;
[[ -e &amp;quot;$INPUT_PATH&amp;quot; ]] || fail &amp;quot;Path input tidak ditemukan: $INPUT_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Ubah menjadi absolute path tanpa membutuhkan realpath.&lt;br /&gt;
if [[ -d &amp;quot;$INPUT_PATH&amp;quot; ]]; then&lt;br /&gt;
    INPUT_PATH=&amp;quot;$(cd -- &amp;quot;$INPUT_PATH&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
    INPUT_IS_DIR=1&lt;br /&gt;
else&lt;br /&gt;
    INPUT_DIR=&amp;quot;$(cd -- &amp;quot;$(dirname -- &amp;quot;$INPUT_PATH&amp;quot;)&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
    INPUT_PATH=&amp;quot;$INPUT_DIR/$(basename -- &amp;quot;$INPUT_PATH&amp;quot;)&amp;quot;&lt;br /&gt;
    INPUT_IS_DIR=0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [[ $# -ge 2 ]]; then&lt;br /&gt;
    OUTPUT_DIR=&amp;quot;$2&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    if (( INPUT_IS_DIR )); then&lt;br /&gt;
        OUTPUT_DIR=&amp;quot;$INPUT_PATH/output&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        OUTPUT_DIR=&amp;quot;$(dirname -- &amp;quot;$INPUT_PATH&amp;quot;)/output&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
mkdir -p -- &amp;quot;$OUTPUT_DIR&amp;quot;&lt;br /&gt;
OUTPUT_DIR=&amp;quot;$(cd -- &amp;quot;$OUTPUT_DIR&amp;quot; &amp;amp;&amp;amp; pwd -P)&amp;quot;&lt;br /&gt;
[[ &amp;quot;$OUTPUT_DIR&amp;quot; != &amp;quot;$INPUT_PATH&amp;quot; ]] \&lt;br /&gt;
    || fail &amp;quot;OUTPUT_DIR tidak boleh sama persis dengan folder input. Gunakan subfolder, misalnya: $INPUT_PATH/output&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ $# -ge 3 ]]; then&lt;br /&gt;
    PYTHON_SCRIPT=&amp;quot;$3&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    if [[ -f &amp;quot;$SCRIPT_DIR/pdf_to_rag_md.py&amp;quot; ]]; then&lt;br /&gt;
        PYTHON_SCRIPT=&amp;quot;$SCRIPT_DIR/pdf_to_rag_md.py&amp;quot;&lt;br /&gt;
    elif [[ -f &amp;quot;$SCRIPT_DIR/pdf_to_rag_md(2).py&amp;quot; ]]; then&lt;br /&gt;
        PYTHON_SCRIPT=&amp;quot;$SCRIPT_DIR/pdf_to_rag_md(2).py&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        fail &amp;quot;Script Python tidak ditemukan. Letakkan pdf_to_rag_md.py di $SCRIPT_DIR atau berikan argumen PYTHON_SCRIPT.&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
[[ -f &amp;quot;$PYTHON_SCRIPT&amp;quot; ]] || fail &amp;quot;Script Python tidak ditemukan: $PYTHON_SCRIPT&amp;quot;&lt;br /&gt;
PYTHON_SCRIPT=&amp;quot;$(cd -- &amp;quot;$(dirname -- &amp;quot;$PYTHON_SCRIPT&amp;quot;)&amp;quot; &amp;amp;&amp;amp; pwd -P)/$(basename -- &amp;quot;$PYTHON_SCRIPT&amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Pastikan script Python valid dan dependensinya tersedia sebelum batch dimulai.&lt;br /&gt;
python3 -m py_compile &amp;quot;$PYTHON_SCRIPT&amp;quot; \&lt;br /&gt;
    || fail &amp;quot;Script Python gagal diperiksa dengan py_compile.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
python3 - &amp;lt;&amp;lt;'PY' \&lt;br /&gt;
    || fail &amp;quot;Dependensi Python belum lengkap. Instal dengan: python3 -m pip install pymupdf pyyaml&amp;quot;&lt;br /&gt;
try:&lt;br /&gt;
    import pymupdf  # noqa: F401&lt;br /&gt;
except ImportError:&lt;br /&gt;
    import fitz  # noqa: F401&lt;br /&gt;
import yaml  # noqa: F401&lt;br /&gt;
PY&lt;br /&gt;
&lt;br /&gt;
find_input_files() {&lt;br /&gt;
    if [[ &amp;quot;$OUTPUT_DIR&amp;quot; == &amp;quot;$INPUT_PATH/&amp;quot;* ]]; then&lt;br /&gt;
        find &amp;quot;$INPUT_PATH&amp;quot; -path &amp;quot;$OUTPUT_DIR&amp;quot; -prune -o -type f &amp;quot;$@&amp;quot; -print0&lt;br /&gt;
    else&lt;br /&gt;
        find &amp;quot;$INPUT_PATH&amp;quot; -type f &amp;quot;$@&amp;quot; -print0&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
printf '\n=== Daftar semua file pada input ===\n'&lt;br /&gt;
if (( INPUT_IS_DIR )); then&lt;br /&gt;
    while IFS= read -r -d '' file; do&lt;br /&gt;
        printf '%s\n' &amp;quot;$file&amp;quot;&lt;br /&gt;
    done &amp;lt; &amp;lt;(find_input_files | sort -z)&lt;br /&gt;
else&lt;br /&gt;
    printf '%s\n' &amp;quot;$INPUT_PATH&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
printf '=== Akhir daftar file ===\n\n'&lt;br /&gt;
&lt;br /&gt;
PDF_FILES=()&lt;br /&gt;
if (( INPUT_IS_DIR )); then&lt;br /&gt;
    while IFS= read -r -d '' pdf; do&lt;br /&gt;
        PDF_FILES+=(&amp;quot;$pdf&amp;quot;)&lt;br /&gt;
    done &amp;lt; &amp;lt;(find_input_files -iname '*.pdf' | sort -z)&lt;br /&gt;
else&lt;br /&gt;
    [[ &amp;quot;${INPUT_PATH,,}&amp;quot; == *.pdf ]] \&lt;br /&gt;
        || fail &amp;quot;File input bukan PDF: $INPUT_PATH&amp;quot;&lt;br /&gt;
    PDF_FILES+=(&amp;quot;$INPUT_PATH&amp;quot;)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
TOTAL=${#PDF_FILES[@]}&lt;br /&gt;
if (( TOTAL == 0 )); then&lt;br /&gt;
    log &amp;quot;Tidak ada file PDF yang ditemukan.&amp;quot;&lt;br /&gt;
    exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
LOG_FILE=&amp;quot;$OUTPUT_DIR/batch_conversion.log&amp;quot;&lt;br /&gt;
SUMMARY_FILE=&amp;quot;$OUTPUT_DIR/batch_summary.tsv&amp;quot;&lt;br /&gt;
printf 'status\tinput_pdf\toutput_folder\n' &amp;gt; &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
: &amp;gt; &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
log &amp;quot;Ditemukan $TOTAL file PDF.&amp;quot;&lt;br /&gt;
log &amp;quot;Output utama: $OUTPUT_DIR&amp;quot;&lt;br /&gt;
log &amp;quot;Log batch: $LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
SUCCESS=0&lt;br /&gt;
FAILED=0&lt;br /&gt;
INDEX=0&lt;br /&gt;
&lt;br /&gt;
for PDF_FILE in &amp;quot;${PDF_FILES[@]}&amp;quot;; do&lt;br /&gt;
    ((INDEX += 1))&lt;br /&gt;
&lt;br /&gt;
    if (( INPUT_IS_DIR )); then&lt;br /&gt;
        RELATIVE_PATH=&amp;quot;${PDF_FILE#&amp;quot;$INPUT_PATH&amp;quot;/}&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        RELATIVE_PATH=&amp;quot;$(basename -- &amp;quot;$PDF_FILE&amp;quot;)&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    RELATIVE_PARENT=&amp;quot;$(dirname -- &amp;quot;$RELATIVE_PATH&amp;quot;)&amp;quot;&lt;br /&gt;
    PDF_NAME=&amp;quot;$(basename -- &amp;quot;$RELATIVE_PATH&amp;quot;)&amp;quot;&lt;br /&gt;
    PDF_STEM=&amp;quot;${PDF_NAME%.*}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if [[ &amp;quot;$RELATIVE_PARENT&amp;quot; == &amp;quot;.&amp;quot; ]]; then&lt;br /&gt;
        PDF_OUTPUT_DIR=&amp;quot;$OUTPUT_DIR/$PDF_STEM&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        PDF_OUTPUT_DIR=&amp;quot;$OUTPUT_DIR/$RELATIVE_PARENT/$PDF_STEM&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    mkdir -p -- &amp;quot;$PDF_OUTPUT_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    printf '\n[%d/%d] Konversi: %s\n' &amp;quot;$INDEX&amp;quot; &amp;quot;$TOTAL&amp;quot; &amp;quot;$PDF_FILE&amp;quot;&lt;br /&gt;
    printf '        Output   : %s\n' &amp;quot;$PDF_OUTPUT_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    printf '\n===== [%d/%d] %s =====\n' &amp;quot;$INDEX&amp;quot; &amp;quot;$TOTAL&amp;quot; &amp;quot;$PDF_FILE&amp;quot; \&lt;br /&gt;
        | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    set +e&lt;br /&gt;
    python3 &amp;quot;$PYTHON_SCRIPT&amp;quot; \&lt;br /&gt;
        &amp;quot;$PDF_FILE&amp;quot; \&lt;br /&gt;
        --output-dir &amp;quot;$PDF_OUTPUT_DIR&amp;quot; \&lt;br /&gt;
        --overwrite 2&amp;gt;&amp;amp;1 | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
    EXIT_CODE=${PIPESTATUS[0]}&lt;br /&gt;
    set -e&lt;br /&gt;
&lt;br /&gt;
    if (( EXIT_CODE == 0 )); then&lt;br /&gt;
        printf 'SUCCESS\t%s\t%s\n' &amp;quot;$PDF_FILE&amp;quot; &amp;quot;$PDF_OUTPUT_DIR&amp;quot; \&lt;br /&gt;
            &amp;gt;&amp;gt; &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
        ((SUCCESS += 1))&lt;br /&gt;
        log &amp;quot;BERHASIL: $PDF_FILE&amp;quot; | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        printf 'FAILED(%d)\t%s\t%s\n' &amp;quot;$EXIT_CODE&amp;quot; &amp;quot;$PDF_FILE&amp;quot; &amp;quot;$PDF_OUTPUT_DIR&amp;quot; \&lt;br /&gt;
            &amp;gt;&amp;gt; &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
        ((FAILED += 1))&lt;br /&gt;
        log &amp;quot;GAGAL (exit $EXIT_CODE): $PDF_FILE&amp;quot; | tee -a &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
printf '\n=== Ringkasan batch ===\n'&lt;br /&gt;
printf 'Total PDF : %d\n' &amp;quot;$TOTAL&amp;quot;&lt;br /&gt;
printf 'Berhasil  : %d\n' &amp;quot;$SUCCESS&amp;quot;&lt;br /&gt;
printf 'Gagal     : %d\n' &amp;quot;$FAILED&amp;quot;&lt;br /&gt;
printf 'Output    : %s\n' &amp;quot;$OUTPUT_DIR&amp;quot;&lt;br /&gt;
printf 'Ringkasan : %s\n' &amp;quot;$SUMMARY_FILE&amp;quot;&lt;br /&gt;
printf 'Log       : %s\n' &amp;quot;$LOG_FILE&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(( FAILED == 0 ))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:47:44 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Batch_pdf_to_md.sh</comments>
		</item>
		<item>
			<title>MCP: Convert PDF ke .md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73719&amp;oldid=73718</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73719&amp;oldid=73718</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 01:45, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l4&quot; &gt;Line 4:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 4:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download shell script]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/&lt;/del&gt;batch_pdf_to_md.sh&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download shell script]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[[&lt;/ins&gt;batch_pdf_to_md.sh&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download Python script dengan nama sederhana]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/&lt;/del&gt;pdf_to_rag_md.py&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [Download Python script dengan nama sederhana]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[[&lt;/ins&gt;pdf_to_rag_md.py&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;### Instalasi&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;### Instalasi&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:45:10 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Convert_PDF_ke_.md</comments>
		</item>
		<item>
			<title>MCP: Convert PDF ke .md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73718&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Convert_PDF_ke_.md&amp;diff=73718&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Shell script sudah dibuat berdasarkan opsi CLI pada Python terlampir.   ### File  * [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip) * [Download shell s...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Shell script sudah dibuat berdasarkan opsi CLI pada Python terlampir. &lt;br /&gt;
&lt;br /&gt;
### File&lt;br /&gt;
&lt;br /&gt;
* [Download paket lengkap ZIP](sandbox:/mnt/data/pdf_batch_converter.zip)&lt;br /&gt;
* [Download shell script](sandbox:/mnt/data/batch_pdf_to_md.sh)&lt;br /&gt;
* [Download Python script dengan nama sederhana](sandbox:/mnt/data/pdf_to_rag_md.py)&lt;br /&gt;
&lt;br /&gt;
### Instalasi&lt;br /&gt;
&lt;br /&gt;
Letakkan `batch_pdf_to_md.sh` dan `pdf_to_rag_md.py` dalam folder yang sama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod +x batch_pdf_to_md.sh&lt;br /&gt;
chmod +x pdf_to_rag_md.py&lt;br /&gt;
&lt;br /&gt;
python3 -m pip install pymupdf pyyaml&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### Menjalankan&lt;br /&gt;
&lt;br /&gt;
Output otomatis ditempatkan di subfolder `output`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh /opt/ai-stack/documents&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dengan folder output khusus:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh \&lt;br /&gt;
  /opt/ai-stack/documents \&lt;br /&gt;
  /opt/ai-stack/output&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atau menentukan lokasi Python script secara eksplisit:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./batch_pdf_to_md.sh \&lt;br /&gt;
  /opt/ai-stack/documents \&lt;br /&gt;
  /opt/ai-stack/output \&lt;br /&gt;
  /opt/scripts/pdf_to_rag_md.py&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Script akan:&lt;br /&gt;
&lt;br /&gt;
1. Menampilkan semua file dalam path input.&lt;br /&gt;
2. Mencari seluruh PDF secara rekursif, termasuk subfolder.&lt;br /&gt;
3. Menjalankan Python converter untuk setiap PDF.&lt;br /&gt;
4. Membuat folder output terpisah untuk setiap PDF agar `manifest.json` tidak saling menimpa.&lt;br /&gt;
5. Membuat `batch_conversion.log`.&lt;br /&gt;
6. Membuat `batch_summary.tsv` berisi status berhasil atau gagal.&lt;br /&gt;
&lt;br /&gt;
Contoh hasil:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/output/&lt;br /&gt;
├── Buku Pertama/&lt;br /&gt;
│   ├── Buku Pertama 01 Topik.md&lt;br /&gt;
│   ├── Buku Pertama 02 Topik.md&lt;br /&gt;
│   └── manifest.json&lt;br /&gt;
├── AI/&lt;br /&gt;
│   └── Buku Kedua/&lt;br /&gt;
│       ├── Buku Kedua 01 Topik.md&lt;br /&gt;
│       └── manifest.json&lt;br /&gt;
├── batch_conversion.log&lt;br /&gt;
└── batch_summary.tsv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Shell script tersebut sudah diuji dengan beberapa PDF, nama file yang mengandung spasi, dan PDF di dalam subfolder.&lt;/div&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:44:24 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Convert_PDF_ke_.md</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73717&amp;oldid=73709</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73717&amp;oldid=73709</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;MCP&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 01:44, 26 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l89&quot; &gt;Line 89:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 89:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[MCP: Instalasi]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Convert PDF ke .md]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 26 Jul 2026 01:44:11 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>Pdf to rag md.py</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Pdf_to_rag_md.py&amp;diff=73716&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Pdf_to_rag_md.py&amp;diff=73716&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;&amp;lt;pre&amp;gt; #!/usr/bin/env python3 &amp;quot;&amp;quot;&amp;quot; Convert a text-based PDF into RAG-friendly Markdown files, one file per topic.  Main features ------------- - Uses the PDF table of contents w...&amp;quot;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=Pdf_to_rag_md.py&amp;amp;diff=73716&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Fri, 24 Jul 2026 21:03:25 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Pdf_to_rag_md.py</comments>
		</item>
		<item>
			<title>Requirements-pdf-to-rag-md.txt</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Requirements-pdf-to-rag-md.txt&amp;diff=73715&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Requirements-pdf-to-rag-md.txt&amp;diff=73715&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot; pymupdf&amp;gt;=1.26,&amp;lt;2  pyyaml&amp;gt;=6,&amp;lt;7&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt; pymupdf&amp;gt;=1.26,&amp;lt;2&lt;br /&gt;
 pyyaml&amp;gt;=6,&amp;lt;7&lt;/div&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:57:25 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Requirements-pdf-to-rag-md.txt</comments>
		</item>
		<item>
			<title>RAG: PDF to md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73714&amp;oldid=73712</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73714&amp;oldid=73712</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 20:56, 24 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-multi&quot; lang=&quot;en&quot;&gt;(One intermediate revision by the same user not shown)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot; &gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;## File Python&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;## File Python&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Unduh `&lt;/del&gt;pdf_to_rag_md.py&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;`&lt;/del&gt;]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/pdf_to_rag_md.py)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[&lt;/ins&gt;pdf_to_rag_md.py]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Unduh `&lt;/del&gt;requirements-pdf-to-rag-md.txt&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;`&lt;/del&gt;]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(sandbox:/mnt/data/requirements-pdf-to-rag-md.txt)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[&lt;/ins&gt;requirements-pdf-to-rag-md.txt]&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Skrip sudah diperiksa dengan `py_compile` dan diuji pada:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Skrip sudah diperiksa dengan `py_compile` dan diuji pada:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:56:52 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:RAG:_PDF_to_md</comments>
		</item>
		<item>
			<title>RAG: PDF to md</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73712&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=RAG:_PDF_to_md&amp;diff=73712&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;## File Python  * [Unduh `pdf_to_rag_md.py`](sandbox:/mnt/data/pdf_to_rag_md.py) * [Unduh `requirements-pdf-to-rag-md.txt`](sandbox:/mnt/data/requirements-pdf-to-rag-md.txt)...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;## File Python&lt;br /&gt;
&lt;br /&gt;
* [Unduh `pdf_to_rag_md.py`](sandbox:/mnt/data/pdf_to_rag_md.py)&lt;br /&gt;
* [Unduh `requirements-pdf-to-rag-md.txt`](sandbox:/mnt/data/requirements-pdf-to-rag-md.txt)&lt;br /&gt;
&lt;br /&gt;
Skrip sudah diperiksa dengan `py_compile` dan diuji pada:&lt;br /&gt;
&lt;br /&gt;
* PDF dengan bookmark dan struktur heading.&lt;br /&gt;
* PDF tanpa heading, menggunakan fallback setiap lima halaman.&lt;br /&gt;
&lt;br /&gt;
## Instalasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p ~/Apps/pdf-to-rag&lt;br /&gt;
cd ~/Apps/pdf-to-rag&lt;br /&gt;
&lt;br /&gt;
python3 -m venv .venv&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
pip install --upgrade pip&lt;br /&gt;
pip install -r requirements-pdf-to-rag-md.txt&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Menjalankan&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menentukan folder output:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot; \&lt;br /&gt;
    --output-dir hasil-rag&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menambahkan tag metadata:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot; \&lt;br /&gt;
    --tags &amp;quot;RAG,AI,LLM,dokumentasi&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika folder output sudah ada:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python pdf_to_rag_md.py &amp;quot;Judul Buku.pdf&amp;quot; \&lt;br /&gt;
    --overwrite&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Format filename&lt;br /&gt;
&lt;br /&gt;
Untuk PDF yang memiliki heading:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Judul Buku 01 BAB 1 Pendahuluan.md&lt;br /&gt;
Judul Buku 02 1.1 Latar Belakang.md&lt;br /&gt;
Judul Buku 03 1.2 Tujuan.md&lt;br /&gt;
Judul Buku 04 BAB 2 Metode.md&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika PDF tidak memiliki heading, otomatis fallback per lima halaman:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Judul Buku 01 Bagian Halaman 1-5.md&lt;br /&gt;
Judul Buku 02 Bagian Halaman 6-10.md&lt;br /&gt;
Judul Buku 03 Bagian Halaman 11-15.md&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Judul buku diambil secara berurutan dari:&lt;br /&gt;
&lt;br /&gt;
1. Metadata title PDF.&lt;br /&gt;
2. Teks judul dengan font terbesar pada halaman awal.&lt;br /&gt;
3. Nama file PDF.&lt;br /&gt;
&lt;br /&gt;
## Konten yang dibuang&lt;br /&gt;
&lt;br /&gt;
Secara default, skrip membuang:&lt;br /&gt;
&lt;br /&gt;
* Gambar dan blok nonteks.&lt;br /&gt;
* Caption `Gambar`, `Figure`, atau `Fig`.&lt;br /&gt;
* Baris `Sumber:` dan `Source:` pada caption.&lt;br /&gt;
* Nomor halaman.&lt;br /&gt;
* Header dan footer berulang.&lt;br /&gt;
* Footnote yang terdeteksi di bagian bawah halaman.&lt;br /&gt;
* Daftar isi.&lt;br /&gt;
* Daftar gambar dan daftar tabel.&lt;br /&gt;
* Daftar istilah dan glosarium.&lt;br /&gt;
* Daftar singkatan, simbol, dan nomenklatur.&lt;br /&gt;
* Indeks.&lt;br /&gt;
* Daftar pustaka, bibliography, dan references.&lt;br /&gt;
* Kata pengantar, prakata, dan foreword.&lt;br /&gt;
* Ucapan terima kasih.&lt;br /&gt;
* Tentang penulis.&lt;br /&gt;
* Halaman sampul dan copyright yang terdeteksi.&lt;br /&gt;
* Karakter tersembunyi, soft hyphen, dan spasi berlebihan.&lt;br /&gt;
&lt;br /&gt;
## Metadata pada setiap file Markdown&lt;br /&gt;
&lt;br /&gt;
Setiap file memiliki YAML front matter seperti:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
---&lt;br /&gt;
schema_version: '1.0'&lt;br /&gt;
document_id: pdf-914f553ce7c36f8704e4&lt;br /&gt;
topic_id: pdf-914f553ce7c36f8704e4-topic-0001&lt;br /&gt;
chunk_id: pdf-914f553ce7c36f8704e4-topic-0001&lt;br /&gt;
&lt;br /&gt;
book_title: Buku Uji RAG&lt;br /&gt;
title: BAB 1 Pendahuluan&lt;br /&gt;
topic: BAB 1 Pendahuluan&lt;br /&gt;
topic_index: 1&lt;br /&gt;
&lt;br /&gt;
language: id&lt;br /&gt;
tags:&lt;br /&gt;
  - RAG&lt;br /&gt;
  - AI&lt;br /&gt;
&lt;br /&gt;
source:&lt;br /&gt;
  file: Buku Uji RAG.pdf&lt;br /&gt;
  sha256: 914f553ce7c36f8704e412b1fcb51b90&lt;br /&gt;
  page_start: 3&lt;br /&gt;
  page_end: 8&lt;br /&gt;
  pages:&lt;br /&gt;
    - 3&lt;br /&gt;
    - 4&lt;br /&gt;
    - 5&lt;br /&gt;
    - 6&lt;br /&gt;
    - 7&lt;br /&gt;
    - 8&lt;br /&gt;
  trace: Buku Uji RAG.pdf#page=3-8&lt;br /&gt;
  pdf_title: Buku Uji RAG&lt;br /&gt;
  pdf_author: Nama Penulis&lt;br /&gt;
&lt;br /&gt;
rag:&lt;br /&gt;
  unit: topic&lt;br /&gt;
  filename_pattern: Judul Buku 00 Topik.md&lt;br /&gt;
  topic_detection: pdf_toc&lt;br /&gt;
  word_count: 1450&lt;br /&gt;
  character_count: 9860&lt;br /&gt;
  content_sha256: 76a95b85fe3c9e48882c351138aa5f86&lt;br /&gt;
  suggested_splitter: markdown_headers_then_token_window&lt;br /&gt;
&lt;br /&gt;
extraction:&lt;br /&gt;
  engine: PyMuPDF&lt;br /&gt;
  images: ignored&lt;br /&gt;
  figure_captions: removed&lt;br /&gt;
  junk_sections: removed&lt;br /&gt;
  standalone_page_number_filter: enabled&lt;br /&gt;
  footnote_filter: bottom_position_and_small_font&lt;br /&gt;
&lt;br /&gt;
output_file: Buku Uji RAG 01 BAB 1 Pendahuluan.md&lt;br /&gt;
generated_at: '2026-07-25T03:00:00+00:00'&lt;br /&gt;
---&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Skrip juga menghasilkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
manifest.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Manifest berisi daftar semua topik, filename, rentang halaman, metode pendeteksian topik, hash dokumen, dan halaman nonkonten yang dibuang.&lt;br /&gt;
&lt;br /&gt;
PDF hasil scan yang tidak memiliki selectable text harus menjalani OCR terlebih dahulu.&lt;/div&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:54:35 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:RAG:_PDF_to_md</comments>
		</item>
		<item>
			<title>RAG</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=RAG&amp;diff=73711&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=RAG&amp;diff=73711&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;   ==Pranala Menarik==  * &lt;a href=&quot;/wiki/index.php/RAG:_PDF_to_md&quot; title=&quot;RAG: PDF to md&quot;&gt;RAG: PDF to md&lt;/a&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Pranala Menarik==&lt;br /&gt;
&lt;br /&gt;
* [[RAG: PDF to md]]&lt;/div&gt;</description>
			<pubDate>Fri, 24 Jul 2026 20:53:52 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:RAG</comments>
		</item>
		<item>
			<title>MCP: Instalasi</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi&amp;diff=73710&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi&amp;diff=73710&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# PANDUAN INSTALASI LOCAL AI STACK BERBASIS DOCKER  ## Ollama + Open WebUI + AnythingLLM + MCP + n8n  **Perangkat:**  ```text Laptop       : Dell RAM          : 16 GB GPU...&amp;quot;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=MCP:_Instalasi&amp;amp;diff=73710&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Fri, 24 Jul 2026 09:56:10 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:MCP:_Instalasi</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73709&amp;oldid=73706</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73709&amp;oldid=73706</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ComfyUI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 03:47, 24 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l85&quot; &gt;Line 85:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 85:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Text to Speech]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Text to Speech]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==MCP==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[MCP: Instalasi]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Fri, 24 Jul 2026 03:47:33 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>ComfyUI: Text to Speech</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73708&amp;oldid=73707</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73708&amp;oldid=73707</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;amp;diff=73708&amp;amp;oldid=73707&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Fri, 24 Jul 2026 02:38:57 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Text_to_Speech</comments>
		</item>
		<item>
			<title>ComfyUI: Text to Speech</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73707&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Text_to_Speech&amp;diff=73707&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Saya sudah membuat workflow **Text-to-Speech Bahasa Indonesia** paling sederhana:  [Download workflow JSON ComfyUI TTS Indonesia](sandbox:/mnt/data/comfyui_tts_bahasa_indonesi...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Saya sudah membuat workflow **Text-to-Speech Bahasa Indonesia** paling sederhana:&lt;br /&gt;
&lt;br /&gt;
[Download workflow JSON ComfyUI TTS Indonesia](sandbox:/mnt/data/comfyui_tts_bahasa_indonesia_sederhana.json)&lt;br /&gt;
&lt;br /&gt;
Workflow hanya menggunakan dua node:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Edge TTS → Save Audio&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Node menggunakan suara perempuan Indonesia **Gadis**, kecepatan normal, dan menyimpan hasil sebagai WAV. Custom node tersebut juga menyediakan suara laki-laki Indonesia **Ardi**, serta pengaturan kecepatan dan tinggi nada. ([GitHub][1])&lt;br /&gt;
&lt;br /&gt;
## 1. Instal custom node&lt;br /&gt;
&lt;br /&gt;
Pada server:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose exec -u root comfyui bash -lc '&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
cd /opt/ComfyUI/custom_nodes&lt;br /&gt;
&lt;br /&gt;
if [ ! -d ComfyUI-EdgeTTS ]; then&lt;br /&gt;
    git clone https://github.com/1038lab/ComfyUI-EdgeTTS.git&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
python -m pip install --no-cache-dir \&lt;br /&gt;
    -r ComfyUI-EdgeTTS/requirements.txt&lt;br /&gt;
'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Repositori resminya memang mengarahkan instalasi ke folder `custom_nodes`, dilanjutkan dengan pemasangan `requirements.txt`. ([GitHub][2])&lt;br /&gt;
&lt;br /&gt;
Periksa apakah berhasil:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cari apakah node berikut berhasil dimuat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
EdgeTTS&lt;br /&gt;
Save_Audio&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 2. Upload workflow&lt;br /&gt;
&lt;br /&gt;
Buka:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.230:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian seret file berikut ke canvas ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui_tts_bahasa_indonesia_sederhana.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Workflow JSON merupakan format resmi untuk menyimpan graph, node, widget, dan hubungan antar-node ComfyUI. ([ComfyUI][3])&lt;br /&gt;
&lt;br /&gt;
## 3. Jalankan TTS&lt;br /&gt;
&lt;br /&gt;
Pada node **Edge TTS**, ubah teks:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Halo, selamat datang. Ini adalah contoh text to speech sederhana dalam Bahasa Indonesia menggunakan ComfyUI.&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Suara default:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
[Indonesian] id-ID Gadis&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk suara laki-laki, pilih:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
[Indonesian] id-ID Ardi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lalu tekan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ctrl + Enter&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
atau klik **Queue**.&lt;br /&gt;
&lt;br /&gt;
## 4. Lokasi hasil&lt;br /&gt;
&lt;br /&gt;
File akan tersimpan sebagai:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ComfyUI/output/TTS/indonesia-0001.wav&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Nomor akan bertambah otomatis:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
indonesia-0002.wav&lt;br /&gt;
indonesia-0003.wav&lt;br /&gt;
indonesia-0004.wav&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Node `Save_Audio` memang menyimpan keluaran di direktori output ComfyUI dan memberikan nomor urut ketika opsi overwrite dimatikan. ([GitHub][4])&lt;br /&gt;
&lt;br /&gt;
**Catatan:** workflow ini menggunakan layanan Microsoft Edge TTS secara online, sehingga container ComfyUI memerlukan akses internet ketika menghasilkan suara. Tidak memerlukan API key. ([GitHub][5])&lt;br /&gt;
&lt;br /&gt;
[1]: https://github.com/1038lab/ComfyUI-EdgeTTS/blob/main/ailab_edgeTTS.py &amp;quot;ComfyUI-EdgeTTS/ailab_edgeTTS.py at main · 1038lab/ComfyUI-EdgeTTS · GitHub&amp;quot;&lt;br /&gt;
[2]: https://github.com/1038lab/ComfyUI-EdgeTTS &amp;quot;GitHub - 1038lab/ComfyUI-EdgeTTS: ComfyUI-EdgeTTS is a powerful text-to-speech node for ComfyUI, leveraging Microsoft's Edge TTS capabilities. It enables seamless conversion of text into natural-sounding speech, supporting multiple languages and voices. Ideal for enhancing user interactions, this node is easy to integrate and customize, making it perfect for various applications. · GitHub&amp;quot;&lt;br /&gt;
[3]: https://docs.comfy.org/specs/workflow_json_0.4?utm_source=chatgpt.com &amp;quot;Workflow JSON 0.4 - ComfyUI&amp;quot;&lt;br /&gt;
[4]: https://github.com/1038lab/ComfyUI-EdgeTTS/blob/main/ailab_audio.py &amp;quot;ComfyUI-EdgeTTS/ailab_audio.py at main · 1038lab/ComfyUI-EdgeTTS · GitHub&amp;quot;&lt;br /&gt;
[5]: https://github.com/rany2/edge-tts?utm_source=chatgpt.com &amp;quot;GitHub - rany2/edge-tts: Use Microsoft Edge's online text-to-speech service from Python WITHOUT needing Microsoft Edge or Windows or an API key · GitHub&amp;quot;&lt;/div&gt;</description>
			<pubDate>Thu, 23 Jul 2026 23:43:35 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Text_to_Speech</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73706&amp;oldid=73704</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73706&amp;oldid=73704</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ComfyUI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 23:43, 23 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l84&quot; &gt;Line 84:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 84:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[ComfyUI: Text to Speech]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Thu, 23 Jul 2026 23:43:30 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + ComfyUI docker</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM:_Ubuntu_26.04_server_Ollama_GPU_%2B_Open-WebUI_%2B_n8n_%2B_WAHA_%2B_ComfyUI_docker&amp;diff=73705&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM:_Ubuntu_26.04_server_Ollama_GPU_%2B_Open-WebUI_%2B_n8n_%2B_WAHA_%2B_ComfyUI_docker&amp;diff=73705&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;# Instalasi AI Stack di Ubuntu Server 26.04  Target perangkat:  * Laptop Dell * NVIDIA GeForce RTX 4060 Laptop GPU 8 GB * Ubuntu Server 26.04 * Docker Engine + Docker Compose...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# Instalasi AI Stack di Ubuntu Server 26.04&lt;br /&gt;
&lt;br /&gt;
Target perangkat:&lt;br /&gt;
&lt;br /&gt;
* Laptop Dell&lt;br /&gt;
* NVIDIA GeForce RTX 4060 Laptop GPU 8 GB&lt;br /&gt;
* Ubuntu Server 26.04&lt;br /&gt;
* Docker Engine + Docker Compose&lt;br /&gt;
* Ollama memakai GPU&lt;br /&gt;
* ComfyUI memakai GPU&lt;br /&gt;
* Open WebUI **tanpa GPU**&lt;br /&gt;
* n8n tanpa GPU&lt;br /&gt;
* WAHA tanpa GPU&lt;br /&gt;
&lt;br /&gt;
Karena bagian “gunakan folder awal …” belum lengkap, panduan ini memakai:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Docker secara resmi sudah mencantumkan Ubuntu 26.04 LTS sebagai sistem yang didukung. ([Docker Documentation][1])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 1. Arsitektur akhir&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/&lt;br /&gt;
├── .env&lt;br /&gt;
├── compose.yaml&lt;br /&gt;
├── ollama/&lt;br /&gt;
├── open-webui/&lt;br /&gt;
├── n8n/&lt;br /&gt;
├── waha/&lt;br /&gt;
│   ├── .env&lt;br /&gt;
│   ├── sessions/&lt;br /&gt;
│   └── media/&lt;br /&gt;
└── comfyui/&lt;br /&gt;
    ├── Dockerfile&lt;br /&gt;
    ├── models/&lt;br /&gt;
    │   ├── checkpoints/&lt;br /&gt;
    │   ├── vae/&lt;br /&gt;
    │   ├── loras/&lt;br /&gt;
    │   ├── clip/&lt;br /&gt;
    │   ├── controlnet/&lt;br /&gt;
    │   └── upscale_models/&lt;br /&gt;
    ├── input/&lt;br /&gt;
    ├── output/&lt;br /&gt;
    ├── custom_nodes/&lt;br /&gt;
    └── user/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Port yang digunakan:&lt;br /&gt;
&lt;br /&gt;
| Aplikasi   |  Port | Alamat                              |&lt;br /&gt;
| ---------- | ----: | ----------------------------------- |&lt;br /&gt;
| Open WebUI |  3000 | `http://IP-SERVER:3000`             |&lt;br /&gt;
| n8n        |  5678 | `http://IP-SERVER:5678`             |&lt;br /&gt;
| WAHA       |  3001 | `http://IP-SERVER:3001/dashboard`   |&lt;br /&gt;
| ComfyUI    |  8188 | `http://IP-SERVER:8188`             |&lt;br /&gt;
| Ollama     | 11434 | Hanya localhost dan jaringan Docker |&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN A — PERSIAPAN UBUNTU&lt;br /&gt;
&lt;br /&gt;
## 2. Update Ubuntu Server&lt;br /&gt;
&lt;br /&gt;
Masuk melalui terminal atau SSH, kemudian jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt full-upgrade -y&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Instal paket dasar:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y \&lt;br /&gt;
  ca-certificates \&lt;br /&gt;
  curl \&lt;br /&gt;
  gnupg \&lt;br /&gt;
  git \&lt;br /&gt;
  openssl \&lt;br /&gt;
  ubuntu-drivers-common \&lt;br /&gt;
  ufw&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Reboot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo reboot&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah server hidup kembali, login lagi melalui SSH.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN B — DRIVER NVIDIA RTX 4060&lt;br /&gt;
&lt;br /&gt;
## 3. Pastikan GPU terdeteksi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
lspci | grep -i nvidia&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh hasil:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NVIDIA Corporation AD107M [GeForce RTX 4060 Max-Q / Mobile]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat driver yang tersedia:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ubuntu-drivers list --gpgpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk server AI/headless, instal driver komputasi yang direkomendasikan otomatis:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ubuntu-drivers install --gpgpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ubuntu merekomendasikan `ubuntu-drivers` karena alat ini memilih paket driver yang sesuai dan mendukung penggunaan Secure Boot melalui modul yang ditandatangani. ([Ubuntu][2])&lt;br /&gt;
&lt;br /&gt;
Reboot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo reboot&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Periksa driver NVIDIA&lt;br /&gt;
&lt;br /&gt;
Setelah login kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar kurang lebih seperti:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NVIDIA-SMI ...&lt;br /&gt;
Driver Version: ...&lt;br /&gt;
CUDA Version: ...&lt;br /&gt;
NVIDIA GeForce RTX 4060 Laptop GPU&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jangan lanjut ke instalasi Docker GPU sebelum `nvidia-smi` berhasil.&lt;br /&gt;
&lt;br /&gt;
Apabila muncul:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa Secure Boot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mokutil --sb-state&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pada beberapa laptop, Secure Boot harus dinonaktifkan melalui BIOS atau kunci MOK driver harus dikonfirmasi ketika boot.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN C — INSTALASI DOCKER&lt;br /&gt;
&lt;br /&gt;
## 5. Hapus paket Docker lama yang mungkin konflik&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
for pkg in \&lt;br /&gt;
  docker.io \&lt;br /&gt;
  docker-doc \&lt;br /&gt;
  docker-compose \&lt;br /&gt;
  docker-compose-v2 \&lt;br /&gt;
  podman-docker \&lt;br /&gt;
  containerd \&lt;br /&gt;
  runc&lt;br /&gt;
do&lt;br /&gt;
  sudo apt remove -y &amp;quot;$pkg&amp;quot; 2&amp;gt;/dev/null || true&lt;br /&gt;
done&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Docker menyarankan menghapus paket distribusi yang dapat bertabrakan dengan Docker Engine resmi. ([Docker Documentation][1])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Tambahkan repository resmi Docker&lt;br /&gt;
&lt;br /&gt;
Buat direktori keyring:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ambil kunci resmi Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo curl -fsSL \&lt;br /&gt;
  https://download.docker.com/linux/ubuntu/gpg \&lt;br /&gt;
  -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur agar kunci dapat dibaca APT:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tambahkan repository Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;gt;/dev/null &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Update repository:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Instal Docker Engine dan Docker Compose&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y \&lt;br /&gt;
  docker-ce \&lt;br /&gt;
  docker-ce-cli \&lt;br /&gt;
  containerd.io \&lt;br /&gt;
  docker-buildx-plugin \&lt;br /&gt;
  docker-compose-plugin&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan Docker saat boot:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl enable --now docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa status:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl status docker --no-pager&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo docker run --rm hello-world&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Izinkan user menjalankan Docker tanpa sudo&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo usermod -aG docker &amp;quot;$USER&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Arti opsi:&lt;br /&gt;
&lt;br /&gt;
* `-a` berarti menambahkan user tanpa menghapus grup yang sudah dimiliki.&lt;br /&gt;
* `-G docker` berarti menambahkan user ke grup Docker.&lt;br /&gt;
&lt;br /&gt;
Logout dari SSH:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
exit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Login kembali, kemudian periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker version&lt;br /&gt;
docker compose version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji kembali tanpa `sudo`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm hello-world&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN D — NVIDIA CONTAINER TOOLKIT&lt;br /&gt;
&lt;br /&gt;
## 9. Tambahkan repository NVIDIA Container Toolkit&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \&lt;br /&gt;
  | sudo gpg --dearmor \&lt;br /&gt;
  -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tambahkan repository:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -fsSL \&lt;br /&gt;
  https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \&lt;br /&gt;
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \&lt;br /&gt;
  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Update APT:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Instal NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasikan Docker agar mengenali NVIDIA Runtime:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Restart Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Langkah tersebut mengikuti prosedur NVIDIA untuk mengaktifkan GPU di dalam container Docker. ([NVIDIA Docs][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Uji GPU dari dalam Docker&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm --gpus all ubuntu:24.04 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan RTX 4060 muncul di hasil perintah.&lt;br /&gt;
&lt;br /&gt;
Ollama juga menyarankan pengujian GPU Docker sebelum mencoba menjalankan model. Ollama membutuhkan NVIDIA Container Toolkit untuk akselerasi NVIDIA di Docker. ([Ollama][4])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN E — MEMBUAT STRUKTUR FOLDER&lt;br /&gt;
&lt;br /&gt;
## 11. Buat folder utama&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo mkdir -p /opt/ai-stack&lt;br /&gt;
sudo chown -R &amp;quot;$USER&amp;quot;:&amp;quot;$USER&amp;quot; /opt/ai-stack&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat folder data:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p \&lt;br /&gt;
  ollama \&lt;br /&gt;
  open-webui \&lt;br /&gt;
  n8n \&lt;br /&gt;
  waha/sessions \&lt;br /&gt;
  waha/media \&lt;br /&gt;
  comfyui/input \&lt;br /&gt;
  comfyui/output \&lt;br /&gt;
  comfyui/custom_nodes \&lt;br /&gt;
  comfyui/user&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat folder model ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p \&lt;br /&gt;
  comfyui/models/checkpoints \&lt;br /&gt;
  comfyui/models/vae \&lt;br /&gt;
  comfyui/models/loras \&lt;br /&gt;
  comfyui/models/clip \&lt;br /&gt;
  comfyui/models/controlnet \&lt;br /&gt;
  comfyui/models/upscale_models&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur kepemilikan folder n8n. Container resmi n8n berjalan dengan UID `1000`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chown -R 1000:1000 /opt/ai-stack/n8n&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat struktur:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
find /opt/ai-stack -maxdepth 3 -type d | sort&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN F — KONFIGURASI RAHASIA&lt;br /&gt;
&lt;br /&gt;
## 12. Cari IP server&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
SERVER_IP=$(ip route get 1.1.1.1 | awk '{print $7; exit}')&lt;br /&gt;
echo &amp;quot;$SERVER_IP&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa juga dengan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
hostname -I&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila ada beberapa IP, gunakan IP LAN yang dipakai komputer lain untuk mengakses server.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 13. Buat file `.env` utama&lt;br /&gt;
&lt;br /&gt;
Pastikan sedang di:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat konfigurasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
SERVER_IP=$(ip route get 1.1.1.1 | awk '{print $7; exit}')&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; .env &amp;lt;&amp;lt;EOF&lt;br /&gt;
SERVER_IP=${SERVER_IP}&lt;br /&gt;
WEBUI_SECRET_KEY=$(openssl rand -hex 32)&lt;br /&gt;
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Amankan file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod 600 .env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat .env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
SERVER_IP=192.168.0.100&lt;br /&gt;
WEBUI_SECRET_KEY=...&lt;br /&gt;
N8N_ENCRYPTION_KEY=...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN G — KONFIGURASI WAHA&lt;br /&gt;
&lt;br /&gt;
## 14. Generate konfigurasi WAHA&lt;br /&gt;
&lt;br /&gt;
WAHA menyediakan perintah `init-waha` untuk membuat username, password dashboard, dan API key secara acak. ([GitHub][5])&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
docker run --rm \&lt;br /&gt;
  -v &amp;quot;$PWD/waha:/app/env&amp;quot; \&lt;br /&gt;
  devlikeapro/waha:latest \&lt;br /&gt;
  init-waha /app/env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Biasanya terdapat variabel seperti:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
WAHA_API_KEY=...&lt;br /&gt;
WAHA_DASHBOARD_USERNAME=...&lt;br /&gt;
WAHA_DASHBOARD_PASSWORD=...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Amankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
chmod 600 waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Atur alamat eksternal WAHA agar menggunakan port host `3001`:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
SERVER_IP=$(grep '^SERVER_IP=' .env | cut -d= -f2)&lt;br /&gt;
&lt;br /&gt;
if grep -q '^WAHA_BASE_URL=' waha/.env; then&lt;br /&gt;
  sed -i \&lt;br /&gt;
    &amp;quot;s#^WAHA_BASE_URL=.*#WAHA_BASE_URL=http://${SERVER_IP}:3001#&amp;quot; \&lt;br /&gt;
    waha/.env&lt;br /&gt;
else&lt;br /&gt;
  echo &amp;quot;WAHA_BASE_URL=http://${SERVER_IP}:3001&amp;quot; &amp;gt;&amp;gt; waha/.env&lt;br /&gt;
fi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
grep -E 'WAHA_BASE_URL|WAHA_DASHBOARD_USERNAME|WAHA_API_KEY' waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
WAHA menyimpan sesi pada `/app/.sessions` dan media pada `/app/.media`; kedua lokasi ini akan dipetakan ke folder host agar tidak hilang saat container dibuat ulang. ([GitHub][6])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN H — DOCKERFILE COMFYUI&lt;br /&gt;
&lt;br /&gt;
## 15. Buat Dockerfile ComfyUI&lt;br /&gt;
&lt;br /&gt;
Panduan ini membangun image dari repository resmi ComfyUI dan memasang PyTorch CUDA. Repository resmi ComfyUI berada di organisasi Comfy-Org. ([GitHub][7])&lt;br /&gt;
&lt;br /&gt;
Buat file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; comfyui/Dockerfile &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
FROM nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04&lt;br /&gt;
&lt;br /&gt;
ENV DEBIAN_FRONTEND=noninteractive&lt;br /&gt;
ENV PIP_NO_CACHE_DIR=1&lt;br /&gt;
ENV PYTHONUNBUFFERED=1&lt;br /&gt;
ENV PATH=&amp;quot;/opt/venv/bin:${PATH}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends \&lt;br /&gt;
    ca-certificates \&lt;br /&gt;
    git \&lt;br /&gt;
    curl \&lt;br /&gt;
    ffmpeg \&lt;br /&gt;
    build-essential \&lt;br /&gt;
    python3 \&lt;br /&gt;
    python3-dev \&lt;br /&gt;
    python3-pip \&lt;br /&gt;
    python3-venv \&lt;br /&gt;
    libgl1 \&lt;br /&gt;
    libglib2.0-0 \&lt;br /&gt;
    libsm6 \&lt;br /&gt;
    libxext6 \&lt;br /&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;br /&gt;
&lt;br /&gt;
RUN python3 -m venv /opt/venv \&lt;br /&gt;
    &amp;amp;&amp;amp; pip install --upgrade pip setuptools wheel&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt&lt;br /&gt;
&lt;br /&gt;
RUN git clone --depth 1 \&lt;br /&gt;
    https://github.com/Comfy-Org/ComfyUI.git \&lt;br /&gt;
    /opt/ComfyUI&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt/ComfyUI&lt;br /&gt;
&lt;br /&gt;
RUN pip install \&lt;br /&gt;
    torch \&lt;br /&gt;
    torchvision \&lt;br /&gt;
    torchaudio \&lt;br /&gt;
    --index-url https://download.pytorch.org/whl/cu128&lt;br /&gt;
&lt;br /&gt;
RUN pip install -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
EXPOSE 8188&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;main.py&amp;quot;, \&lt;br /&gt;
     &amp;quot;--listen&amp;quot;, &amp;quot;0.0.0.0&amp;quot;, \&lt;br /&gt;
     &amp;quot;--port&amp;quot;, &amp;quot;8188&amp;quot;, \&lt;br /&gt;
     &amp;quot;--preview-method&amp;quot;, &amp;quot;auto&amp;quot;]&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
PyTorch menyediakan paket CUDA untuk Linux melalui indeks wheel CUDA yang sesuai. ([PyTorch Documentation][8])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN I — DOCKER COMPOSE&lt;br /&gt;
&lt;br /&gt;
## 16. Buat file `compose.yaml`&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
cat &amp;gt; compose.yaml &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
name: ai-stack&lt;br /&gt;
&lt;br /&gt;
services:&lt;br /&gt;
&lt;br /&gt;
  ollama:&lt;br /&gt;
    image: ollama/ollama:latest&lt;br /&gt;
    container_name: ollama&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;127.0.0.1:11434:11434&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./ollama:/root/.ollama&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      OLLAMA_HOST: &amp;quot;0.0.0.0:11434&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      # Lepaskan model dari VRAM setelah tidak digunakan.&lt;br /&gt;
      OLLAMA_KEEP_ALIVE: &amp;quot;5m&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      # RTX 4060 Laptop hanya memiliki VRAM 8 GB.&lt;br /&gt;
      OLLAMA_MAX_LOADED_MODELS: &amp;quot;1&amp;quot;&lt;br /&gt;
      OLLAMA_NUM_PARALLEL: &amp;quot;1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    deploy:&lt;br /&gt;
      resources:&lt;br /&gt;
        reservations:&lt;br /&gt;
          devices:&lt;br /&gt;
            - driver: nvidia&lt;br /&gt;
              count: all&lt;br /&gt;
              capabilities:&lt;br /&gt;
                - gpu&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  open-webui:&lt;br /&gt;
    image: ghcr.io/open-webui/open-webui:main&lt;br /&gt;
    container_name: open-webui&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - ollama&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3000:8080&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./open-webui:/app/backend/data&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      OLLAMA_BASE_URL: &amp;quot;http://ollama:11434&amp;quot;&lt;br /&gt;
      WEBUI_SECRET_KEY: &amp;quot;${WEBUI_SECRET_KEY}&amp;quot;&lt;br /&gt;
      TZ: &amp;quot;Asia/Jakarta&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  n8n:&lt;br /&gt;
    image: docker.n8n.io/n8nio/n8n:latest&lt;br /&gt;
    container_name: n8n&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;5678:5678&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./n8n:/home/node/.n8n&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      N8N_HOST: &amp;quot;${SERVER_IP}&amp;quot;&lt;br /&gt;
      N8N_PORT: &amp;quot;5678&amp;quot;&lt;br /&gt;
      N8N_PROTOCOL: &amp;quot;http&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      N8N_EDITOR_BASE_URL: &amp;quot;http://${SERVER_IP}:5678/&amp;quot;&lt;br /&gt;
      WEBHOOK_URL: &amp;quot;http://${SERVER_IP}:5678/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      N8N_ENCRYPTION_KEY: &amp;quot;${N8N_ENCRYPTION_KEY}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      # Diperlukan karena akses masih menggunakan HTTP lokal.&lt;br /&gt;
      # Ubah menjadi true setelah memakai HTTPS.&lt;br /&gt;
      N8N_SECURE_COOKIE: &amp;quot;false&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: &amp;quot;true&amp;quot;&lt;br /&gt;
      N8N_DIAGNOSTICS_ENABLED: &amp;quot;false&amp;quot;&lt;br /&gt;
      N8N_PERSONALIZATION_ENABLED: &amp;quot;false&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      GENERIC_TIMEZONE: &amp;quot;Asia/Jakarta&amp;quot;&lt;br /&gt;
      TZ: &amp;quot;Asia/Jakarta&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  waha:&lt;br /&gt;
    image: devlikeapro/waha:latest&lt;br /&gt;
    container_name: waha&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3001:3000&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    env_file:&lt;br /&gt;
      - ./waha/.env&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./waha/sessions:/app/.sessions&lt;br /&gt;
      - ./waha/media:/app/.media&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  comfyui:&lt;br /&gt;
    build:&lt;br /&gt;
      context: ./comfyui&lt;br /&gt;
      dockerfile: Dockerfile&lt;br /&gt;
&lt;br /&gt;
    image: local/comfyui:cu128&lt;br /&gt;
    container_name: comfyui&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;8188:8188&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./comfyui/models:/opt/ComfyUI/models&lt;br /&gt;
      - ./comfyui/input:/opt/ComfyUI/input&lt;br /&gt;
      - ./comfyui/output:/opt/ComfyUI/output&lt;br /&gt;
      - ./comfyui/custom_nodes:/opt/ComfyUI/custom_nodes&lt;br /&gt;
      - ./comfyui/user:/opt/ComfyUI/user&lt;br /&gt;
&lt;br /&gt;
    shm_size: &amp;quot;4gb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    deploy:&lt;br /&gt;
      resources:&lt;br /&gt;
        reservations:&lt;br /&gt;
          devices:&lt;br /&gt;
            - driver: nvidia&lt;br /&gt;
              count: all&lt;br /&gt;
              capabilities:&lt;br /&gt;
                - gpu&lt;br /&gt;
&lt;br /&gt;
    networks:&lt;br /&gt;
      - ai-net&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  ai-net:&lt;br /&gt;
    name: ai-net&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasi tersebut memastikan:&lt;br /&gt;
&lt;br /&gt;
* Ollama memperoleh akses GPU.&lt;br /&gt;
* ComfyUI memperoleh akses GPU.&lt;br /&gt;
* Open WebUI memakai image `main`, bukan image `cuda`.&lt;br /&gt;
* Open WebUI tidak mendapat reservasi perangkat GPU.&lt;br /&gt;
* n8n dan WAHA tidak mendapat reservasi perangkat GPU.&lt;br /&gt;
* Semua aplikasi dapat berkomunikasi melalui jaringan `ai-net`.&lt;br /&gt;
&lt;br /&gt;
Open WebUI mendokumentasikan image `main` untuk instalasi biasa dan koneksi ke Ollama menggunakan `OLLAMA_BASE_URL`; image `cuda` hanya diperlukan bila Open WebUI sendiri membutuhkan GPU. ([Open WebUI][9])&lt;br /&gt;
&lt;br /&gt;
n8n merekomendasikan Docker untuk sebagian besar instalasi self-hosted karena dependensi aplikasi dapat diisolasi dari sistem operasi. ([n8n Documentation][10])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 17. Validasi Docker Compose&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose config&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila tidak muncul pesan error, konfigurasi YAML valid.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN J — MENJALANKAN STACK&lt;br /&gt;
&lt;br /&gt;
## 18. Download image aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose pull&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Perintah ini menarik image:&lt;br /&gt;
&lt;br /&gt;
* Ollama&lt;br /&gt;
* Open WebUI&lt;br /&gt;
* n8n&lt;br /&gt;
* WAHA&lt;br /&gt;
&lt;br /&gt;
ComfyUI akan dibangun secara lokal.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 19. Build ComfyUI&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose build --pull comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa image yang dibuat:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker images | grep comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
local/comfyui    cu128&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 20. Jalankan semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa container:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
NAME          STATUS&lt;br /&gt;
ollama        Up&lt;br /&gt;
open-webui    Up&lt;br /&gt;
n8n           Up&lt;br /&gt;
waha          Up&lt;br /&gt;
comfyui       Up&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 21. Periksa log&lt;br /&gt;
&lt;br /&gt;
Semua aplikasi:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Open WebUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 open-webui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
n8n:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 n8n&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
WAHA:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 waha&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log secara langsung:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs -f comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tekan `Ctrl+C` untuk keluar dari tampilan log. Container tetap berjalan.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN K — PENGUJIAN&lt;br /&gt;
&lt;br /&gt;
## 22. Uji Ollama&lt;br /&gt;
&lt;br /&gt;
Periksa API:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl http://127.0.0.1:11434/api/tags&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa GPU dari container Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec ollama nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Download contoh model ringan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec -it ollama ollama pull llama3.2:3b&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan model:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec -it ollama ollama run llama3.2:3b&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ollama mendokumentasikan penggunaan container resmi `ollama/ollama`, akses GPU NVIDIA, dan perintah `docker exec ... ollama run`. ([Ollama][11])&lt;br /&gt;
&lt;br /&gt;
Keluar dari chat Ollama dengan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/bye&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa model:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec ollama ollama list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 23. Buka Open WebUI&lt;br /&gt;
&lt;br /&gt;
Dari komputer lain pada jaringan yang sama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:3000&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.100:3000&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Akun pertama yang dibuat akan menjadi administrator.&lt;br /&gt;
&lt;br /&gt;
Open WebUI sudah diarahkan ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://ollama:11434&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jadi tidak perlu memasukkan alamat Ollama secara manual.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 24. Buka n8n&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:5678&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.100:5678&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Buat akun administrator n8n melalui halaman awal.&lt;br /&gt;
&lt;br /&gt;
Dari node HTTP Request di n8n, alamat internal yang dapat digunakan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ollama:&lt;br /&gt;
http://ollama:11434&lt;br /&gt;
&lt;br /&gt;
WAHA:&lt;br /&gt;
http://waha:3000&lt;br /&gt;
&lt;br /&gt;
Open WebUI:&lt;br /&gt;
http://open-webui:8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh endpoint Ollama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://ollama:11434/api/generate&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh endpoint WAHA:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://waha:3000/api/sendText&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 25. Buka WAHA&lt;br /&gt;
&lt;br /&gt;
Dashboard:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:3001/dashboard&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Swagger/API:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:3001&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lihat username dan password:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
grep -E \&lt;br /&gt;
  'WAHA_DASHBOARD_USERNAME|WAHA_DASHBOARD_PASSWORD|WAHA_API_KEY' \&lt;br /&gt;
  /opt/ai-stack/waha/.env&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Masuk ke dashboard, buat sesi `default`, kemudian scan QR menggunakan WhatsApp pada telepon.&lt;br /&gt;
&lt;br /&gt;
WAHA menggunakan QR untuk menghubungkan sesi dan menyediakan endpoint HTTP untuk mengirim pesan. ([GitHub][5])&lt;br /&gt;
&lt;br /&gt;
**Catatan penting:** WAHA merupakan klien otomatisasi tidak resmi. Dokumentasi WAHA sendiri menjelaskan bahwa WhatsApp tidak mengizinkan bot atau klien tidak resmi sehingga penggunaannya tidak sepenuhnya aman dari pemblokiran akun. Gunakan nomor pengujian atau nomor nonkritis dan jangan melakukan spam. ([WAHA][12])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 26. Buka ComfyUI&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://IP-SERVER:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.100:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa apakah PyTorch mendeteksi GPU:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec comfyui python -c \&lt;br /&gt;
'import torch; print(&amp;quot;CUDA:&amp;quot;, torch.cuda.is_available()); print(&amp;quot;GPU:&amp;quot;, torch.cuda.get_device_name(0) if torch.cuda.is_available() else &amp;quot;Tidak terdeteksi&amp;quot;)'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
CUDA: True&lt;br /&gt;
GPU: NVIDIA GeForce RTX 4060 Laptop GPU&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN L — MEMASUKKAN MODEL COMFYUI&lt;br /&gt;
&lt;br /&gt;
## 27. Copy checkpoint Stable Diffusion&lt;br /&gt;
&lt;br /&gt;
Misalnya model berada pada:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
~/Downloads/DreamShaper_8_pruned.safetensors&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Copy:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cp \&lt;br /&gt;
  ~/Downloads/DreamShaper_8_pruned.safetensors \&lt;br /&gt;
  /opt/ai-stack/comfyui/models/checkpoints/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lh /opt/ai-stack/comfyui/models/checkpoints/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Restart ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lokasi umum model:&lt;br /&gt;
&lt;br /&gt;
| Jenis      | Folder                           |&lt;br /&gt;
| ---------- | -------------------------------- |&lt;br /&gt;
| Checkpoint | `comfyui/models/checkpoints/`    |&lt;br /&gt;
| LoRA       | `comfyui/models/loras/`          |&lt;br /&gt;
| VAE        | `comfyui/models/vae/`            |&lt;br /&gt;
| CLIP       | `comfyui/models/clip/`           |&lt;br /&gt;
| ControlNet | `comfyui/models/controlnet/`     |&lt;br /&gt;
| Upscaler   | `comfyui/models/upscale_models/` |&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN M — PENGELOLAAN GPU 8 GB&lt;br /&gt;
&lt;br /&gt;
## 28. Hindari Ollama dan ComfyUI memakai VRAM berat bersamaan&lt;br /&gt;
&lt;br /&gt;
RTX 4060 memiliki VRAM 8 GB. Ollama dan ComfyUI boleh hidup bersamaan, tetapi model baru memakai banyak VRAM ketika sedang dimuat.&lt;br /&gt;
&lt;br /&gt;
Konfigurasi berikut sudah membantu Ollama melepaskan model setelah lima menit:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
OLLAMA_KEEP_ALIVE: &amp;quot;5m&amp;quot;&lt;br /&gt;
OLLAMA_MAX_LOADED_MODELS: &amp;quot;1&amp;quot;&lt;br /&gt;
OLLAMA_NUM_PARALLEL: &amp;quot;1&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa pemakaian GPU:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
watch -n 1 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Keluar dengan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ctrl+C&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Apabila ComfyUI mengalami `CUDA out of memory`, hentikan Ollama sementara:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose stop ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali setelah selesai memakai ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sebaliknya, untuk memberikan GPU sepenuhnya kepada Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN N — FIREWALL&lt;br /&gt;
&lt;br /&gt;
## 29. Batasi akses hanya dari jaringan lokal&lt;br /&gt;
&lt;br /&gt;
Contoh jaringan lokal:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
192.168.0.0/24&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan SSH terlebih dahulu:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow OpenSSH&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan Open WebUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 3000 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan n8n:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 5678 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan WAHA:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 3001 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Izinkan ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw allow from 192.168.0.0/24 to any port 8188 proto tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Aktifkan firewall:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw enable&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo ufw status numbered&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Port Ollama tidak perlu dibuka karena dipetakan hanya ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
127.0.0.1:11434&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Open WebUI dan n8n tetap dapat mengakses Ollama melalui jaringan internal Docker.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN O — PERINTAH OPERASIONAL&lt;br /&gt;
&lt;br /&gt;
## 30. Start semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 31. Stop semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
docker compose stop&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 32. Start kembali&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 33. Restart semua aplikasi&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 34. Hapus container tanpa menghapus data&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose down&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Folder data tetap berada di `/opt/ai-stack`.&lt;br /&gt;
&lt;br /&gt;
Jalankan kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 35. Periksa status&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## 36. Periksa penggunaan resource&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker stats&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN P — UPDATE&lt;br /&gt;
&lt;br /&gt;
## 37. Update Ollama, Open WebUI, n8n, dan WAHA&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Open WebUI menyarankan memakai tag versi tertentu untuk lingkungan produksi daripada selalu memakai tag bergerak seperti `main`. Setelah sistem stabil, image sebaiknya dipasangi nomor versi agar update tidak mendadak mengubah perilaku aplikasi. ([Open WebUI][9])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 38. Update ComfyUI&lt;br /&gt;
&lt;br /&gt;
Karena source ComfyUI diambil saat proses build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
docker compose build \&lt;br /&gt;
  --pull \&lt;br /&gt;
  --no-cache \&lt;br /&gt;
  comfyui&lt;br /&gt;
&lt;br /&gt;
docker compose up -d comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# BAGIAN Q — TROUBLESHOOTING&lt;br /&gt;
&lt;br /&gt;
## 39. Docker tidak mendeteksi GPU&lt;br /&gt;
&lt;br /&gt;
Pesan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
could not select device driver &amp;quot;nvidia&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm --gpus all ubuntu:24.04 nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 40. n8n mengalami `permission denied`&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo chown -R 1000:1000 /opt/ai-stack/n8n&lt;br /&gt;
docker compose restart n8n&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 41. Open WebUI tidak menemukan Ollama&lt;br /&gt;
&lt;br /&gt;
Periksa Ollama:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps ollama&lt;br /&gt;
docker compose logs --tail=100 ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Uji melalui jaringan Docker:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm \&lt;br /&gt;
  --network ai-net \&lt;br /&gt;
  curlimages/curl:latest \&lt;br /&gt;
  http://ollama:11434/api/tags&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa konfigurasi Open WebUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker inspect open-webui \&lt;br /&gt;
  --format '{{range .Config.Env}}{{println .}}{{end}}' \&lt;br /&gt;
  | grep OLLAMA&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang benar:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OLLAMA_BASE_URL=http://ollama:11434&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 42. ComfyUI kehabisan VRAM&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hentikan Ollama sementara:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop ollama&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Gunakan model lebih ringan atau kurangi resolusi gambar.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 43. WAHA kehilangan sesi setelah restart&lt;br /&gt;
&lt;br /&gt;
Periksa pemetaan volume:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker inspect waha \&lt;br /&gt;
  --format '{{json .Mounts}}' \&lt;br /&gt;
  | python3 -m json.tool&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pastikan terdapat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/ai-stack/waha/sessions -&amp;gt; /app/.sessions&lt;br /&gt;
/opt/ai-stack/waha/media    -&amp;gt; /app/.media&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa folder:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -lah /opt/ai-stack/waha/sessions&lt;br /&gt;
ls -lah /opt/ai-stack/waha/media&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Checklist akhir&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /opt/ai-stack&lt;br /&gt;
&lt;br /&gt;
nvidia-smi&lt;br /&gt;
docker version&lt;br /&gt;
docker compose version&lt;br /&gt;
docker compose ps&lt;br /&gt;
curl http://127.0.0.1:11434/api/tags&lt;br /&gt;
docker exec comfyui python -c 'import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil akhir yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Ollama      : GPU RTX 4060&lt;br /&gt;
ComfyUI     : GPU RTX 4060&lt;br /&gt;
Open WebUI  : CPU, terhubung ke Ollama&lt;br /&gt;
n8n         : CPU&lt;br /&gt;
WAHA        : CPU&lt;br /&gt;
Data        : tersimpan di /opt/ai-stack&lt;br /&gt;
Timezone    : Asia/Jakarta&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
[1]: https://docs.docker.com/engine/install/ubuntu/ &amp;quot;Install Docker Engine on Ubuntu | Docker Docs&amp;quot;&lt;br /&gt;
[2]: https://ubuntu.com/server/docs/how-to/graphics/install-nvidia-drivers/ &amp;quot;NVIDIA drivers installation - Ubuntu Server documentation&amp;quot;&lt;br /&gt;
[3]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html &amp;quot;Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit&amp;quot;&lt;br /&gt;
[4]: https://docs.ollama.com/troubleshooting?utm_source=chatgpt.com &amp;quot;Troubleshooting - Ollama&amp;quot;&lt;br /&gt;
[5]: https://github.com/devlikeapro/waha-docs/blob/main/content//docs/overview/quick-start/index.md &amp;quot;waha-docs/content/docs/overview/quick-start/index.md at main · devlikeapro/waha-docs · GitHub&amp;quot;&lt;br /&gt;
[6]: https://github.com/devlikeapro/waha/blob/core/docker-compose.yaml &amp;quot;waha/docker-compose.yaml at core · devlikeapro/waha · GitHub&amp;quot;&lt;br /&gt;
[7]: https://github.com/comfyanonymous &amp;quot;comfyanonymous (comfyanonymous) · GitHub&amp;quot;&lt;br /&gt;
[8]: https://docs.pytorch.org/get-started/locally/?utm_source=chatgpt.com &amp;quot;Start Locally | PyTorch&amp;quot;&lt;br /&gt;
[9]: https://docs.openwebui.com/getting-started/quick-start/ &amp;quot;Quick Start / Open WebUI&amp;quot;&lt;br /&gt;
[10]: https://docs.n8n.io/deploy/host-n8n/install-options/install-with-docker?utm_source=chatgpt.com &amp;quot;Install with Docker | Deploy&amp;quot;&lt;br /&gt;
[11]: https://docs.ollama.com/docker?utm_source=chatgpt.com &amp;quot;Docker - Ollama&amp;quot;&lt;br /&gt;
[12]: https://waha.devlike.pro/docs/overview/introduction/?utm_source=chatgpt.com &amp;quot;📖 Introduction | WAHA&amp;quot;&lt;/div&gt;</description>
			<pubDate>Thu, 23 Jul 2026 18:10:39 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM:_Ubuntu_26.04_server_Ollama_GPU_%2B_Open-WebUI_%2B_n8n_%2B_WAHA_%2B_ComfyUI_docker</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73704&amp;oldid=73701</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73704&amp;oldid=73701</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Pranala Menarik&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:10, 23 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l44&quot; &gt;Line 44:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 44:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: docker shell access]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: docker shell access]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + ComfyUI docker]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh docker]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh docker]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh + Webmail docker]] '''NOT RECOMMEND'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[LLM: Ubuntu 26.04 server Ollama GPU + Open-WebUI + n8n + WAHA + Wazuh + Webmail docker]] '''NOT RECOMMEND'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Thu, 23 Jul 2026 18:10:23 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<item>
			<title>ComfyUI: Instalasi via docker compose</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73703&amp;oldid=73702</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73703&amp;oldid=73702</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;amp;diff=73703&amp;amp;oldid=73702&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Tue, 21 Jul 2026 11:39:13 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Instalasi_via_docker_compose</comments>
		</item>
		<item>
			<title>ComfyUI: Instalasi via docker compose</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73702&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ComfyUI:_Instalasi_via_docker_compose&amp;diff=73702&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;## Menambahkan ComfyUI ke Docker Compose yang sudah ada  Cara yang relatif aman adalah **membangun image ComfyUI sendiri dari repositori resmi**, bukan memakai image komunitas...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;## Menambahkan ComfyUI ke Docker Compose yang sudah ada&lt;br /&gt;
&lt;br /&gt;
Cara yang relatif aman adalah **membangun image ComfyUI sendiri dari repositori resmi**, bukan memakai image komunitas yang isinya tidak selalu jelas. Instalasi resmi ComfyUI menggunakan repositori `Comfy-Org/ComfyUI`, memasang PyTorch dan `requirements.txt`, lalu menjalankan `main.py`. ComfyUI-Manager sekarang diaktifkan melalui `manager_requirements.txt` dan parameter `--enable-manager`. ([GitHub][1])&lt;br /&gt;
&lt;br /&gt;
Struktur akhirnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
local-ai/&lt;br /&gt;
├── compose.yaml&lt;br /&gt;
└── comfyui/&lt;br /&gt;
    ├── Dockerfile&lt;br /&gt;
    ├── .dockerignore&lt;br /&gt;
    └── data/&lt;br /&gt;
        ├── models/&lt;br /&gt;
        ├── input/&lt;br /&gt;
        ├── output/&lt;br /&gt;
        ├── custom_nodes/&lt;br /&gt;
        ├── user/&lt;br /&gt;
        └── cache/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### 1. Pastikan GPU NVIDIA dapat digunakan Docker&lt;br /&gt;
&lt;br /&gt;
Periksa driver:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa NVIDIA Container Toolkit:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dpkg -l | grep nvidia-container-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika belum terpasang:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \&lt;br /&gt;
  | sudo gpg --dearmor \&lt;br /&gt;
  -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \&lt;br /&gt;
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \&lt;br /&gt;
  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-container-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Konfigurasikan runtime NVIDIA:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo nvidia-ctk runtime configure --runtime=docker&lt;br /&gt;
sudo systemctl restart docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Itu adalah prosedur resmi NVIDIA untuk Debian dan Ubuntu. ([NVIDIA Docs][2])&lt;br /&gt;
&lt;br /&gt;
Tes akses GPU dari container:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker run --rm --gpus all \&lt;br /&gt;
  nvidia/cuda:12.9.0-base-ubuntu22.04 \&lt;br /&gt;
  nvidia-smi&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Walaupun host memakai Ubuntu 24.04, container boleh menggunakan basis Ubuntu 22.04.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 2. Buat direktori ComfyUI&lt;br /&gt;
&lt;br /&gt;
Masuk ke direktori tempat `compose.yaml` berada:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd ~/Apps/LocalAI&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sesuaikan apabila lokasi compose berbeda.&lt;br /&gt;
&lt;br /&gt;
Buat struktur folder:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p comfyui/data/{input,output,custom_nodes,user,cache}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p comfyui/data/models/{checkpoints,vae,loras,controlnet,clip,clip_vision,diffusion_models,text_encoders,unet,upscale_models,embeddings}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Periksa:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
find comfyui -maxdepth 3 -type d&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 3. Buat Dockerfile ComfyUI&lt;br /&gt;
&lt;br /&gt;
Buat file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nano comfyui/Dockerfile&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
```dockerfile&lt;br /&gt;
FROM python:3.12-slim-bookworm&lt;br /&gt;
&lt;br /&gt;
ENV DEBIAN_FRONTEND=noninteractive \&lt;br /&gt;
    PYTHONUNBUFFERED=1 \&lt;br /&gt;
    PIP_NO_CACHE_DIR=1&lt;br /&gt;
&lt;br /&gt;
# Paket sistem yang diperlukan ComfyUI dan berbagai custom node.&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends \&lt;br /&gt;
    git \&lt;br /&gt;
    ca-certificates \&lt;br /&gt;
    curl \&lt;br /&gt;
    ffmpeg \&lt;br /&gt;
    build-essential \&lt;br /&gt;
    libgl1 \&lt;br /&gt;
    libglib2.0-0 \&lt;br /&gt;
    libgomp1 \&lt;br /&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt&lt;br /&gt;
&lt;br /&gt;
# Mengambil ComfyUI dari repositori resmi.&lt;br /&gt;
RUN git clone --depth 1 https://github.com/Comfy-Org/ComfyUI.git&lt;br /&gt;
&lt;br /&gt;
WORKDIR /opt/ComfyUI&lt;br /&gt;
&lt;br /&gt;
# Memasang PyTorch dengan dukungan NVIDIA CUDA 12.8.&lt;br /&gt;
RUN python -m pip install --upgrade pip setuptools wheel \&lt;br /&gt;
    &amp;amp;&amp;amp; python -m pip install \&lt;br /&gt;
       torch torchvision torchaudio \&lt;br /&gt;
       --index-url https://download.pytorch.org/whl/cu128 \&lt;br /&gt;
    &amp;amp;&amp;amp; python -m pip install -r requirements.txt \&lt;br /&gt;
    &amp;amp;&amp;amp; python -m pip install -r manager_requirements.txt&lt;br /&gt;
&lt;br /&gt;
EXPOSE 8188&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;main.py&amp;quot;, \&lt;br /&gt;
     &amp;quot;--listen&amp;quot;, &amp;quot;0.0.0.0&amp;quot;, \&lt;br /&gt;
     &amp;quot;--port&amp;quot;, &amp;quot;8188&amp;quot;, \&lt;br /&gt;
     &amp;quot;--enable-manager&amp;quot;, \&lt;br /&gt;
     &amp;quot;--preview-method&amp;quot;, &amp;quot;auto&amp;quot;]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
CUDA 12.8 dipilih karena cocok untuk keluarga GPU NVIDIA modern seperti Turing, Ampere, dan Blackwell, termasuk RTX 20, RTX 30, RTX 40, dan RTX 50. PyTorch masih menyediakan wheel CUDA 12.8 secara terpisah. ([GitHub][3])&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 4. Buat `.dockerignore`&lt;br /&gt;
&lt;br /&gt;
Ini penting agar file model yang ukurannya puluhan gigabyte tidak ikut dikirim sebagai Docker build context.&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
nano comfyui/.dockerignore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
data/&lt;br /&gt;
__pycache__/&lt;br /&gt;
*.pyc&lt;br /&gt;
*.pyo&lt;br /&gt;
.git/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 5. Tambahkan service ComfyUI ke `compose.yaml`&lt;br /&gt;
&lt;br /&gt;
Tambahkan bagian berikut **setelah service `waha` tetapi sebelum bagian paling bawah `volumes:`**:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
  ################################&lt;br /&gt;
  # 5. COMFYUI (Image Generation)&lt;br /&gt;
  ################################&lt;br /&gt;
  comfyui:&lt;br /&gt;
    build:&lt;br /&gt;
      context: ./comfyui&lt;br /&gt;
      dockerfile: Dockerfile&lt;br /&gt;
    image: local/comfyui:cu128&lt;br /&gt;
    container_name: comfyui&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;192.168.0.230:8188:8188&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    environment:&lt;br /&gt;
      - TZ=Asia/Jakarta&lt;br /&gt;
      - NVIDIA_VISIBLE_DEVICES=all&lt;br /&gt;
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility&lt;br /&gt;
&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./comfyui/data/models:/opt/ComfyUI/models&lt;br /&gt;
      - ./comfyui/data/input:/opt/ComfyUI/input&lt;br /&gt;
      - ./comfyui/data/output:/opt/ComfyUI/output&lt;br /&gt;
      - ./comfyui/data/custom_nodes:/opt/ComfyUI/custom_nodes&lt;br /&gt;
      - ./comfyui/data/user:/opt/ComfyUI/user&lt;br /&gt;
      - ./comfyui/data/cache:/root/.cache&lt;br /&gt;
&lt;br /&gt;
    shm_size: &amp;quot;8gb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    deploy:&lt;br /&gt;
      resources:&lt;br /&gt;
        reservations:&lt;br /&gt;
          devices:&lt;br /&gt;
            - driver: nvidia&lt;br /&gt;
              count: all&lt;br /&gt;
              capabilities: [&amp;quot;gpu&amp;quot;]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Bagian akhir compose tetap seperti sebelumnya:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
volumes:&lt;br /&gt;
  ollama_data:&lt;br /&gt;
  openwebui_data:&lt;br /&gt;
  n8n_data:&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tidak perlu menambahkan `comfyui_data` karena ComfyUI menggunakan bind mount ke direktori `./comfyui/data`.&lt;br /&gt;
&lt;br /&gt;
Docker Compose memang mendukung reservasi GPU melalui `deploy.resources.reservations.devices`, dan `capabilities: [&amp;quot;gpu&amp;quot;]` wajib dicantumkan. ([Docker Documentation][4])&lt;br /&gt;
&lt;br /&gt;
### Tentang pengaturan port&lt;br /&gt;
&lt;br /&gt;
Baris ini:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
ports:&lt;br /&gt;
  - &amp;quot;192.168.0.230:8188:8188&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
berarti ComfyUI hanya mendengarkan melalui alamat LAN server `192.168.0.230`.&lt;br /&gt;
&lt;br /&gt;
Apabila alamat server berbeda, ubah IP tersebut. Untuk membuka melalui seluruh interface, gunakan:&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
ports:&lt;br /&gt;
  - &amp;quot;8188:8188&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Namun ComfyUI sebaiknya tidak langsung dibuka ke internet, terutama ketika Manager aktif karena Manager dapat memasang dan menjalankan kode dari custom node.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 6. Validasi YAML&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose config&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika tidak ada pesan kesalahan, build hanya service ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose build comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose up -d comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Keterangan:&lt;br /&gt;
&lt;br /&gt;
* `up` membuat dan menjalankan container.&lt;br /&gt;
* `-d` menjalankan container di belakang layar.&lt;br /&gt;
* `comfyui` berarti hanya service ComfyUI yang dijalankan.&lt;br /&gt;
&lt;br /&gt;
Periksa status:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose ps&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Seharusnya terdapat:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui    running    192.168.0.230:8188-&amp;gt;8188/tcp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 7. Periksa log ComfyUI&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose logs -f --tail=100 comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cari informasi seperti:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Device: cuda:0&lt;br /&gt;
Using pytorch attention&lt;br /&gt;
Starting server&lt;br /&gt;
To see the GUI go to: http://0.0.0.0:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tekan `Ctrl+C` untuk keluar dari tampilan log. Container tetap berjalan.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 8. Verifikasi PyTorch dan GPU&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker exec comfyui python -c \&lt;br /&gt;
'import torch; print(&amp;quot;CUDA tersedia:&amp;quot;, torch.cuda.is_available()); print(&amp;quot;PyTorch:&amp;quot;, torch.__version__); print(&amp;quot;CUDA:&amp;quot;, torch.version.cuda); print(&amp;quot;GPU:&amp;quot;, torch.cuda.get_device_name(0) if torch.cuda.is_available() else &amp;quot;Tidak ada&amp;quot;)'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil yang diharapkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
CUDA tersedia: True&lt;br /&gt;
PyTorch: 2.x.x&lt;br /&gt;
CUDA: 12.8&lt;br /&gt;
GPU: NVIDIA GeForce RTX ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 9. Buka ComfyUI&lt;br /&gt;
&lt;br /&gt;
Dari komputer dalam jaringan yang sama:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
http://192.168.0.230:8188&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
ComfyUI tidak menyertakan checkpoint model secara otomatis. Tempatkan file model `*.safetensors` di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui/data/models/checkpoints/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
VAE ditempatkan di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui/data/models/vae/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
LoRA ditempatkan di:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
comfyui/data/models/loras/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lokasi checkpoint dan VAE tersebut sesuai struktur model resmi ComfyUI. ([GitHub][1])&lt;br /&gt;
&lt;br /&gt;
Setelah memasukkan model, restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## 10. Perintah operasional&lt;br /&gt;
&lt;br /&gt;
Menghentikan ComfyUI saja:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menjalankannya kembali:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Restart:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Menghapus container tanpa menghapus model dan hasil gambar:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose rm -sf comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Membangun ulang ComfyUI versi terbaru:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose build --no-cache comfyui&lt;br /&gt;
docker compose up -d comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
`--no-cache` memaksa Docker mengambil ulang kode dan memasang ulang dependency, bukan menggunakan layer build lama.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Jika VRAM tidak cukup&lt;br /&gt;
&lt;br /&gt;
Ollama dan ComfyUI memakai GPU NVIDIA yang sama. Ketika model Ollama masih berada di VRAM, ComfyUI dapat mengalami:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
CUDA out of memory&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Untuk pengujian, hentikan Ollama sementara:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose stop ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jalankan ComfyUI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose restart comfyui&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Setelah selesai membuat gambar:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
docker compose start ollama&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Terakhir, sebaiknya pindahkan `WHATSAPP_API_KEY`, password dashboard WAHA, dan password Swagger dari YAML ke file `.env`, serta ganti nilai password yang saat ini masih sederhana sebelum server dapat diakses pengguna lain.&lt;br /&gt;
&lt;br /&gt;
[1]: https://github.com/comfy-org/ComfyUI &amp;quot;GitHub - Comfy-Org/ComfyUI: The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface. · GitHub&amp;quot;&lt;br /&gt;
[2]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/1.17.7/install-guide.html &amp;quot;Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit&amp;quot;&lt;br /&gt;
[3]: https://github.com/pytorch/pytorch/releases?utm_source=chatgpt.com &amp;quot;Releases · pytorch/pytorch&amp;quot;&lt;br /&gt;
[4]: https://docs.docker.com/compose/how-tos/gpu-support/ &amp;quot;Run Docker Compose services with GPU access | Docker Docs&amp;quot;&lt;/div&gt;</description>
			<pubDate>Tue, 21 Jul 2026 09:17:44 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ComfyUI:_Instalasi_via_docker_compose</comments>
		</item>
		<item>
			<title>LLM</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73701&amp;oldid=73666</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=LLM&amp;diff=73701&amp;oldid=73666</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;ComfyUI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 09:13, 21 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l82&quot; &gt;Line 82:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 82:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[ComfyUI: Instalasi venv GPU]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* [[ComfyUI: Instalasi via docker compose]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Nvidia==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 21 Jul 2026 09:13:23 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:LLM</comments>
		</item>
		<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>
		<item>
			<title>DVWP</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=DVWP&amp;diff=73697&amp;oldid=73696</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=DVWP&amp;diff=73697&amp;oldid=73696</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:21, 4 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-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;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;Ahh siap — &lt;/del&gt;'''DVWP = Damn Vulnerable WordPress'''.&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;'''DVWP = Damn Vulnerable WordPress'''.&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;DVWP lebih realistis dibanding DVWA untuk latihan WordPress security, karena kamu belajar hal-hal yang sering muncul di pentest WordPress sungguhan: plugin, theme, `/wp-admin`, `/wp-login.php`, `/wp-content/`, XML-RPC, plugin vulnerable, file terbuka, credential lemah, dan salah konfigurasi.&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;DVWP lebih realistis dibanding DVWA untuk latihan WordPress security, karena kamu belajar hal-hal yang sering muncul di pentest WordPress sungguhan: plugin, theme, `/wp-admin`, `/wp-login.php`, `/wp-content/`, XML-RPC, plugin vulnerable, file terbuka, credential lemah, dan salah konfigurasi.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sat, 04 Jul 2026 01:21:07 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:DVWP</comments>
		</item>
		<item>
			<title>DVWP</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=DVWP&amp;diff=73696&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=DVWP&amp;diff=73696&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Ahh siap — &amp;#039;&amp;#039;&amp;#039;DVWP = Damn Vulnerable WordPress&amp;#039;&amp;#039;&amp;#039;.  DVWP lebih realistis dibanding DVWA untuk latihan WordPress security, karena kamu belajar hal-hal yang sering muncul di p...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Ahh siap — '''DVWP = Damn Vulnerable WordPress'''.&lt;br /&gt;
&lt;br /&gt;
DVWP lebih realistis dibanding DVWA untuk latihan WordPress security, karena kamu belajar hal-hal yang sering muncul di pentest WordPress sungguhan: plugin, theme, `/wp-admin`, `/wp-login.php`, `/wp-content/`, XML-RPC, plugin vulnerable, file terbuka, credential lemah, dan salah konfigurasi.&lt;br /&gt;
&lt;br /&gt;
== 1. Aturan utama: jalankan hanya di lab lokal==&lt;br /&gt;
&lt;br /&gt;
Gunakan DVWP hanya di lingkungan sendiri:&lt;br /&gt;
&lt;br /&gt;
 Kali Linux       = mesin attacker / latihan&lt;br /&gt;
 DVWP WordPress   = target vulnerable&lt;br /&gt;
 Network          = localhost / host-only / private VM network&lt;br /&gt;
&lt;br /&gt;
Jangan expose DVWP ke internet publik. Karena ini memang sengaja vulnerable.&lt;br /&gt;
&lt;br /&gt;
== 2. Tujuan awal: pahami struktur WordPress==&lt;br /&gt;
&lt;br /&gt;
Sebelum menyerang apa pun, buka websitenya manual dulu dan pahami struktur WordPress:&lt;br /&gt;
&lt;br /&gt;
 /wp-login.php        → halaman login&lt;br /&gt;
 /wp-admin/           → dashboard admin&lt;br /&gt;
 /wp-content/         → tempat theme, plugin, upload&lt;br /&gt;
 /wp-content/plugins/ → plugin yang terpasang&lt;br /&gt;
 /wp-content/themes/  → theme yang terpasang&lt;br /&gt;
 /xmlrpc.php          → endpoint XML-RPC WordPress&lt;br /&gt;
 /wp-json/            → REST API WordPress&lt;br /&gt;
&lt;br /&gt;
Dalam pentest WordPress, banyak celah berasal dari '''plugin dan theme''', bukan hanya dari WordPress core.&lt;br /&gt;
&lt;br /&gt;
== 3. Recon dasar dari Kali Linux==&lt;br /&gt;
&lt;br /&gt;
Misalnya DVWP kamu jalan di:&lt;br /&gt;
&lt;br /&gt;
 http://127.0.0.1:31337&lt;br /&gt;
&lt;br /&gt;
Mulai dari cek service:&lt;br /&gt;
&lt;br /&gt;
 nmap -sV -p 31337,31338 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
Artinya:&lt;br /&gt;
&lt;br /&gt;
 -sV       = deteksi service dan versinya&lt;br /&gt;
 -p        = scan hanya port tertentu&lt;br /&gt;
 127.0.0.1 = mesin lokal&lt;br /&gt;
&lt;br /&gt;
Lalu cek response web:&lt;br /&gt;
&lt;br /&gt;
 curl -I http://127.0.0.1:31337&lt;br /&gt;
&lt;br /&gt;
Artinya:&lt;br /&gt;
&lt;br /&gt;
 -I = hanya tampilkan HTTP header&lt;br /&gt;
&lt;br /&gt;
Ini membiasakan kamu untuk mengamati dulu sebelum langsung pakai tool besar.&lt;br /&gt;
&lt;br /&gt;
== 4. Gunakan WPScan, tapi jangan bergantung 100% pada tool==&lt;br /&gt;
&lt;br /&gt;
WPScan adalah tool utama untuk enumerasi WordPress.&lt;br /&gt;
&lt;br /&gt;
Contoh:&lt;br /&gt;
&lt;br /&gt;
 wpscan --url http://127.0.0.1:31337 --enumerate u,p,t&lt;br /&gt;
&lt;br /&gt;
Artinya:&lt;br /&gt;
&lt;br /&gt;
 --url        = URL target WordPress&lt;br /&gt;
 --enumerate  = minta WPScan melakukan enumerasi&lt;br /&gt;
 u            = users&lt;br /&gt;
 p            = plugins&lt;br /&gt;
 t            = themes&lt;br /&gt;
&lt;br /&gt;
Alur belajar yang bagus:&lt;br /&gt;
&lt;br /&gt;
 1. Jalankan WPScan&lt;br /&gt;
 2. Lihat user/plugin/theme yang ditemukan&lt;br /&gt;
 3. Verifikasi manual lewat browser&lt;br /&gt;
 4. Cek path plugin di /wp-content/plugins/&lt;br /&gt;
 5. Pahami jenis vulnerability-nya&lt;br /&gt;
 6. Baru coba eksploitasi di lab&lt;br /&gt;
&lt;br /&gt;
Jangan hanya copy-paste exploit. Biasakan bertanya:&lt;br /&gt;
&lt;br /&gt;
 Input mana yang vulnerable?&lt;br /&gt;
 Butuh login atau tidak?&lt;br /&gt;
 Impact-nya apa?&lt;br /&gt;
 Buktinya apa?&lt;br /&gt;
 Cara fix-nya bagaimana?&lt;br /&gt;
&lt;br /&gt;
== 5. Fokus latihan pada plugin==&lt;br /&gt;
&lt;br /&gt;
WordPress sering vulnerable karena plugin. Jadi untuk tiap plugin, buat catatan kecil seperti ini:&lt;br /&gt;
&lt;br /&gt;
 Plugin:&lt;br /&gt;
 Versi:&lt;br /&gt;
 Vulnerability:&lt;br /&gt;
 Butuh login? ya/tidak&lt;br /&gt;
 Impact:&lt;br /&gt;
 Evidence / bukti:&lt;br /&gt;
 Cara memperbaiki:&lt;br /&gt;
 Referensi:&lt;br /&gt;
&lt;br /&gt;
Ini sangat mirip dengan cara kerja report pentest sungguhan.&lt;br /&gt;
&lt;br /&gt;
== 6. Attack surface WordPress yang perlu dipahami dulu==&lt;br /&gt;
&lt;br /&gt;
Prioritaskan belajar ini:&lt;br /&gt;
&lt;br /&gt;
 1. User enumeration&lt;br /&gt;
 2. Weak/default credentials&lt;br /&gt;
 3. Vulnerable plugins&lt;br /&gt;
 4. File upload weakness&lt;br /&gt;
 5. Directory listing / exposed files&lt;br /&gt;
 6. XML-RPC abuse&lt;br /&gt;
 7. REST API exposure&lt;br /&gt;
 8. phpMyAdmin/adminer exposure&lt;br /&gt;
 9. wp-config.php atau backup leak&lt;br /&gt;
 10. Privilege escalation di dalam wp-admin&lt;br /&gt;
&lt;br /&gt;
Penjelasan singkat:&lt;br /&gt;
&lt;br /&gt;
 User enumeration&lt;br /&gt;
 mencari username yang valid di WordPress.&lt;br /&gt;
&lt;br /&gt;
 Weak/default credentials&lt;br /&gt;
 login dengan password lemah atau default.&lt;br /&gt;
&lt;br /&gt;
 Vulnerable plugins&lt;br /&gt;
 plugin lama atau plugin yang punya CVE.&lt;br /&gt;
&lt;br /&gt;
 File upload weakness&lt;br /&gt;
 upload file berbahaya karena validasi buruk.&lt;br /&gt;
&lt;br /&gt;
 Directory listing&lt;br /&gt;
 folder bisa dibuka dan isinya kelihatan.&lt;br /&gt;
&lt;br /&gt;
 Exposed files&lt;br /&gt;
 file sensitif seperti backup, .sql, .zip, .bak, atau config terbuka.&lt;br /&gt;
&lt;br /&gt;
 XML-RPC abuse&lt;br /&gt;
 endpoint xmlrpc.php disalahgunakan untuk brute force atau pingback abuse.&lt;br /&gt;
&lt;br /&gt;
 REST API exposure&lt;br /&gt;
 informasi user/post/settings terlalu terbuka lewat /wp-json/.&lt;br /&gt;
&lt;br /&gt;
 phpMyAdmin/adminer exposure&lt;br /&gt;
 panel database terbuka ke web.&lt;br /&gt;
&lt;br /&gt;
 wp-config.php leak&lt;br /&gt;
 file konfigurasi WordPress bocor, bisa berisi credential database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 7. Tool yang bagus untuk latihan DVWP==&lt;br /&gt;
&lt;br /&gt;
Tool utama dari Kali:&lt;br /&gt;
&lt;br /&gt;
 Browser + Burp Suite&lt;br /&gt;
&lt;br /&gt;
Untuk melihat, intercept, dan memodifikasi HTTP request.&lt;br /&gt;
&lt;br /&gt;
 WPScan&lt;br /&gt;
&lt;br /&gt;
Untuk enumerasi WordPress, plugin, theme, user, dan vulnerability.&lt;br /&gt;
&lt;br /&gt;
 Nmap&lt;br /&gt;
&lt;br /&gt;
Untuk cek port dan service yang terbuka.&lt;br /&gt;
&lt;br /&gt;
 Gobuster / Feroxbuster&lt;br /&gt;
&lt;br /&gt;
Untuk mencari folder atau file tersembunyi.&lt;br /&gt;
&lt;br /&gt;
 Nikto&lt;br /&gt;
&lt;br /&gt;
Untuk cek basic web server misconfiguration.&lt;br /&gt;
&lt;br /&gt;
 Curl&lt;br /&gt;
&lt;br /&gt;
Untuk memahami HTTP request dan response secara manual.&lt;br /&gt;
&lt;br /&gt;
 Searchsploit&lt;br /&gt;
&lt;br /&gt;
Untuk mencari referensi exploit lokal dari Exploit-DB.&lt;br /&gt;
&lt;br /&gt;
== 8. Workflow beginner yang bagus==&lt;br /&gt;
&lt;br /&gt;
Pakai alur ini setiap latihan:&lt;br /&gt;
&lt;br /&gt;
 Step 1: Apakah target bisa diakses?&lt;br /&gt;
 Step 2: Port/service apa yang terbuka?&lt;br /&gt;
 Step 3: Apakah ini WordPress?&lt;br /&gt;
 Step 4: Versi WordPress berapa?&lt;br /&gt;
 Step 5: User apa saja yang terlihat?&lt;br /&gt;
 Step 6: Plugin/theme apa yang terpasang?&lt;br /&gt;
 Step 7: Apakah versi plugin/theme vulnerable?&lt;br /&gt;
 Step 8: Exploit-nya butuh login atau tidak?&lt;br /&gt;
 Step 9: Bisa tidak membuktikan impact dengan aman?&lt;br /&gt;
 Step 10: Bagaimana cara memperbaikinya?&lt;br /&gt;
&lt;br /&gt;
Kebiasaan ini lebih penting daripada menghafal payload.&lt;br /&gt;
&lt;br /&gt;
== 9. Rencana latihan 7 hari==&lt;br /&gt;
&lt;br /&gt;
 Hari 1:&lt;br /&gt;
 Install/start DVWP dan pahami struktur aplikasinya.&lt;br /&gt;
 &lt;br /&gt;
 Hari 2:&lt;br /&gt;
 Latihan nmap, curl, browser inspection, dan Burp Suite.&lt;br /&gt;
 &lt;br /&gt;
 Hari 3:&lt;br /&gt;
 Jalankan WPScan dan verifikasi user/plugin/theme secara manual.&lt;br /&gt;
 &lt;br /&gt;
 Hari 4:&lt;br /&gt;
 Pelajari path plugin di /wp-content/plugins/.&lt;br /&gt;
 &lt;br /&gt;
 Hari 5:&lt;br /&gt;
 Latihan directory discovery dan exposed file checking.&lt;br /&gt;
 &lt;br /&gt;
 Hari 6:&lt;br /&gt;
 Pilih satu vulnerability plugin, pelajari pelan-pelan, lalu tulis mini report.&lt;br /&gt;
 &lt;br /&gt;
 Hari 7:&lt;br /&gt;
 Ulangi dari awal tanpa melihat catatan.&lt;br /&gt;
&lt;br /&gt;
== 10. Buat folder catatan latihan==&lt;br /&gt;
&lt;br /&gt;
Bikin folder seperti ini:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/Apps/Pentest/DVWP-notes&lt;br /&gt;
 cd ~/Apps/Pentest/DVWP-notes&lt;br /&gt;
 &lt;br /&gt;
 touch 01-recon.md&lt;br /&gt;
 touch 02-wordpress-structure.md&lt;br /&gt;
 touch 03-wpscan.md&lt;br /&gt;
 touch 04-plugins.md&lt;br /&gt;
 touch 05-exposed-files.md&lt;br /&gt;
 touch 06-findings-report.md&lt;br /&gt;
 touch 99-cheatsheet.md&lt;br /&gt;
&lt;br /&gt;
Isi setiap file dengan format:&lt;br /&gt;
&lt;br /&gt;
 Target:&lt;br /&gt;
 Tool yang digunakan:&lt;br /&gt;
 Command:&lt;br /&gt;
 Arti command:&lt;br /&gt;
 Finding:&lt;br /&gt;
 Evidence / bukti:&lt;br /&gt;
 Risk:&lt;br /&gt;
 Fix:&lt;br /&gt;
 Lesson learned:&lt;br /&gt;
&lt;br /&gt;
== 11. Contoh catatan sederhana==&lt;br /&gt;
&lt;br /&gt;
 Target:&lt;br /&gt;
 http://127.0.0.1:31337&lt;br /&gt;
 &lt;br /&gt;
 Tool:&lt;br /&gt;
 WPScan&lt;br /&gt;
 &lt;br /&gt;
 Command:&lt;br /&gt;
 wpscan --url http://127.0.0.1:31337 --enumerate u,p,t&lt;br /&gt;
 &lt;br /&gt;
 Arti:&lt;br /&gt;
 Melakukan enumerasi user, plugin, dan theme WordPress.&lt;br /&gt;
 &lt;br /&gt;
 Finding:&lt;br /&gt;
 Ditemukan beberapa plugin yang bisa dicek lebih lanjut.&lt;br /&gt;
 &lt;br /&gt;
 Evidence:&lt;br /&gt;
 Plugin terlihat di path /wp-content/plugins/.&lt;br /&gt;
 &lt;br /&gt;
 Risk:&lt;br /&gt;
 Jika plugin versi lama dan vulnerable, attacker bisa mengeksploitasi website.&lt;br /&gt;
 &lt;br /&gt;
 Fix:&lt;br /&gt;
 Update plugin, hapus plugin tidak terpakai, batasi akses admin, dan aktifkan hardening WordPress.&lt;br /&gt;
 &lt;br /&gt;
 Lesson learned:&lt;br /&gt;
 Dalam WordPress pentest, plugin sering menjadi sumber vulnerability utama.&lt;br /&gt;
&lt;br /&gt;
== 12. Mindset penting saat latihan==&lt;br /&gt;
&lt;br /&gt;
Jangan berpikir:&lt;br /&gt;
&lt;br /&gt;
 Payload apa yang harus aku copy-paste?&lt;br /&gt;
&lt;br /&gt;
Tapi biasakan berpikir:&lt;br /&gt;
&lt;br /&gt;
 Data apa yang dikirim user?&lt;br /&gt;
 Server memproses input ini sebagai apa?&lt;br /&gt;
 Apakah input masuk ke SQL query, command, file path, upload handler, atau HTML output?&lt;br /&gt;
 Apa buktinya input saya memengaruhi backend?&lt;br /&gt;
 Impact-nya apa?&lt;br /&gt;
 Cara mitigasinya apa?&lt;br /&gt;
&lt;br /&gt;
Itu mindset pentester yang benar.&lt;br /&gt;
&lt;br /&gt;
== 13. Batas aman==&lt;br /&gt;
&lt;br /&gt;
Yang boleh dilakukan:&lt;br /&gt;
&lt;br /&gt;
 DVWP lokal&lt;br /&gt;
 VM sendiri&lt;br /&gt;
 Docker sendiri&lt;br /&gt;
 Lab kampus/kantor yang memang diizinkan&lt;br /&gt;
 CTF resmi&lt;br /&gt;
&lt;br /&gt;
Yang jangan dilakukan:&lt;br /&gt;
&lt;br /&gt;
 Scan website publik tanpa izin&lt;br /&gt;
 Brute force login asli&lt;br /&gt;
 Coba payload ke sistem kantor tanpa scope&lt;br /&gt;
 Upload shell ke server bukan milik sendiri&lt;br /&gt;
 Pakai WPScan ke domain publik tanpa izin&lt;br /&gt;
&lt;br /&gt;
Intinya: '''DVWP bukan hanya tempat “nge-hack WordPress”. DVWP adalah tempat belajar cara berpikir pentester WordPress: enumerasi, verifikasi, pahami impact, lalu tulis report dengan rapi.'''&lt;/div&gt;</description>
			<pubDate>Sat, 04 Jul 2026 01:20:56 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:DVWP</comments>
		</item>
		<item>
			<title>DVWA</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=DVWA&amp;diff=73695&amp;oldid=73595</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=DVWA&amp;diff=73695&amp;oldid=73595</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Referensi&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:14, 4 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-l55&quot; &gt;Line 55:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 55:&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;* http://www.dvwa.co.uk/&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;* http://www.dvwa.co.uk/&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;* http://www.computersecuritystudent.com/cgi-bin/CSS/process_request_v3.pl?HID=688b0913be93a4d95daed400990c4745&amp;amp;TYPE=SUB&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;* http://www.computersecuritystudent.com/cgi-bin/CSS/process_request_v3.pl?HID=688b0913be93a4d95daed400990c4745&amp;amp;TYPE=SUB&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;&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;==Pranala Menarik==&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;* [[DVWP]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sat, 04 Jul 2026 01:14:00 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:DVWA</comments>
		</item>
		<item>
			<title>PM: Install Virtual Environment</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=PM:_Install_Virtual_Environment&amp;diff=73694&amp;oldid=73689</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=PM:_Install_Virtual_Environment&amp;diff=73694&amp;oldid=73689</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;11. Cara pakai harian&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:38, 28 June 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;(4 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-l38&quot; &gt;Line 38:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 38:&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;  python -m pip install --upgrade pip setuptools wheel&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;  python -m pip install --upgrade pip setuptools wheel&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;== 5. Install PM4Py + library pendukung&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;== 5. Install PM4Py + library pendukung&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;  pip install -U \&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;  pip install -U \&lt;/div&gt;&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-l77&quot; &gt;Line 77:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 77:&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;  Python PM4Py&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;  Python PM4Py&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;== 7. Buat file requirements.txt&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;== 7. Buat file requirements.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;  cat &amp;gt; requirements.txt &amp;lt;&amp;lt; 'EOF'&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;  cat &amp;gt; requirements.txt &amp;lt;&amp;lt; 'EOF'&lt;/div&gt;&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-l109&quot; &gt;Line 109:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 109:&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;Isi:&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;Isi:&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 style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; python&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;  import pm4py&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;  import pm4py&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;  import pandas as pd&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;  import pandas as pd&lt;/div&gt;&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-l130&quot; &gt;Line 130:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 129:&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;  print(df)&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;  print(df)&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;= &lt;/del&gt;Discover Directly-Follows Graph&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;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt; # &lt;/ins&gt;Discover Directly-Follows Graph&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;  dfg, start_activities, end_activities = pm4py.discover_dfg(df)&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;  dfg, start_activities, end_activities = pm4py.discover_dfg(df)&lt;/div&gt;&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-l217&quot; &gt;Line 217:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 216:&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;  deactivate&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;  deactivate&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;== 12. Kalau ada error Graphviz&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;== 12. Kalau ada error Graphviz&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;Cek:&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;Cek:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 28 Jun 2026 09:38:47 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:PM:_Install_Virtual_Environment</comments>
		</item>
		<item>
			<title>PM: Install Virtual Environment</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=PM:_Install_Virtual_Environment&amp;diff=73689&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=PM:_Install_Virtual_Environment&amp;diff=73689&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Berikut langkah lengkap membuat &amp;#039;&amp;#039;&amp;#039;virtualenv PM4Py di `~/Apps/PM4Py`&amp;#039;&amp;#039;&amp;#039; untuk *process mining*. PM4Py resmi bisa di-install dengan `pip install -U pm4py`, dan saat ini menduk...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Berikut langkah lengkap membuat '''virtualenv PM4Py di `~/Apps/PM4Py`''' untuk *process mining*. PM4Py resmi bisa di-install dengan `pip install -U pm4py`, dan saat ini mendukung Python 3.9–3.14. ([PyPI][1])&lt;br /&gt;
&lt;br /&gt;
== 1. Install dependency sistem==&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install -y python3 python3-venv python3-pip graphviz&lt;br /&gt;
&lt;br /&gt;
Keterangan singkat:&lt;br /&gt;
&lt;br /&gt;
 python3-venv&lt;br /&gt;
&lt;br /&gt;
dibutuhkan untuk membuat virtual environment.&lt;br /&gt;
&lt;br /&gt;
 graphviz&lt;br /&gt;
&lt;br /&gt;
dibutuhkan agar visualisasi proses seperti Petri net, BPMN, dan *process tree* bisa digambar dengan baik.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 2. Buat folder kerja==&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/Apps/PM4Py&lt;br /&gt;
 cd ~/Apps/PM4Py&lt;br /&gt;
&lt;br /&gt;
== 3. Buat virtualenv==&lt;br /&gt;
&lt;br /&gt;
 python3 -m venv venv&lt;br /&gt;
&lt;br /&gt;
Aktifkan:&lt;br /&gt;
&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
Kalau berhasil, prompt terminal biasanya berubah menjadi seperti:&lt;br /&gt;
&lt;br /&gt;
 (venv) onno@i3:~/Apps/PM4Py$&lt;br /&gt;
&lt;br /&gt;
== 4. Upgrade pip dan tools dasar==&lt;br /&gt;
&lt;br /&gt;
 python -m pip install --upgrade pip setuptools wheel&lt;br /&gt;
&lt;br /&gt;
== 5. Install PM4Py + library pendukung&lt;br /&gt;
&lt;br /&gt;
 pip install -U \&lt;br /&gt;
   pm4py \&lt;br /&gt;
   pandas \&lt;br /&gt;
   numpy \&lt;br /&gt;
   matplotlib \&lt;br /&gt;
   seaborn \&lt;br /&gt;
   scikit-learn \&lt;br /&gt;
   scipy \&lt;br /&gt;
   networkx \&lt;br /&gt;
   graphviz \&lt;br /&gt;
   pyvis \&lt;br /&gt;
   jupyterlab \&lt;br /&gt;
   notebook \&lt;br /&gt;
   ipykernel \&lt;br /&gt;
   openpyxl \&lt;br /&gt;
   xlsxwriter&lt;br /&gt;
&lt;br /&gt;
Library utama:&lt;br /&gt;
&lt;br /&gt;
 | Library                  | Fungsi                                     |&lt;br /&gt;
 |  |  |&lt;br /&gt;
 | `pm4py`                  | library utama *process mining*             |&lt;br /&gt;
 | `pandas`, `numpy`        | olah data event log                        |&lt;br /&gt;
 | `matplotlib`, `seaborn`  | visualisasi data                           |&lt;br /&gt;
 | `scikit-learn`           | clustering, klasifikasi, anomaly detection |&lt;br /&gt;
 | `networkx`, `graphviz`   | graph/process visualization                |&lt;br /&gt;
 | `jupyterlab`, `notebook` | kerja lewat Jupyter                        |&lt;br /&gt;
 | `openpyxl`, `xlsxwriter` | baca/tulis Excel                           |&lt;br /&gt;
&lt;br /&gt;
== 6. Daftarkan kernel Jupyter==&lt;br /&gt;
&lt;br /&gt;
 python -m ipykernel install --user --name pm4py --display-name &amp;quot;Python PM4Py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Nanti di Jupyter pilih kernel:&lt;br /&gt;
&lt;br /&gt;
 Python PM4Py&lt;br /&gt;
&lt;br /&gt;
== 7. Buat file requirements.txt&lt;br /&gt;
&lt;br /&gt;
 cat &amp;gt; requirements.txt &amp;lt;&amp;lt; 'EOF'&lt;br /&gt;
 pm4py&lt;br /&gt;
 pandas&lt;br /&gt;
 numpy&lt;br /&gt;
 matplotlib&lt;br /&gt;
 seaborn&lt;br /&gt;
 scikit-learn&lt;br /&gt;
 scipy&lt;br /&gt;
 networkx&lt;br /&gt;
 graphviz&lt;br /&gt;
 pyvis&lt;br /&gt;
 jupyterlab&lt;br /&gt;
 notebook&lt;br /&gt;
 ipykernel&lt;br /&gt;
 openpyxl&lt;br /&gt;
 xlsxwriter&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
Nanti kalau mau install ulang cukup:&lt;br /&gt;
&lt;br /&gt;
 pip install -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
== 8. Test instalasi PM4Py==&lt;br /&gt;
&lt;br /&gt;
Buat file test:&lt;br /&gt;
&lt;br /&gt;
 nano test_pm4py.py&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
 python&lt;br /&gt;
 import pm4py&lt;br /&gt;
 import pandas as pd&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;PM4Py version:&amp;quot;, pm4py.__version__)&lt;br /&gt;
 &lt;br /&gt;
 data = [&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;Register&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-01 08:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;Check&amp;quot;,    &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-01 09:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;Approve&amp;quot;,  &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-01 10:00:00&amp;quot;}, &lt;br /&gt;
 &lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;Register&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-02 08:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;Check&amp;quot;,    &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-02 09:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;Reject&amp;quot;,   &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-02 10:00:00&amp;quot;},&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 df = pd.DataFrame(data)&lt;br /&gt;
 df[&amp;quot;time:timestamp&amp;quot;] = pd.to_datetime(df[&amp;quot;time:timestamp&amp;quot;])&lt;br /&gt;
 &lt;br /&gt;
 print(df)&lt;br /&gt;
&lt;br /&gt;
= Discover Directly-Follows Graph=&lt;br /&gt;
&lt;br /&gt;
 dfg, start_activities, end_activities = pm4py.discover_dfg(df)&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;\nDirectly-Follows Graph:&amp;quot;)&lt;br /&gt;
 print(dfg)&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;\nStart activities:&amp;quot;)&lt;br /&gt;
 print(start_activities)&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;\nEnd activities:&amp;quot;)&lt;br /&gt;
 print(end_activities)&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
 python test_pm4py.py&lt;br /&gt;
&lt;br /&gt;
Kalau sukses, akan keluar versi PM4Py dan hasil *Directly-Follows Graph*.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 9. Test lewat Jupyter Notebook==&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
 jupyter lab&lt;br /&gt;
&lt;br /&gt;
Lalu buat notebook baru dengan kernel:&lt;br /&gt;
&lt;br /&gt;
 Python PM4Py&lt;br /&gt;
&lt;br /&gt;
Cell test:&lt;br /&gt;
&lt;br /&gt;
 import pm4py&lt;br /&gt;
 import pandas as pd&lt;br /&gt;
 &lt;br /&gt;
 pm4py.__version__&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Cell berikutnya:&lt;br /&gt;
&lt;br /&gt;
 data = [&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;A&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-01 08:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;B&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-01 09:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;C&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-01 10:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;A&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-02 08:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;B&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-02 09:00:00&amp;quot;},&lt;br /&gt;
     {&amp;quot;case:concept:name&amp;quot;: &amp;quot;2&amp;quot;, &amp;quot;concept:name&amp;quot;: &amp;quot;D&amp;quot;, &amp;quot;time:timestamp&amp;quot;: &amp;quot;2026-01-02 10:00:00&amp;quot;},&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 df = pd.DataFrame(data)&lt;br /&gt;
 df[&amp;quot;time:timestamp&amp;quot;] = pd.to_datetime(df[&amp;quot;time:timestamp&amp;quot;])&lt;br /&gt;
 &lt;br /&gt;
 df&lt;br /&gt;
&lt;br /&gt;
Cell process mining:&lt;br /&gt;
&lt;br /&gt;
 dfg, start_activities, end_activities = pm4py.discover_dfg(df)&lt;br /&gt;
 &lt;br /&gt;
 dfg&lt;br /&gt;
&lt;br /&gt;
== 10. Struktur folder yang disarankan==&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/Apps/PM4Py/{data,notebooks,scripts,output}&lt;br /&gt;
&lt;br /&gt;
Struktur:&lt;br /&gt;
&lt;br /&gt;
 ~/Apps/PM4Py/&lt;br /&gt;
 ├── venv/&lt;br /&gt;
 ├── data/&lt;br /&gt;
 ├── notebooks/&lt;br /&gt;
 ├── scripts/&lt;br /&gt;
 ├── output/&lt;br /&gt;
 ├── requirements.txt&lt;br /&gt;
 └── test_pm4py.py&lt;br /&gt;
&lt;br /&gt;
== 11. Cara pakai harian==&lt;br /&gt;
&lt;br /&gt;
Setiap mau kerja:&lt;br /&gt;
&lt;br /&gt;
 cd ~/Apps/PM4Py&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 jupyter lab&lt;br /&gt;
&lt;br /&gt;
Keluar dari virtualenv:&lt;br /&gt;
&lt;br /&gt;
 deactivate&lt;br /&gt;
&lt;br /&gt;
== 12. Kalau ada error Graphviz&lt;br /&gt;
&lt;br /&gt;
Cek:&lt;br /&gt;
&lt;br /&gt;
 dot -V&lt;br /&gt;
&lt;br /&gt;
Kalau belum ada:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install -y graphviz&lt;br /&gt;
&lt;br /&gt;
Lalu install ulang Python package-nya:&lt;br /&gt;
&lt;br /&gt;
 pip install -U graphviz&lt;br /&gt;
&lt;br /&gt;
== 13. Versi ringkas semua command==&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install -y python3 python3-venv python3-pip graphviz&lt;br /&gt;
 &lt;br /&gt;
 mkdir -p ~/Apps/PM4Py &lt;br /&gt;
 cd ~/Apps/PM4Py&lt;br /&gt;
 &lt;br /&gt;
 python3 -m venv venv&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 &lt;br /&gt;
 python -m pip install --upgrade pip setuptools wheel&lt;br /&gt;
 &lt;br /&gt;
 pip install -U \&lt;br /&gt;
   pm4py \&lt;br /&gt;
   pandas \&lt;br /&gt;
   numpy \&lt;br /&gt;
   matplotlib \&lt;br /&gt;
   seaborn \&lt;br /&gt;
   scikit-learn \&lt;br /&gt;
   scipy \&lt;br /&gt;
   networkx \&lt;br /&gt;
   graphviz \&lt;br /&gt;
   pyvis \&lt;br /&gt;
   jupyterlab \&lt;br /&gt;
   notebook \&lt;br /&gt;
   ipykernel \&lt;br /&gt;
   openpyxl \&lt;br /&gt;
   xlsxwriter&lt;br /&gt;
 &lt;br /&gt;
 python -m ipykernel install --user --name pm4py --display-name &amp;quot;Python PM4Py&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 mkdir -p data notebooks scripts output&lt;br /&gt;
 &lt;br /&gt;
 python -c &amp;quot;import pm4py; print(pm4py.__version__)&amp;quot;&lt;br /&gt;
 jupyter lab&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 [1]: https://pypi.org/project/pm4py/?utm_source=chatgpt.com &amp;quot;pm4py&amp;quot;&lt;/div&gt;</description>
			<pubDate>Sun, 28 Jun 2026 09:32:04 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:PM:_Install_Virtual_Environment</comments>
		</item>
		<item>
			<title>Process Mining</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Process_Mining&amp;diff=73688&amp;oldid=72784</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Process_Mining&amp;diff=73688&amp;oldid=72784</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 09:31, 28 June 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-l20&quot; &gt;Line 20:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 20:&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 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;* [[PM: Install Virtual Environment]]&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;* [[PM: Methods in pm4py]]&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;* [[PM: Methods in pm4py]]&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;* [[PM: Bottleneck Detection]]&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;* [[PM: Bottleneck Detection]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 28 Jun 2026 09:31:57 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Process_Mining</comments>
		</item>
		<item>
			<title>ML: Python Virtual Environment</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ML:_Python_Virtual_Environment&amp;diff=73687&amp;oldid=73671</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ML:_Python_Virtual_Environment&amp;diff=73687&amp;oldid=73671</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;9. Daftarkan kernel Jupyter&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 08:24, 28 June 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-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;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;Berikut langkah sederhana &lt;/del&gt;di Ubuntu&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;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Install Miniconda &lt;/ins&gt;di Ubuntu &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;26.04 bisa langsung di home folder, '''tidak perlu `sudo`'''. Ini cocok untuk kasus Bapak karena `apt` tidak menyediakan Python 3.12, sedangkan TensorFlow belum cocok dengan Python 3.14.&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;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; mkdir -p ~/Apps/Python&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;Miniconda adalah installer minimal untuk `conda`, &lt;/ins&gt;Python&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, dan paket dasar saja. ([Anaconda][1])&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; cd ~/Apps/&lt;/del&gt;Python&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;/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;Install &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;paket &lt;/del&gt;dasar&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;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;== 1. &lt;/ins&gt;Install &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;dependency &lt;/ins&gt;dasar&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;  sudo apt 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 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;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;  sudo apt install -y &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;python3 python3&lt;/del&gt;-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;pip python3-venv python3-dev build-essential&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;  sudo apt install -y &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;wget curl bzip2 ca&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;certificates&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;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 style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Buat virtual environment:&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;/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; python3 -m venv venv&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;== 2. Download installer Miniconda==&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;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;Aktifkan virtual environment&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; cd ~/Downloads&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 class=&quot;diffchange diffchange-inline&quot;&gt; wget https&lt;/ins&gt;:&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;//repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh&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;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; source venv/bin/activate&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;Ini sesuai pola installer Linux resmi: `Miniconda3-latest-Linux-x86_64.sh`. Dokumentasi conda juga menjelaskan installer Linux dijalankan dengan format `bash &amp;lt;conda-installer-name&amp;gt;-latest-Linux-x86_64.sh`. ([Conda Documentation][2])&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;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;Upgrade pip:&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;== 3. Jalankan installer==&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;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;pip install &lt;/del&gt;--&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;upgrade pip setuptools wheel&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;bash Miniconda3&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;latest&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Linux-x86_64.sh&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;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;Install library Python untuk coding, ML, Keras, Pandas, NumPy, dan Jupyter&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;Saat muncul pertanyaan&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;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;pip install numpy pandas matplotlib scikit-learn tensorflow keras jupyter notebook ipykernel&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;Please, press ENTER to continue&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 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;Tekan '''Enter'''.&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;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;Tambahkan kernel Jupyter&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;Saat muncul lisensi, tekan `q` untuk keluar dari tampilan lisensi, lalu ketik&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;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;python -m ipykernel install --user --name python-ml --display-name &amp;quot;Python ML&amp;quot;&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;yes&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;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;Jalankan Jupyter Notebook&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;Saat ditanya lokasi instalasi, terima default&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;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;  jupyter notebook&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;/home/onno/miniconda3&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Tekan '''Enter'''.&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Saat ditanya:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; Do you wish to update your shell profile to automatically initialize conda?&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Pilih:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; yes&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;== 4. Aktifkan conda==&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Tutup terminal lalu buka lagi.&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Atau langsung jalankan:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; source ~/.bashrc&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Cek:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; conda --version&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Kalau keluar seperti:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; conda 25.x.x&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;berarti sukses.&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;== 5. Matikan auto-activate base==&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Saya sarankan supaya terminal tidak selalu masuk environment `(base)`:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; conda config --set auto_activate_base false&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Tutup terminal lalu buka lagi.&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Kalau ingin mengaktifkan conda manual:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; source ~/miniconda3/etc/profile.d/conda.sh&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;== 6. Buat environment Python 3.12 untuk ML/TensorFlow==&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; source ~/miniconda3/etc/profile.d/conda.sh&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; conda create -y -n python-ml python=3.12&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 class=&quot;diffchange diffchange-inline&quot;&gt; conda activate python-ml&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Cek:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; python --version&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Harus Python 3.12.x.&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;== 7. Install paket machine learning==&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; python -m pip install --upgrade pip setuptools wheel&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; python -m pip install \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   numpy \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   pandas \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   matplotlib \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   scikit-learn \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   tensorflow \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   keras \&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 class=&quot;diffchange diffchange-inline&quot;&gt;   &lt;/ins&gt;jupyter &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 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 class=&quot;diffchange diffchange-inline&quot;&gt;   &lt;/ins&gt;notebook &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 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 class=&quot;diffchange diffchange-inline&quot;&gt;   ipykernel&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;== 8. Test TensorFlow==&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; python -c &amp;quot;import tensorflow as tf; print(tf.__version__)&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt;Cek GPU:&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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; python -c &amp;quot;import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))&amp;quot;&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;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;Nanti browser akan terbuka&lt;/del&gt;. &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Pilih &lt;/del&gt;kernel&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;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;== 9&lt;/ins&gt;. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Daftarkan &lt;/ins&gt;kernel &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Jupyter==&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;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;  Python ML&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;python -m ipykernel install --user --name python-ml --display-name &amp;quot;&lt;/ins&gt;Python ML &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;TensorFlow&amp;quot;&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;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;Untuk masuk lagi lain waktu&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;Jalankan Jupyter&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;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 style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; cd ~/Apps/Python&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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 style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; source venv/bin/activate&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;  jupyter notebook&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;  jupyter notebook&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;Tes &lt;/del&gt;cepat:&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;== Versi &lt;/ins&gt;cepat: &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;copy-paste==&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;/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;/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 class=&quot;diffchange diffchange-inline&quot;&gt; sudo apt update&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 class=&quot;diffchange diffchange-inline&quot;&gt; sudo apt install -y wget curl bzip2 ca-certificates&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; cd ~/Downloads&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 class=&quot;diffchange diffchange-inline&quot;&gt; wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; bash Miniconda3-latest-Linux-x86_64.sh &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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; source ~/.bashrc &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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; conda config --set auto_activate_base false&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; source ~/miniconda3/etc/profile.d/conda.sh&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; conda create -y -n python-ml python=3.12&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 class=&quot;diffchange diffchange-inline&quot;&gt; conda activate python-ml&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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; python -m pip install --upgrade pip setuptools wheel&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 class=&quot;diffchange diffchange-inline&quot;&gt; python -m pip install numpy pandas matplotlib scikit-learn tensorflow keras jupyter notebook ipykernel &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 class=&quot;diffchange diffchange-inline&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 class=&quot;diffchange diffchange-inline&quot;&gt; python -c &amp;quot;import tensorflow as tf; print(tf.__version__)&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 class=&quot;diffchange diffchange-inline&quot;&gt; python -m ipykernel install --user --name python-ml --display-name &amp;quot;Python ML TensorFlow&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;/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;python &lt;/del&gt;-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;c &lt;/del&gt;&amp;quot;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;import numpy, pandas, sklearn, tensorflow, keras; print('OK')&lt;/del&gt;&amp;quot;&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;[1]: https://www.anaconda.com/download?utm_source=chatgpt.com &amp;quot;Download Anaconda Distribution&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 class=&quot;diffchange diffchange-inline&quot;&gt; [2]: https://docs.conda.io/projects/conda/en/latest/user&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;guide/install/linux.html?utm_source=chatgpt.com &lt;/ins&gt;&amp;quot;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Installing on Linux — conda 26.5.4.dev62 documentation&lt;/ins&gt;&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 28 Jun 2026 08:24:10 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ML:_Python_Virtual_Environment</comments>
		</item>
		<item>
			<title>GNS3: Instalasi di Ubuntu 26.04 + VENV + docker</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=GNS3:_Instalasi_di_Ubuntu_26.04_%2B_VENV_%2B_docker&amp;diff=73684&amp;oldid=73680</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=GNS3:_Instalasi_di_Ubuntu_26.04_%2B_VENV_%2B_docker&amp;diff=73684&amp;oldid=73680</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;4. Upgrade pip&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 08:01, 28 June 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;(3 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-l11&quot; &gt;Line 11:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 11:&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 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 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 install -y \&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 install -y \&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;python3 \&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;qemu&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;system&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;x86 &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;   python3-pip \&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;    qemu-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;utils &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;   python3-venv \&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;   python3&lt;/del&gt;-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;dev \&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;   python3-pyqt6 \&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;   python3-pyqt6.qtsvg \&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;   python3&lt;/del&gt;-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;pyqt6.qtwebsockets &lt;/del&gt;\&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;    qemu-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;kvm &lt;/del&gt;\&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;    libvirt-daemon-system \&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;    libvirt-daemon-system \&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;    libvirt-clients \&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;    libvirt-clients \&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;    bridge-utils \&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;    bridge-utils \&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;   virtinst \&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;   cpu-checker \&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;    wireshark \&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;    wireshark \&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;    dynamips \&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;    dynamips \&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;    vpcs &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;    vpcs&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;   ubridge&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&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;/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;Tambahkan user ke grup yang diperlukan:&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;Tambahkan user ke grup yang diperlukan:&lt;/div&gt;&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-l53&quot; &gt;Line 53:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 48:&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;  python -m pip install --upgrade pip setuptools wheel&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;  python -m pip install --upgrade pip setuptools wheel&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; python -m pip install --upgrade PyQt6 PyQt6-sip sip PyQt6-WebEngine&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; &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; SITEPKG=$(python -c &amp;quot;import site; print(site.getsitepackages()[0])&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; &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; cat &amp;gt; &amp;quot;$SITEPKG/sip.py&amp;quot; &amp;lt;&amp;lt;'EOF'&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; from PyQt6.sip import *&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; EOF&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;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;== 5. Install GNS3 GUI dan server&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;== 5. Install GNS3 GUI dan server&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;Versi PyPI terbaru yang terlihat saat ini adalah '''gns3-gui 3.0.6''', dirilis 28 Januari 2026. ([PyPI][2])&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;Versi PyPI terbaru yang terlihat saat ini adalah '''gns3-gui 3.0.6''', dirilis 28 Januari 2026. ([PyPI][2])&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 28 Jun 2026 08:01:30 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:GNS3:_Instalasi_di_Ubuntu_26.04_%2B_VENV_%2B_docker</comments>
		</item>
		<item>
			<title>GNS3: Instalasi di Ubuntu 26.04 + VENV + docker</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=GNS3:_Instalasi_di_Ubuntu_26.04_%2B_VENV_%2B_docker&amp;diff=73680&amp;oldid=0</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=GNS3:_Instalasi_di_Ubuntu_26.04_%2B_VENV_%2B_docker&amp;diff=73680&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;Berikut cara instalasi &amp;#039;&amp;#039;&amp;#039;GNS3 di Python virtual environment&amp;#039;&amp;#039;&amp;#039; menggunakan folder:   ~/Apps/GNS3  Catatan penting: instalasi via `pip/venv` cocok untuk &amp;#039;&amp;#039;&amp;#039;GNS3 GUI + GNS3 ser...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Berikut cara instalasi '''GNS3 di Python virtual environment''' menggunakan folder:&lt;br /&gt;
&lt;br /&gt;
 ~/Apps/GNS3&lt;br /&gt;
&lt;br /&gt;
Catatan penting: instalasi via `pip/venv` cocok untuk '''GNS3 GUI + GNS3 server''', tetapi emulator seperti '''QEMU/KVM, Dynamips, uBridge, VPCS, Wireshark, Docker''' tetap lebih aman dipasang dari package OS. GNS3 server memang bertugas mengelola QEMU/KVM, Docker, VPCS, VirtualBox, VMware, dan Dynamips. ([PyPI][1])&lt;br /&gt;
&lt;br /&gt;
== 1. Install dependency OS==&lt;br /&gt;
&lt;br /&gt;
Untuk Ubuntu/Debian:&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install -y \&lt;br /&gt;
   python3 \&lt;br /&gt;
   python3-pip \&lt;br /&gt;
   python3-venv \&lt;br /&gt;
   python3-dev \&lt;br /&gt;
   python3-pyqt6 \&lt;br /&gt;
   python3-pyqt6.qtsvg \&lt;br /&gt;
   python3-pyqt6.qtwebsockets \&lt;br /&gt;
   qemu-kvm \&lt;br /&gt;
   libvirt-daemon-system \&lt;br /&gt;
   libvirt-clients \&lt;br /&gt;
   bridge-utils \&lt;br /&gt;
   wireshark \&lt;br /&gt;
   dynamips \&lt;br /&gt;
   vpcs \&lt;br /&gt;
   ubridge&lt;br /&gt;
&lt;br /&gt;
Tambahkan user ke grup yang diperlukan:&lt;br /&gt;
&lt;br /&gt;
 sudo usermod -aG kvm,libvirt,wireshark,docker $USER&lt;br /&gt;
&lt;br /&gt;
Logout-login dulu setelah perintah di atas, atau reboot:&lt;br /&gt;
&lt;br /&gt;
 reboot&lt;br /&gt;
&lt;br /&gt;
== 2. Buat folder kerja GNS3==&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/Apps/GNS3&lt;br /&gt;
 cd ~/Apps/GNS3&lt;br /&gt;
&lt;br /&gt;
== 3. Buat Python virtual environment==&lt;br /&gt;
&lt;br /&gt;
 python3 -m venv venv&lt;br /&gt;
&lt;br /&gt;
Aktifkan venv:&lt;br /&gt;
&lt;br /&gt;
 source ~/Apps/GNS3/venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
Pastikan prompt berubah, biasanya ada `(venv)`.&lt;br /&gt;
&lt;br /&gt;
== 4. Upgrade pip==&lt;br /&gt;
&lt;br /&gt;
 python -m pip install --upgrade pip setuptools wheel&lt;br /&gt;
&lt;br /&gt;
== 5. Install GNS3 GUI dan server&lt;br /&gt;
&lt;br /&gt;
Versi PyPI terbaru yang terlihat saat ini adalah '''gns3-gui 3.0.6''', dirilis 28 Januari 2026. ([PyPI][2])&lt;br /&gt;
GNS3 juga menyatakan instalasi dari PyPI bisa dilakukan dengan `pip install gns3-gui` dan `gns3-server`; contoh rilis 3.0 memakai `gns3-gui==3.0.5` dan `gns3-server==3.0.5`. ([GNS3][3])&lt;br /&gt;
&lt;br /&gt;
Install versi terbaru:&lt;br /&gt;
&lt;br /&gt;
 python -m pip install gns3-gui gns3-server&lt;br /&gt;
&lt;br /&gt;
Atau kalau ingin versi dikunci supaya GUI dan server tidak mismatch:&lt;br /&gt;
&lt;br /&gt;
 python -m pip install gns3-gui==3.0.6 gns3-server==3.0.6&lt;br /&gt;
&lt;br /&gt;
Cek hasil instalasi:&lt;br /&gt;
&lt;br /&gt;
 gns3 --version&lt;br /&gt;
 gns3server --version&lt;br /&gt;
&lt;br /&gt;
== 6. Jalankan GNS3==&lt;br /&gt;
&lt;br /&gt;
Aktifkan dulu venv:&lt;br /&gt;
&lt;br /&gt;
 source ~/Apps/GNS3/venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
Jalankan server:&lt;br /&gt;
&lt;br /&gt;
 gns3server&lt;br /&gt;
&lt;br /&gt;
Di terminal lain, aktifkan venv lagi:&lt;br /&gt;
&lt;br /&gt;
 source ~/Apps/GNS3/venv/bin/activate&lt;br /&gt;
 gns3&lt;br /&gt;
&lt;br /&gt;
Atau langsung jalankan GUI saja:&lt;br /&gt;
&lt;br /&gt;
 ~/Apps/GNS3/venv/bin/gns3&lt;br /&gt;
&lt;br /&gt;
== 7. Buat script launcher supaya mudah==&lt;br /&gt;
&lt;br /&gt;
Buat file:&lt;br /&gt;
&lt;br /&gt;
 nano ~/Apps/GNS3/start-gns3.sh&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
 *!/usr/bin/env bash&lt;br /&gt;
 cd ~/Apps/GNS3 || exit 1&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 gns3&lt;br /&gt;
&lt;br /&gt;
Simpan, lalu:&lt;br /&gt;
&lt;br /&gt;
 chmod +x ~/Apps/GNS3/start-gns3.sh&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
 ~/Apps/GNS3/start-gns3.sh&lt;br /&gt;
&lt;br /&gt;
== 8. Buat shortcut desktop==&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.local/share/applications&lt;br /&gt;
 nano ~/.local/share/applications/gns3-venv.desktop&lt;br /&gt;
&lt;br /&gt;
Isi:&lt;br /&gt;
&lt;br /&gt;
 [Desktop Entry]&lt;br /&gt;
 Name=GNS3 VENV&lt;br /&gt;
 Comment=Run GNS3 from ~/Apps/GNS3 Python virtual environment&lt;br /&gt;
 Exec=/home/onno/Apps/GNS3/start-gns3.sh&lt;br /&gt;
 Icon=gns3&lt;br /&gt;
 Terminal=false&lt;br /&gt;
 Type=Application&lt;br /&gt;
 Categories=Network;Education;&lt;br /&gt;
&lt;br /&gt;
Aktifkan:&lt;br /&gt;
&lt;br /&gt;
 chmod +x ~/.local/share/applications/gns3-venv.desktop&lt;br /&gt;
 update-desktop-database ~/.local/share/applications 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
== 9. Struktur folder yang disarankan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ~/Apps/GNS3/&lt;br /&gt;
 ├── venv/&lt;br /&gt;
 ├── start-gns3.sh&lt;br /&gt;
 ├── projects/&lt;br /&gt;
 ├── images/&lt;br /&gt;
 └── appliances/&lt;br /&gt;
&lt;br /&gt;
Buat foldernya:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/Apps/GNS3/projects ~/Apps/GNS3/images ~/Apps/GNS3/appliances&lt;br /&gt;
&lt;br /&gt;
Di dalam GNS3 GUI, arahkan path project ke:&lt;br /&gt;
&lt;br /&gt;
 /home/onno/Apps/GNS3/projects&lt;br /&gt;
&lt;br /&gt;
== 10. Kalau error PyQt&lt;br /&gt;
&lt;br /&gt;
Kalau muncul error seperti modul Qt/PyQt tidak ditemukan, coba:&lt;br /&gt;
&lt;br /&gt;
 source ~/Apps/GNS3/venv/bin/activate&lt;br /&gt;
 python -m pip install PyQt6 PyQt6-Sip PyQt6-WebEngine&lt;br /&gt;
&lt;br /&gt;
Lalu jalankan lagi:&lt;br /&gt;
&lt;br /&gt;
 gns3&lt;br /&gt;
&lt;br /&gt;
== 11. Kalau QEMU/KVM tidak jalan==&lt;br /&gt;
&lt;br /&gt;
Cek KVM:&lt;br /&gt;
&lt;br /&gt;
 ls -l /dev/kvm&lt;br /&gt;
 groups&lt;br /&gt;
&lt;br /&gt;
Pastikan user ada di grup `kvm` dan `libvirt`.&lt;br /&gt;
&lt;br /&gt;
Tes QEMU:&lt;br /&gt;
&lt;br /&gt;
 qemu-system-x86_64 --version&lt;br /&gt;
&lt;br /&gt;
Cek libvirt:&lt;br /&gt;
&lt;br /&gt;
 systemctl status libvirtd&lt;br /&gt;
&lt;br /&gt;
Kalau belum aktif:&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl enable --now libvirtd&lt;br /&gt;
&lt;br /&gt;
== 12. Perintah uninstall&lt;br /&gt;
&lt;br /&gt;
Kalau ingin hapus instalasi venv GNS3:&lt;br /&gt;
&lt;br /&gt;
 rm -rf ~/Apps/GNS3/venv&lt;br /&gt;
 rm -f ~/.local/share/applications/gns3-venv.desktop&lt;br /&gt;
&lt;br /&gt;
Package OS seperti QEMU/Wireshark tidak ikut terhapus.&lt;br /&gt;
&lt;br /&gt;
== Ringkasnya==&lt;br /&gt;
&lt;br /&gt;
Paling penting:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/Apps/GNS3&lt;br /&gt;
 cd ~/Apps/GNS3&lt;br /&gt;
 python3 -m venv venv&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 python -m pip install --upgrade pip setuptools wheel&lt;br /&gt;
 python -m pip install gns3-gui gns3-server&lt;br /&gt;
 gns3&lt;br /&gt;
&lt;br /&gt;
Untuk penggunaan serius, tetap install juga:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install qemu-kvm wireshark dynamips vpcs ubridge&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 [1]: https://pypi.org/project/gns3-server/?utm_source=chatgpt.com &amp;quot;gns3-server&amp;quot;&lt;br /&gt;
 [2]: https://pypi.org/project/gns3-gui/?utm_source=chatgpt.com &amp;quot;gns3-gui&amp;quot;&lt;br /&gt;
 [3]: https://gns3.com/gns3-3-0-released?utm_source=chatgpt.com &amp;quot;GNS3 3.0 Released!&amp;quot;&lt;/div&gt;</description>
			<pubDate>Sun, 28 Jun 2026 07:31:40 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:GNS3:_Instalasi_di_Ubuntu_26.04_%2B_VENV_%2B_docker</comments>
		</item>
		<item>
			<title>Gns3</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=Gns3&amp;diff=73679&amp;oldid=73534</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=Gns3&amp;diff=73679&amp;oldid=73534</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Instalasi&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 07:27, 28 June 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-l23&quot; &gt;Line 23:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 23:&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;* [[GNS3: Instalasi di Ubuntu 24.04]]&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;* [[GNS3: Instalasi di Ubuntu 24.04]]&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;* [[GNS3: Instalasi di Ubuntu 26.04]]&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;* [[GNS3: Instalasi di Ubuntu 26.04]]&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;* [[GNS3: Instalasi di Ubuntu 26.04 + VENV + 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;* [[GNS3: Reset]]&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;* [[GNS3: Reset]]&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;* [[GNS3: Router fisik dekat PC running GNS3]]&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;* [[GNS3: Router fisik dekat PC running GNS3]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 28 Jun 2026 07:27:01 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:Gns3</comments>
		</item>
		<item>
			<title>ML: Python Virtual Environment Keras + GPU</title>
			<link>https://onnocenter.or.id/wiki/index.php?title=ML:_Python_Virtual_Environment_Keras_%2B_GPU&amp;diff=73678&amp;oldid=73677</link>
			<guid isPermaLink="false">https://onnocenter.or.id/wiki/index.php?title=ML:_Python_Virtual_Environment_Keras_%2B_GPU&amp;diff=73678&amp;oldid=73677</guid>
			<description>&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;4. Buat virtual environment&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 04:09, 28 June 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-l61&quot; &gt;Line 61:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 61:&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;  cd ~/Apps/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;  cd ~/Apps/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;div&gt;   &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;   &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;python &lt;/del&gt;-m venv keras-gpu&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;python3 &lt;/ins&gt;-m venv keras-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;  source keras-gpu/bin/activate&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;  source keras-gpu/bin/activate&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;   &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;   &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 28 Jun 2026 04:09:51 GMT</pubDate>
			<dc:creator>Onnowpurbo</dc:creator>
			<comments>https://onnocenter.or.id/wiki/index.php/Talk:ML:_Python_Virtual_Environment_Keras_%2B_GPU</comments>
		</item>
</channel></rss>