Cara Self-Host SearXNG dengan Docker Compose
Jalankan SearXNG privat di VPS dengan Docker Compose. Panduan ini mencakup settings.yml, limiter, nginx dengan TLS, dan API JSON tanpa key atau biaya per kueri.
Yang Anda bangun
Self-hosting SearXNG memberi Anda mesin pencari privat yang berjalan di server milik Anda sendiri. SearXNG adalah mesin metapencarian: mesin ini menerima kueri Anda, meminta hasil dari mesin lain seperti Google, Bing, DuckDuckGo, dan Wikipedia, lalu menggabungkan hasilnya menjadi satu halaman hasil. Tidak ada profil yang dibuat dan tidak ada cookie pelacakan yang ditetapkan, karena satu-satunya mesin yang menyimpan kueri Anda adalah mesin milik Anda sendiri.
Stack ini kecil. Dua container, satu file pengaturan, dan satu reverse proxy. Keputusan utamanya adalah apakah instance tersebut bersifat privat, yang berarti hanya Anda dan skrip milik Anda sendiri yang dapat mengaksesnya, atau publik, yang berarti siapa pun di internet dapat mengirim kueri ke instance tersebut. Pilihan ini mengubah pengaturan keamanan, jadi tentukan sebelum Anda mengetik apa pun. Jawaban default-nya adalah privat.
Ada alasan kedua untuk menjalankannya. Instance SearXNG menggunakan JSON, sehingga skrip atau agen AI apa pun yang Anda buat memperoleh API pencarian yang Anda miliki sendiri, tanpa key, biaya per kueri, atau email tentang kuota.
Instal SearXNG dengan Docker Compose
Proyek ini menyediakan image container dan file Compose. Tarik keduanya ke server Ubuntu 24.04 baru yang sudah memiliki Docker Engine dan plugin Compose. Jika Docker masih baru bagi Anda, mulai dengan Dasar-dasar Docker Compose pada VPS, lalu kembali ke sini.
sudo install -d -o "$USER" -g "$USER" -m 750 /opt/searxng
cd /opt/searxng
mkdir -p core-config
curl -fsSL \
-O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \
-O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example
cp -i .env.example .envFile Compose mendefinisikan dua layanan. core adalah SearXNG, sedangkan valkey adalah penyimpanan data dalam memori yang digunakan untuk pembatasan laju dan status sementara. File ini memasang ./core-config/ ke /etc/searxng/ di dalam container, sehingga semua konfigurasi yang Anda buat berada dalam satu direktori tersebut di host.
Sekarang edit .env. Semua baris dalam contoh yang disediakan diberi komentar. Karena itu, container dimulai pada port 8080 di semua alamat. Hapus tanda komentar dan atur tiga baris berikut.
SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080SEARXNG_HOST=127.0.0.1 adalah pengaturan yang paling penting. Pengaturan ini membuat port yang dipublikasikan menjadi 127.0.0.1:8080:8080, bukan [::]:8080:8080, sehingga container hanya menerima koneksi pada alamat loopback dan internet tidak dapat mengaksesnya secara langsung. Jika langkah ini dilewati, container langsung terekspos saat dimulai karena port Docker yang dipublikasikan ditempatkan sebelum aturan firewall Anda. Baca penjelasan lengkap tentang masalah ini: port Docker yang dipublikasikan melewati ufw.
SEARXNG_VERSION=latest dapat digunakan saat Anda masih belajar. Pada server penting, tetapkan tag secara eksplisit. Per Juli 2026, tag rilis menggunakan tanggal dan berbentuk 2026.3.25-541c6c3cb, sehingga deployment yang menggunakan tag tetap hanya diperbarui saat Anda memutuskan, bukan saat registry berubah tanpa pemberitahuan.
settings.yml: bagian yang penting
Buat core-config/settings.yml sebelum memulai pertama kali. use_default_settings: true memberi tahu SearXNG untuk memuat default bawaan yang disertakan, lalu hanya menerapkan kunci yang Anda tulis. Dengan demikian, file Anda tetap singkat dan tetap berfungsi setelah upgrade yang menambahkan opsi baru.
Buat secret terlebih dahulu karena nilainya akan langsung dimasukkan ke file.
openssl rand -hex 32use_default_settings: true
general:
instance_name: "search.example.com"
server:
base_url: "https://search.example.com/"
secret_key: "paste-the-openssl-output-here"
limiter: false
public_instance: false
image_proxy: true
valkey:
url: valkey://valkey:6379/0
search:
safe_search: 0
autocomplete: "duckduckgo"
formats:
- html
- jsonsecret_key menandatangani data sesi dan token. Default bawaan adalah string literal ultrasecretkey. Jika dibiarkan, siapa pun yang mengetahui default tersebut dapat memalsukan token itu. Ganti sekali, lalu jangan ubah lagi: perubahan berikutnya akan menghapus semua preferensi yang tersimpan.
base_url harus berupa alamat HTTPS publik dengan garis miring di akhir. SearXNG menggunakan alamat ini saat menulis tautan yang ditampilkannya. Jika tetap mengarah ke localhost, tautan "halaman berikutnya" di browser jarak jauh akan mengarah ke mesin milik pembaca sendiri dan gagal.
formats menentukan jenis output yang akan dihasilkan endpoint web. json tidak ada dalam daftar default, sehingga permintaan JSON akan mengembalikan 403 sampai Anda menambahkannya. image_proxy: true merutekan thumbnail hasil melalui server Anda, sehingga situs yang meng-host gambar tersebut tidak pernah melihat alamat pengunjung Anda.
valkey.url menggunakan hostname valkey karena nama tersebut adalah nama layanan dalam file Compose. Compose menempatkan kedua container dalam satu network sehingga nama layanan dapat di-resolve. Jika diarahkan ke localhost, limiter akan gagal karena di dalam container core, localhost adalah container tersebut.
Secret disimpan dalam file biasa. Karena itu, lindungi direktori di sekitarnya, bukan file itu sendiri. chmod 750 /opt/searxng mencegah pengguna host lain mengaksesnya. Jangan memperketat core-config/settings.yml menjadi mode 600: container berjalan sebagai pengguna tanpa hak khusus, dan jika pengguna tersebut tidak dapat membaca file, SearXNG tidak akan dapat memulai sama sekali.
Mulai stack, lalu periksa.
cd /opt/searxng
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080/docker compose ps seharusnya menampilkan kedua container dalam status running. curl seharusnya memberikan respons HTTP/1.1 200 OK. Jika tidak memberikan respons, baca docker compose logs core karena kesalahan YAML dalam settings.yml akan muncul di sana sebagai kesalahan parsing yang menyebutkan barisnya.
Tempatkan di belakang nginx dengan TLS
Container hanya mendengarkan pada loopback. nginx membuatnya dapat dijangkau dan menambahkan keamanan lapisan transport (TLS). Tulis /etc/nginx/sites-available/searxng.
server {
listen 80;
server_name search.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}sudo ln -s /etc/nginx/sites-available/searxng /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d search.example.comnginx -t mencetak syntax is ok dan test is successful sebelum Anda memuat ulang konfigurasi. Certbot menulis ulang file yang sama agar mendengarkan pada 443 dengan sertifikat dan menambahkan pengalihan dari port 80. Rekaman DNS untuk search.example.com harus sudah mengarah ke server ini, karena otoritas sertifikat membuktikan kepemilikan dengan mengambil file melalui HTTP. Panduan lengkap, termasuk perpanjangan sertifikat, tersedia dalam panduan Certbot dan nginx untuk Ubuntu 24.04.
Kedua header penerusan tersebut bukan sekadar pelengkap. Tanpa X-Forwarded-For dan X-Real-IP, setiap permintaan yang tiba di SearXNG membawa alamat proxy. Akibatnya, pembatas laju menganggap satu klien menghasilkan seluruh lalu lintas dan tidak dapat membedakan pengunjung.
Mengapa skrip dan agen memerlukan API pencarian JSON
Dengan json di formats, endpoint yang sama untuk merender halaman juga mengembalikan data terstruktur.
curl -s 'http://127.0.0.1:8080/search?q=wireguard+mtu&format=json' \
| jq -r '.results[0:5][] | .url'Anda menerima sebuah objek dengan array results. Setiap entri berisi url, title, content, dan mesin yang menyediakannya, serta answers, infoboxes, dan suggestions. Data ini cukup untuk memberi masukan ke peringkas, pemeriksa tautan, atau loop penelitian.
Hal ini penting untuk semua hal yang berbasis agen. Model bahasa memiliki batas waktu data pelatihan. Karena itu, model memerlukan pencarian langsung untuk menjawab pertanyaan tentang kondisi saat ini. API pencarian komersial mengenakan biaya per kueri dan menerapkan pembatasan laju yang ketat. Instans lokal hanya memerlukan satu container pada server yang sudah Anda biayai. Kueri juga tidak pernah meninggalkan server tersebut. Jika Anda menghubungkan berbagai alat ke model, alasan yang sama berlaku untuk menjalankan server MCP di VPS. Alat pencarian biasanya menjadi alat pertama yang ditambahkan.
Ada 2 aturan untuk penggunaan API. Jaga agar instans tetap privat. Ikat sisi API ke alamat loopback atau jaringan privat. Dengan demikian, hanya host Anda yang dapat mengaksesnya. Kemudian, kirim kueri secara wajar. SearXNG meneruskan permintaan Anda ke mesin pencarian nyata. Jadi, skrip yang menjalankan seratus kueri per detik dapat menyebabkan Google memblokir server Anda.
Pembatas laju dan perubahan untuk instans publik
Pembatas laju adalah pertahanan SearXNG terhadap bot. Pembatas ini memantau header permintaan, alamat, dan laju permintaan, lalu menolak lalu lintas yang terlihat otomatis. Pembatas ini memerlukan Valkey untuk menyimpan status tersebut. Karena itu, Valkey disertakan dalam file Compose.
Pada instans privat, pertahankan limiter: false. Skrip Anda sendiri secara definisi menghasilkan lalu lintas otomatis. Karena itu, pembatas laju akan memblokir panggilan JSON yang menjadi alasan Anda membuat instans tersebut. Sebagai gantinya, kontrol akses menjadi tugas reverse proxy: pasangan allow dan deny dalam location nginx, autentikasi dasar HTTP, atau firewall yang hanya mengizinkan server lain milik Anda.
Jika Anda menerbitkan instans tersebut untuk digunakan orang lain, aktifkan kedua sakelar.
server:
limiter: true
public_instance: trueKontrol yang lebih terperinci berada di core-config/limiter.toml, yang dibaca container dari /etc/searxng/limiter.toml. Anda hanya perlu menulis kunci yang ingin diubah. Di balik proxy, Anda harus mendeklarasikan proxy tersebut. Jika tidak, pembatas laju akan menganggap alamat nginx Anda sebagai satu-satunya klien yang melakukan penyalahgunaan.
[botdetection]
trusted_proxies = [
'127.0.0.0/8',
'::1',
]
[botdetection.ip_limit]
link_token = truelink_token = true membuat SearXNG menerbitkan token yang hanya akan diambil oleh sesi browser nyata. Hal ini menghentikan sebagian besar scraper sederhana. Perkirakan instans publik akan menarik scraper tersebut dalam beberapa hari. Perkirakan juga munculnya kesalahan engine. Semakin banyak lalu lintas yang Anda teruskan, semakin cepat engine upstream mulai mengirim CAPTCHA ke alamat server Anda. Instans SearXNG publik memerlukan pemeliharaan berkelanjutan. Instans privat tidak memerlukannya. Karena itu, instans privat biasanya termasuk dalam daftar singkat hal yang layak di-hosting sendiri pada 2026.
Alasan pencarian tidak menghasilkan apa pun
Buka /stats pada instance Anda. Halaman ini mencantumkan setiap engine beserta tingkat kesalahan dan waktu responsnya. Halaman ini adalah tempat pertama yang perlu diperiksa ketika hasil pencarian terlalu sedikit.
Engine yang menampilkan kesalahan "Access denied" atau "CAPTCHA" telah memblokir alamat server Anda. Hal ini umum terjadi pada alamat dalam rentang pusat data karena mesin pencari menganggap alamat tersebut milik scraper. SearXNG kemudian menangguhkan engine yang gagal selama jangka waktu tertentu, bukan mencoba kembali. Akibatnya, satu engine yang diblokir tidak lagi digunakan dan hasil pencarian Anda berkurang tanpa pemberitahuan. Nonaktifkan engine tersebut di settings.yml atau terima pengurangan hasilnya. Engine lainnya tetap memberikan respons.
Jika semua engine gagal secara bersamaan, container tidak memiliki resolusi nama keluar yang berfungsi atau tidak memiliki rute ke internet. Uji kondisi tersebut dari dalam container.
docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo okFAQ
Apakah SearXNG membuat pencarian saya anonim?
SearXNG menyembunyikan identitas Anda dari mesin pencari yang dituju karena mesin tersebut melihat server Anda yang mengirimkan permintaan, bukan browser Anda. SearXNG tidak menyembunyikan kueri dari server Anda dan tidak menyembunyikan server Anda dari mesin pencari tersebut. Pada instans untuk satu pengguna, semua traffic dari alamat tersebut berasal dari Anda, sehingga alamat itu sendiri menjadi pengenal. Traffic antara browser dan instans Anda dilindungi oleh sertifikat TLS.
Mengapa permintaan JSON mengembalikan 403 Forbidden?
Ada dua penyebab, dan keduanya terkait konfigurasi. json mungkin tidak ada dalam daftar formats di bawah search: dalam settings.yml, yang merupakan keadaan default, atau limiter aktif dan mengklasifikasikan skrip Anda sebagai bot. Tambahkan format tersebut terlebih dahulu, mulai ulang dengan docker compose restart core, lalu coba lagi. Jika masih gagal, tetapkan limiter: false dan kendalikan akses di reverse proxy.
Apakah saya memerlukan container Valkey jika limiter tetap dinonaktifkan?
Biarkan container tersebut tetap berjalan. SearXNG dapat bekerja tanpanya, tetapi limiter tidak dapat diaktifkan nanti tanpa container tersebut. Container itu juga menyimpan state lain yang berumur singkat. Ukuran container kecil dan hanya menyimpan data cache, sehingga menghapusnya hanya menghemat sedikit ruang dan menghilangkan opsi bagi Anda.
Bagaimana cara memperbarui SearXNG?
Jalankan docker compose pull lalu docker compose up -d di /opt/searxng. Compose membuat ulang setiap container yang image-nya berubah dan membiarkan direktori core-config/ tetap utuh, sehingga settings.yml tetap tersimpan. Karena use_default_settings: true menggabungkan kunci Anda di atas nilai default yang disertakan, opsi yang ditambahkan oleh upstream akan menggunakan nilai yang sesuai, bukan menyebabkan file rusak.
Dapatkah beberapa orang menggunakan satu instans secara bersama-sama?
Ya. Dalam kondisi ini, aktifkan limiter dan tetapkan public_instance: true. Preferensi disimpan di browser masing-masing pengunjung, sehingga tidak ada akun yang perlu dikelola. Pantau /stats selama seminggu setelah instans dibuka untuk umum karena mesin pencari upstream mulai menolak server Anda jauh sebelum Anda menyadari bahwa hasil pencarian berkurang.