Cara Pasang SearXNG Sendiri dengan Docker Compose
Ketahui cara memasang enjin carian SearXNG pada VPS menggunakan Docker Compose. Panduan ini merangkumi konfigurasi settings.yml, pengehad, Nginx dengan TLS serta API JSON.
Apa yang anda sedang bina
Self-hosting SearXNG memberikan anda enjin carian peribadi yang berjalan pada pelayan anda sendiri. SearXNG ialah enjin meta-carian: ia mengambil pertanyaan anda, meminta enjin lain seperti Google, Bing, DuckDuckGo dan Wikipedia, kemudian menggabungkan hasil yang diperoleh ke dalam satu halaman keputusan. Tiada profil dibina dan tiada kuki penjejakan ditetapkan, kerana satu-satunya mesin yang menyimpan pertanyaan anda ialah mesin anda sendiri. Jika anda menemui panduan lama untuk sesuatu yang dipanggil Searx sahaja, itu adalah projek asal yang menjadi asas kepada projek ini, dan ia tidak menerima sebarang commit sejak 2023, jadi semak status kedua-duanya sebelum anda mengikuti salah satu daripadanya.
Strukturnya kecil. Dua kontena, satu fail tetapan, satu reverse proxy. Ia boleh berkongsi VPS kecil dengan mudah, yang tidak terpakai untuk setiap servis self-hosted: pustaka foto yang dibandingkan dalam PhotoPrism lawan Immich menetapkan had minimum RAM mereka berdasarkan pengindeks dan bukannya aplikasi web. Keputusan sebenar ialah sama ada instans tersebut bersifat peribadi, bermakna hanya anda dan skrip anda sendiri yang mencapainya, atau awam, bermakna sesiapa sahaja di internet boleh membuat pertanyaan melaluinya. Pilihan itu mengubah tetapan keselamatan, jadi buat keputusan sebelum anda menaip apa-apa. Jawapan lalai ialah peribadi.
Terdapat sebab kedua untuk menjalankannya. Instans SearXNG menggunakan format JSON, jadi mana-mana skrip atau ejen AI yang anda tulis akan mendapat API carian milik anda sendiri, tanpa kunci, tanpa pengebilan setiap pertanyaan dan tanpa e-mel kuota.
Memasang SearXNG dengan Docker Compose
Projek ini menerbitkan imej kontena dan fail Compose. Muat turun kedua-duanya ke pelayan Ubuntu 24.04 baharu yang sudah mempunyai Docker Engine dan pemalam Compose. Jika Docker merupakan perkara baharu bagi anda, mulakan dengan asas Docker Compose pada VPS dan kembali semula 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 .envFail Compose mentakrifkan dua servis. core ialah SearXNG itu sendiri, dan valkey ialah stor data dalam memori yang digunakan untuk pengehadan kadar (rate limiting) dan status jangka pendek. Ia melekapkan ./core-config/ pada /etc/searxng/ di dalam kontena, jadi semua yang anda konfigurasikan berada dalam satu direktori tersebut pada hos.
Sekarang, sunting .env. Setiap baris dalam contoh yang dibekalkan telah diletakkan dalam komen, itulah sebabnya kontena bermula pada port 8080 pada setiap alamat. Buang tanda komen dan tetapkan tiga perkara ini.
SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080SEARXNG_HOST=127.0.0.1 adalah yang penting. Ia menjadikan port yang diterbitkan sebagai 127.0.0.1:8080:8080 dan bukannya [::]:8080:8080, supaya kontena hanya menjawab pada alamat loopback dan internet tidak boleh mencapainya secara terus. Abaikan langkah ini dan kontena akan terdedah sebaik sahaja ia bermula, kerana port Docker yang diterbitkan dimasukkan mendahului peraturan firewall anda. Perangkap itu wajar dibaca sepenuhnya: port Docker yang diterbitkan memintas ufw.
SEARXNG_VERSION=latest adalah memadai semasa anda sedang belajar. Pada pelayan yang penting bagi anda, tetapkan tag (pin). Setakat Julai 2026, tag keluaran adalah berasaskan tarikh dan kelihatan seperti 2026.3.25-541c6c3cb, jadi penggunaan yang ditetapkan (pinned) hanya akan dinaik taraf apabila anda membuat keputusan, bukan apabila registri berubah tanpa pengetahuan anda. Disiplin yang sama berbaloi untuk apa-apa sahaja yang berjalan lama pada mesin tersebut, itulah sebabnya relay RustDesk yang dihoskan sendiri turut menetapkan tag imejnya: naik taraf tanpa pengawasan bagi servis akses jauh biasanya berlaku pada saat yang paling tidak sesuai.
settings.yml: bahagian yang penting
Cipta core-config/settings.yml sebelum permulaan pertama. use_default_settings: true memberitahu SearXNG untuk memuatkan tetapan lalai yang disertakan dan kemudian hanya menggunakan kunci yang anda tulis, supaya fail anda kekal ringkas dan bertahan semasa naik taraf yang menambah pilihan baharu.
Jana secret terlebih dahulu, kerana nilainya dimasukkan terus ke dalam fail.
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. Nilai lalai yang disertakan ialah rentetan literal ultrasecretkey, dan membiarkannya bermakna sesiapa yang mengetahui nilai lalai tersebut boleh memalsukan token tersebut. Gantikannya sekali, kemudian jangan ubahnya lagi: menukarnya kemudian akan memadamkan semua keutamaan yang disimpan.
base_url mestilah alamat HTTPS awam, dengan garis miring (trailing slash) di hujungnya. Ia adalah apa yang ditulis oleh SearXNG ke dalam pautan yang dipaparkannya. Jika dibiarkan menghala ke localhost, pautan "halaman seterusnya" dalam pelayar jauh akan menghala ke mesin pembaca sendiri dan gagal.
formats menentukan jenis output yang akan dihasilkan oleh titik akhir web. json tiada dalam senarai lalai, jadi permintaan JSON akan mengembalikan 403 sehingga anda menambahkannya. image_proxy: true menghalakan lakaran kecil hasil carian melalui pelayan anda, supaya tapak yang mengehoskan imej tersebut tidak akan melihat alamat pelawat anda.
valkey.url menggunakan nama hos valkey kerana itu ialah nama servis dalam fail Compose, dan Compose meletakkan kedua-dua kontena pada satu rangkaian di mana nama servis boleh diselesaikan. Jika dihalakan ke localhost, pengehad (limiter) akan gagal, kerana di dalam kontena core, localhost ialah kontena itu sendiri.
Secret disimpan dalam fail biasa, jadi lindungi direktori di sekelilingnya dan bukannya fail itu sendiri. chmod 750 /opt/searxng menghalang pengguna hos lain daripada mengaksesnya. Jangan ketatkan core-config/settings.yml kepada mod 600: kontena berjalan sebagai pengguna tanpa keistimewaan (unprivileged user) sendiri, dan fail yang tidak boleh dibaca olehnya akan menyebabkan SearXNG gagal bermula sama sekali.
Mulakan stack dan semaknya.
cd /opt/searxng
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080/docker compose ps sepatutnya menunjukkan kedua-dua kontena dalam status running. curl sepatutnya menjawab HTTP/1.1 200 OK. Jika ia tidak menjawab apa-apa, baca docker compose logs core, kerana kesilapan YAML dalam settings.yml akan dipaparkan di sana sebagai ralat penghuraian (parse error) yang menamakan baris tersebut.
Letakkan di belakang nginx dengan TLS
Kontena hanya mendengar pada loopback, jadi nginx yang menjadikannya boleh dicapai, dan ia juga yang menambah keselamatan lapisan pengangkutan (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 semula. Certbot menulis semula fail yang sama untuk mendengar pada port 443 dengan sijil dan menambah ubah hala (redirect) daripada port 80. Rekod DNS untuk search.example.com mestilah sudah menghala ke pelayan ini, kerana pihak berkuasa sijil membuktikan pemilikan dengan mengambil fail melalui HTTP. Panduan lengkap, termasuk pembaharuan, ada dalam panduan Certbot dan nginx untuk Ubuntu 24.04.
Dua pengepala (header) pemajuan tersebut bukan sekadar hiasan. Tanpa X-Forwarded-For dan X-Real-IP, setiap permintaan yang sampai ke SearXNG membawa alamat proksi, jadi pengehad kadar (rate limiter) melihat satu klien membuat semua trafik dan tidak dapat membezakan antara pelawat.
Mengapa skrip dan ejen memerlukan API carian JSON
Dengan json dalam formats, endpoint yang sama yang memaparkan halaman tersebut mengembalikan data berstruktur.
curl -s 'http://127.0.0.1:8080/search?q=wireguard+mtu&format=json' \
| jq -r '.results[0:5][] | .url'Anda akan menerima objek dengan tatasusunan results, di mana setiap entri membawa url, title, content dan enjin yang membekalkannya, di samping answers, infoboxes dan suggestions. Itu sudah memadai untuk membekalkan data kepada peringkas, penyemak pautan, atau gelung penyelidikan. Menyerahkan hasil tersebut kepada model bahasa merupakan langkah yang lebih besar daripada yang disangka, memandangkan hasil carian adalah teks yang tidak dipercayai dan boleh membawa arahan tersendiri, iaitu perkara yang dibincangkan secara terperinci dalam menghalakan ejen AI ke instans SearXNG anda.
Perkara ini penting bagi apa-apa sahaja yang berbentuk ejen. Model bahasa mempunyai had masa latihan, jadi ia memerlukan carian langsung untuk menjawab soalan tentang masa kini, manakala API carian komersial mengenakan bayaran bagi setiap pertanyaan dan mempunyai had kadar yang ketat. Instans tempatan hanya memerlukan satu kontena pada pelayan yang sudah anda bayar, dan pertanyaan tersebut tidak pernah keluar dari pelayan itu. Jika anda menyambungkan alatan ke dalam model, penaakulan yang sama mendorong menjalankan pelayan MCP pada VPS, di mana alat carian biasanya merupakan alat pertama yang ditambah oleh pengguna.
Dua peraturan untuk penggunaan API. Pastikan instans bersifat peribadi, jadi ikat bahagian API kepada alamat loopback atau rangkaian peribadi dan benarkan hanya hos anda sendiri untuk mencapainya. Kemudian, buat pertanyaan secara berhemah. SearXNG memajukan permintaan anda kepada enjin carian sebenar, jadi skrip yang menjalankan seratus pertanyaan sesaat bermakna anda meminta Google untuk menyekat pelayan anda.
Limiter, dan perkara yang berubah untuk instans awam
Limiter ialah pertahanan bot SearXNG. Ia memantau pengepala permintaan, alamat dan kadar permintaan, serta menggugurkan trafik yang kelihatan automatik. Ia memerlukan Valkey untuk menyimpan status tersebut, itulah sebabnya fail Compose menyertakannya.
Pada instans peribadi, kekalkan limiter: false. Skrip anda sendiri secara definisinya adalah trafik automatik, jadi limiter akan menyekat panggilan JSON yang anda bina instans tersebut untuknya. Kawalan akses sebaliknya adalah tugas reverse proxy: pasangan allow dan deny dalam location nginx, pengesahan asas HTTP, atau firewall yang hanya membenarkan pelayan anda yang lain. Jika anda perlu mencapai instans peribadi daripada komputer riba yang bertukar-tukar rangkaian, meletakkan alamat onion v3 di hadapannya ialah pilihan keempat, kerana tor bersambung ke port loopback yang sama tanpa mendedahkan apa-apa yang baharu kepada internet.
Jika anda menerbitkan instans tersebut untuk orang lain, hidupkan kedua-dua suis.
server:
limiter: true
public_instance: trueKawalan yang lebih terperinci terdapat dalam core-config/limiter.toml, yang dibaca oleh kontena pada /etc/searxng/limiter.toml. Anda hanya perlu menulis kunci yang ingin diubah. Di sebalik proksi, anda mesti mengisytiharkan proksi tersebut, atau limiter akan menganggap alamat nginx anda sebagai satu-satunya klien yang menyalahgunakan sistem.
[botdetection]
trusted_proxies = [
'127.0.0.0/8',
'::1',
]
[botdetection.ip_limit]
link_token = truelink_token = true menyebabkan SearXNG mengeluarkan token yang hanya akan diambil oleh sesi pelayar sebenar, yang menghentikan kebanyakan pengikis (scraper) ringkas. Jangkakan instans awam akan menarik perhatian mereka dalam masa beberapa hari. Jangkakan juga ralat enjin, kerana lebih banyak trafik yang anda majukan, lebih cepat enjin hulu (upstream) mula mengembalikan CAPTCHA ke alamat pelayan anda. Instans SearXNG awam ialah tugas yang berterusan. Instans peribadi pula tidak, itulah sebabnya ia berada dalam kebanyakan senarai pendek perkara yang berbaloi untuk di-self-host pada tahun 2026. Tidak semua entri dalam senarai tersebut adalah infrastruktur: membina semula pustaka Jellyfin sebagai kedai sewa era 90-an yang boleh dilayari adalah kontena yang sama di sebalik blok nginx yang sama, yang ditujukan untuk hiburan waktu malam dan bukannya aliran kerja.
Mengapa carian tidak memulangkan hasil
Buka /stats pada instans anda. Ia menyenaraikan setiap enjin beserta kadar ralat dan masa responsnya, dan ia merupakan tempat pertama untuk diperiksa apabila hasil carian terasa berkurangan.
Enjin yang memaparkan ralat "Access denied" atau "CAPTCHA" telah menyekat alamat pelayan anda. Keadaan ini biasa berlaku pada alamat dalam julat pusat data kerana enjin carian menganggap alamat tersebut milik scraper. SearXNG kemudian menggantung enjin yang gagal itu untuk suatu tempoh dan bukannya mencuba semula, lalu satu enjin yang disekat hilang daripada hasil carian tanpa disedari. Nyahdayakannya dalam settings.yml atau terima kehilangan tersebut. Namun, itu bukan satu-satunya pilihan kerana sesetengah sekatan CAPTCHA mempunyai penyelesaian yang kekal selepas restart. Enjin yang lain masih memberikan respons. Kod 429 merupakan kes yang tidak jelas kerana kod itu boleh berpunca daripada limiter anda sendiri atau daripada enjin huluan yang menolak pelayan anda. Baris log menunjukkan yang mana satu berlaku sebelum anda mula mengubah tetapan.
Jika setiap enjin gagal serentak, kontena tersebut tidak mempunyai resolusi nama keluar yang berfungsi atau tiada laluan ke internet. Uji perkara itu dari dalam kontena.
docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo okTiada apa-apa pada kotak pelayan yang akan memberitahu anda apabila semakan itu mula gagal, jadi jalankan ia daripada cron dan biarkan kegagalan menolak makluman ke telefon anda daripada pelayan ntfy anda sendiri dan bukannya menunggu sehingga anda perasan hasil carian telah menjadi sedikit.
FAQ
Adakah SearXNG menjadikan carian saya tanpa nama?
Ia menyembunyikan identiti anda daripada enjin carian yang dihubungi, kerana enjin tersebut melihat pelayan anda yang membuat permintaan, bukannya pelayar web anda. Ia tidak menyembunyikan pertanyaan daripada pelayan anda, dan ia tidak menyembunyikan pelayan anda daripada enjin carian tersebut. Pada instans pengguna tunggal, semua trafik daripada alamat tersebut adalah milik anda, jadi alamat itu sendiri menjadi pengecam. Trafik antara pelayar web anda dan instans anda dilindungi oleh sijil TLS. Kedudukan anda berbanding ISP, pengendali instans awam, dan enjin carian itu sendiri diperincikan dalam apa yang sebenarnya disembunyikan oleh SearXNG.
Mengapa permintaan JSON mengembalikan 403 Forbidden?
Terdapat dua punca, dan kedua-duanya berkaitan dengan konfigurasi. Sama ada json tiada dalam senarai formats di bawah search: dalam settings.yml, yang merupakan keadaan lalai, atau pengehad (limiter) diaktifkan dan telah mengelaskan skrip anda sebagai bot. Tambahkan format tersebut terlebih dahulu, mulakan semula dengan docker compose restart core, kemudian cuba lagi. Jika ia masih gagal, tetapkan limiter: false dan kawal akses pada reverse proxy sebagai gantinya.
Adakah saya memerlukan kontena Valkey jika saya mematikan pengehad?
Biarkan ia berjalan. SearXNG boleh berfungsi tanpanya, tetapi pengehad tidak boleh diaktifkan kemudian tanpa Valkey, dan ia juga menyimpan status jangka pendek yang lain. Kontena tersebut bersaiz kecil dan hanya menyimpan data cache, jadi membuangnya hanya menjimatkan ruang yang sangat sedikit dan menyebabkan anda kehilangan pilihan tersebut.
Bagaimanakah cara untuk mengemas kini SearXNG?
Jalankan docker compose pull kemudian docker compose up -d dalam /opt/searxng. Compose akan mencipta semula mana-mana kontena yang imejnya telah berubah dan membiarkan direktori core-config/ anda tidak disentuh, jadi settings.yml akan kekal. Kerana use_default_settings: true menggabungkan kunci anda dengan tetapan lalai yang dibekalkan, pilihan yang ditambah di peringkat upstream akan tiba dengan nilai yang munasabah dan tidak merosakkan fail tersebut.
Bolehkah beberapa orang berkongsi satu instans?
Ya, dan itulah keadaan di mana anda perlu mengaktifkan pengehad dan menetapkan public_instance: true. Keutamaan (preferences) disimpan dalam pelayar web setiap pelawat, jadi tiada akaun yang perlu diuruskan. Pantau /stats selama seminggu selepas membukanya kepada orang lain, kerana enjin carian upstream akan mula menolak pelayan anda jauh sebelum anda menyedari kehilangan hasil carian.