SSD Nodes Learn 🎉 VPS mulai $5.50/bln
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-13

Cara Self-Host OpenTag untuk Mention @agent

Jalankan OpenTag v0.9.0 di VPS agar mention Slack dan GitHub memicu coding agent, dengan TLS, verifikasi signature webhook, scope token, dan default aman.

Hal yang dilakukan OpenTag saat Anda menyebut agen

OpenTag mengubah @mention dalam thread Slack atau issue GitHub menjadi eksekusi coding agent pada mesin yang Anda miliki. Seseorang menambahkan komentar @opentag investigate this pada issue. Listener menerima event platform, memeriksa signature-nya, mencocokkan mention dengan project yang terikat, menjalankan coding agent pada checkout lokal, lalu memposting hasilnya kembali ke thread yang sama.

Project ini menggunakan lisensi MIT dan tersedia di amplifthq/opentag. Per Agustus 2026, release bertag terbaru adalah v0.9.0, yang dipublikasikan pada 28 July 2026, dan didistribusikan sebagai package npm. Tidak ada container image resmi, sehingga versi yang harus Anda pin adalah versi npm. Semua command di bawah melakukan pin pada versi tersebut.

Ini menjadi project VPS, bukan project laptop, karena sisi GitHub. GitHub mengirimkan event repository dengan membuat request HTTP ke URL yang Anda daftarkan satu kali. Karena itu, URL tersebut harus merespons pada alamat yang sama esok hari.

Empat komponen utama

Listener menerima event dari platform, dan setiap platform memiliki listener sendiri. Listener GitHub adalah endpoint HTTP pada port 3050 di path /github/webhooks. Listener Slack Events API berada pada port 3040 di /slack/events. Slack juga dapat berjalan dalam Socket Mode. Dalam mode ini, aplikasi membuka WebSocket keluar dan sama sekali tidak memerlukan port masuk.

Dispatcher adalah koordinator. Secara default, dispatcher mendengarkan port 3030, menyimpan status eksekusi dalam file database lokal yang ditentukan oleh OPENTAG_DATABASE_PATH, serta mencatat jejak audit untuk setiap eksekusi. Tidak ada koneksi dari luar server yang boleh mencapai port ini.

Runner adalah daemon lokal. Runner melakukan polling untuk mencari pekerjaan, mengambil alih eksekusi, mempertahankan lease atas eksekusi tersebut, dan mengirim heartbeat setiap 15 detik secara default selama eksekusi masih berjalan. Runner menolak setiap eksekusi yang sudah diambil jika target project tidak ada atau berada di luar allowlist dalam konfigurasinya sendiri. Pemeriksaan ini mencegah event GitHub mengarahkan agent ke repository yang belum Anda tautkan.

Executor adalah coding agent itu sendiri. OpenTag menjalankannya melalui ACP (agent client protocol), yaitu protokol JSON-RPC yang menggunakan input dan output standar. Dengan demikian, agent berjalan sebagai child process di dalam working directory yang diberikan OpenTag. Nama bawaan mencakup echo, codex, claude-code, cursor, opencode, hermes, dan openclaw. Mulailah dengan echo, yaitu executor yang disertakan dalam contoh konfigurasi, karena executor ini membuktikan bahwa seluruh alur berfungsi sebelum model mengubah kode Anda.

Urutannya tidak pernah berubah: event platform, pemeriksaan signature, pencatatan eksekusi, pengambilan alih, agent, lalu balasan di thread.

Mengapa laptop dan tunnel saja tidak cukup

Panduan penyiapan GitHub meminta Anda menjalankan ngrok http 3050 lalu menempelkan host tunnel ke webhook repository. Cara ini berfungsi selama sepuluh menit pertama. Host tunnel gratis berubah setiap kali proses dimulai ulang dan tidak lagi tersedia saat laptop masuk mode tidur. GitHub tetap menyimpan URL payload lama dan terus mencoba mengaksesnya. Akibatnya, tab Recent Deliveries pada pengaturan webhook dipenuhi kegagalan, sementara thread tetap diam. Tidak ada yang menyadarinya selama seminggu karena webhook yang tidak melakukan apa pun terlihat sama seperti bot yang tidak pernah disebutkan.

VPS mengatasi dua masalah tersebut. Nama DNS tidak berubah, sehingga URL payload yang ditempel sekali tetap benar. Mesin tidak masuk mode tidur, sehingga komentar pada pukul 02:00 tetap mendapat jawaban. Siapkan server dengan benar terlebih dahulu: sepuluh menit pertama pada VPS baru membahas pengguna login dan firewall yang diasumsikan oleh panduan ini.

Slack adalah pengecualian. Dalam Socket Mode, Slack membuat koneksi keluar dan tidak memerlukan URL publik, sehingga deployment khusus Slack dapat tetap tertutup. GitHub tidak memiliki mekanisme yang setara. Webhook repository adalah HTTP masuk. Artinya, Anda memerlukan endpoint publik, TLS (keamanan lapisan transport), dan pemeriksaan tanda tangan.

Host OpenTag secara mandiri di Ubuntu dari rilis yang dipatok

OpenTag v0.9.0 memerlukan Node.js 22 atau yang lebih baru. Ubuntu 24.04 menyediakan Node 18 di repositorinya sendiri, jadi instal dari NodeSource.

curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejs
node -v

node -v harus mencetak v22 atau yang lebih tinggi. Pada Node 20, instalasi mencetak peringatan EBADENGINE dan CLI dapat gagal saat mulai berjalan.

Buat akun khusus untuk service. Agent berjalan dengan izin pengguna ini, jadi akun tersebut bukan akun login Anda dan bukan root. Pengguna dengan hak minimum pada VPS menjelaskan alasan pemisahan ini layak dilakukan.

sudo adduser --disabled-password --gecos "" opentag
sudo loginctl enable-linger opentag
sudo npm install -g @opentag/cli@0.9.0
command -v opentag

command -v opentag harus mencetak path seperti /usr/bin/opentag. Pengaturan linger penting di Linux: OpenTag memasang service latar belakang melalui systemd, dan user service tanpa linger berhenti begitu sesi SSH Anda ditutup.

Jalankan setup sebagai pengguna tersebut.

sudo -iu opentag opentag setup

Setup menanyakan enam hal: bahasa CLI, alamat listening lokal, coding agent, project lokal yang akan digunakan, kredensial platform yang akan disimpan, dan cara menjalankannya. Pertahankan alamat listening pada 127.0.0.1, karena nginx menghentikan TLS dan meneruskan koneksi ke alamat tersebut. Dengan demikian, listener tidak perlu dapat dijangkau dari luar. Untuk GitHub, setup juga menanyakan repository dalam format owner/repo, apakah setup boleh membuka pull request, port webhook (3050 secara default), dan token. Pilih mode background service pada langkah terakhir. Jika Anda sudah memiliki config dan ingin memasang service tanpa prompt, opentag setup --service melakukannya.

Config disimpan di /home/opentag/.config/opentag/config.json dan state runtime di /home/opentag/.local/state/opentag. Setelah setup menulis file tersebut, periksa key ini secara manual.

{
  "runnerId": "runner_local",
  "dispatcherUrl": "http://localhost:3030",
  "runnerToken": "...",
  "approvalMode": "ask",
  "repositories": []
}

Utamakan runnerToken, yaitu bearer token dengan cakupan runner, daripada pairingToken yang lebih lama dan digunakan bersama. File config menyimpan kredensial dalam teks biasa, kecuali Anda menggantinya dengan referensi secret. Referensi ini membaca nilainya dari environment atau dari file di disk saat startup. Bagaimanapun, file ini adalah hal paling sensitif di server: gunakan mode 600, miliki oleh opentag, dan jangan pernah menyimpannya di dalam repository git. Penjelasan yang lebih luas tersedia di menjaga secret tetap di luar AI agent.

Periksa instalasi sebelum mengekspos apa pun.

sudo -iu opentag opentag doctor
sudo -iu opentag opentag status

opentag doctor memeriksa dispatcher, binding, checkout, dan executor. opentag status mencetak config dan state runtime, serta dapat dibatasi ke satu run setelah run tersedia. Perbaiki semua hal yang dilaporkan doctor sebelum Anda menghubungkan platform ke server ini.

Letakkan TLS di depan dan buka hanya dua path

nginx menangani terminasi TLS dan meneruskan tepat dua path. Semua path lainnya mengembalikan 404. Dengan demikian, pemindai yang menemukan host tersebut tidak dapat mengetahui apa yang berjalan di belakangnya.

Tulis server block biasa pada port 80 di /etc/nginx/sites-available/opentag dengan dua lokasi berikut, lalu biarkan Certbot menambahkan bagian TLS.

sudo apt install -y nginx certbot python3-certbot-nginx
sudo ln -s /etc/nginx/sites-available/opentag /etc/nginx/sites-enabled/opentag
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d opentag.example.com

nginx -t mencetak syntax is ok dan test is successful. Ini satu-satunya pengaman antara kesalahan pengetikan dan reload yang membuat situs tidak dapat diakses. Certbot pada Ubuntu 24.04 dengan nginx membahas pembaruan serta penyebab kegagalan challenge ACME (automatic certificate management environment). Hasil akhirnya terlihat seperti ini.

server {
    listen 443 ssl;
    server_name opentag.example.com;

    ssl_certificate     /etc/letsencrypt/live/opentag.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/opentag.example.com/privkey.pem;

    client_max_body_size 2m;

    location = /github/webhooks {
        proxy_pass http://127.0.0.1:3050;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location = /slack/events {
        proxy_pass http://127.0.0.1:3040;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location / {
        return 404;
    }
}

= di location = /github/webhooks adalah pencocokan persis, sedangkan proxy_pass tanpa apa pun setelah port meneruskan URI asli tanpa perubahan. Jika = dihapus, semua path di bawah /github/webhooks/ juga akan diteruskan. Ini memperluas permukaan akses melebihi kebutuhan listener.

Firewall tetap dibatasi.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

Port 3030, 3040, dan 3050 tidak pernah dibuka. Pastikan port-port tersebut terikat ke loopback, bukan ke semua interface.

sudo ss -tlnp

Setiap baris OpenTag harus berbentuk 127.0.0.1:3030 atau serupa. Baris yang berbentuk 0.0.0.0:3050 berarti listener tersebut menawarkan akses ke seluruh Internet dan hanya ufw yang mencegahnya, sehingga satu kesalahan konfigurasi firewall dapat membuka pemicu agen. Dasar-dasar firewall ufw menjelaskan fungsi default deny tersebut.

Dua pemeriksaan ini membuktikan bahwa pintu depan berfungsi. curl -I https://opentag.example.com/ mengembalikan 404 dari nginx. Ini menunjukkan bahwa sertifikat valid dan catch-all tertutup. Permintaan ke /slack/events atau /github/webhooks tanpa tanda tangan tidak boleh mengembalikan 200.

Verifikasi setiap tanda tangan karena URL bersifat publik

Siapa pun dapat menemukan URL payload. URL tersebut tersimpan di pengaturan repositori, riwayat browser, atau tangkapan layar yang ditempelkan ke tiket. Tanda tangan adalah satu-satunya pembeda antara delivery GitHub yang sah dan permintaan yang ditulis secara manual oleh seseorang.

GitHub menandatangani setiap delivery menggunakan secret webhook dan mengirimkan hasilnya dalam header x-hub-signature-256. OpenTag memverifikasi header tersebut terhadap platforms.github.webhookSecret. Catatan hardening proyek menyatakan aturan ini secara langsung: jangan menerima event sumber tanpa tanda tangan pada /github/webhooks. Slack menandatangani setiap permintaan menggunakan SLACK_SIGNING_SECRET dan menyertakan timestamp, sehingga body yang ditangkap tidak dapat diputar ulang beberapa jam kemudian.

Mengabaikan hal ini bukan risiko kecil. Endpoint yang tidak diverifikasi menerima payload issue_comment yang ditulis secara manual dan berisi @opentag. OpenTag kemudian menjalankan coding agent menggunakan token Anda, di checkout Anda, berdasarkan instruksi dari orang yang tidak dikenal. Balasannya dikirim ke thread yang disebutkan oleh payload palsu tersebut.

OpenTag menambahkan dua lapisan perlindungan. Delivery sumber dilacak berdasarkan ID delivery, sehingga pengiriman ulang event yang sama tidak memulai proses kedua. Panggilan runner menerima kunci idempotensi, sehingga pemutaran ulang satu panggilan mengembalikan status berhasil tanpa menambahkan event audit lain.

Batas laju dapat dikonfigurasi dan harus diaktifkan. OPENTAG_RATE_LIMIT_WINDOW_MS dan OPENTAG_RATE_LIMIT_MAX_REQUESTS membatasi laju permintaan, OPENTAG_MAX_REQUEST_BODY_BYTES membatasi ukuran body, dan payload yang terlalu besar ditolak dengan 413 request_body_too_large. OPENTAG_RATE_LIMIT_DISABLED=true tersedia untuk pengembangan lokal dan tidak boleh digunakan pada server publik. Ada satu aturan lain dari catatan yang sama: URL relay publik harus menggunakan HTTPS, dan CLI hanya mengizinkan HTTP biasa untuk localhost.

Cakupan token apa yang sebenarnya dibutuhkan bot?

Di GitHub, OpenTag menggunakan personal access token dengan cakupan terperinci, bukan GitHub App. Dokumentasi menyebutkan bahwa penggunaan App direncanakan dan saat ini bukan konfigurasi CLI default. Hal ini menimbulkan konsekuensi yang sering terlewat: bot memberikan komentar sebagai pengguna manusia yang membuat token tersebut. Buat token di bawah akun yang tidak keberatan namanya dikutip dalam setiap balasan triase.

Atur cakupannya sesempit yang ditentukan dalam panduan penyiapan. Pilih Only select repositories dan pilih satu repositori. Berikan Issues: Read and write serta Pull requests: Read and write. Itu sudah cukup untuk membaca mention dan membalas dalam thread.

Perhatikan yang tidak disertakan: akses tulis ke kode. OpenTag tidak melakukan push branch kecuali preparePullRequestBranch ditetapkan ke true. Tersedia juga githubApplyToken terpisah agar token yang menulis kode tidak sama dengan token yang menulis komentar. Pisahkan keduanya, dan jangan aktifkan token tulis sampai alur baca dan komentar telah berjalan selama beberapa minggu.

Konfigurasi yang harus dihindari adalah token dengan Contents: Read and write pada All repositories. Siapa pun yang dapat memberikan komentar pada salah satu repositori tersebut kini dapat mengarahkan agent yang memiliki hak commit, sementara audit trail mencatat bahwa pemilik tokenlah yang melakukannya. Perluas cakupan satu repositori setiap kali, setelah agent membuktikan kelayakannya.

Di Slack, cakupan bot adalah app_mentions:read, chat:write, reactions:write, dan channels:history. Private channel juga memerlukan groups:history serta subscription ke event message.groups. Socket Mode memerlukan app-level token dengan connections:write, yaitu token yang diawali xapp-. channels:history membaca riwayat pesan di public channel tempat bot telah ditambahkan. Karena itu, tambahkan bot ke channel yang membutuhkannya, bukan ke semua channel.

Merutekkan satu masalah dari awal hingga akhir

Webhook menjadi langkah pertama. Di repository, buka Settings, lalu Webhooks, kemudian Add webhook. URL payload adalah https://opentag.example.com/github/webhooks, jenis kontennya adalah application/json, dan secret adalah secret yang dibuat oleh setup. Berlangganan Issue comments dan Pull request review comments, tanpa yang lain.

GitHub mengirimkan delivery ping segera setelah Anda menyimpan konfigurasi. Buka Recent Deliveries dan periksa apakah request benar-benar mencapai server. Status 502 di sana berarti nginx tidak dapat menjangkau listener. Ini adalah masalah lokal, bukan masalah GitHub.

Sekarang gunakan webhook tersebut. Buka issue yang menjelaskan bug, lalu tambahkan komentar:

@opentag triage this. Reproduce the report against the current main branch, then reply with the file and function most likely responsible, plus the test you would write first.

Urutan yang seharusnya terjadi sebagai berikut. Recent Deliveries mencatat delivery issue_comment dengan respons 2xx. Dispatcher mencatat sebuah run. Runner mengambil run tersebut dan mulai mengirim heartbeat. Executor membuka checkout dan menjalankan tugas. Jawaban muncul sebagai komentar dalam thread issue yang sama. sudo -iu opentag opentag status menampilkan run saat masih berlangsung, sehingga Anda dapat memantaunya tanpa menebak-nebak.

Atur approvalMode ke ask sebelum run nyata pertama. Dalam mode ask, run berhenti sementara dan menunggu persetujuan seseorang sebelum melakukan tindakan yang mengubah state. Mode auto dan autonomous juga tersedia. Keduanya dapat digunakan nanti pada repository yang transkripnya sudah Anda baca selama satu bulan.

Di sisi Slack, run yang sama dimulai dengan /bind owner/repo di channel, lalu sebuah mention. Bot juga menjawab /help, /status, /doctor, /stop, dan /unbind confirm. Batasi pihak yang dapat mengubah binding dengan OPENTAG_SLACK_BINDING_ADMIN_USER_IDS, yaitu daftar Slack user ID yang dipisahkan koma, karena binding memetakan channel publik ke checkout pada server Anda.

Triage adalah rute awal yang baik karena hanya membaca dan tidak menulis, serta jawabannya mudah dievaluasi. Review adalah langkah berikutnya, ketika agent memberikan komentar pada diff, bukan pada issue: agent review pull request yang di-host sendiri menggunakan arsitektur yang sama dan diarahkan ke pull request. Jika Anda ingin agent mengakses sistem milik Anda saat bekerja, gunakan MCP server pada VPS. Pencarian web adalah kemampuan lain yang sering diminta dalam triage, dan menghubungkan agent ke instance SearXNG milik Anda sendiri membuat pencarian tersebut tetap berlangsung pada perangkat keras yang Anda kelola, dengan konsekuensi adanya satu jalur tambahan yang memungkinkan teks dari pihak luar mencapai agent.

Apa yang terjadi ketika agent salah di depan semua orang?

Agent akan salah. Pertanyaannya adalah seberapa besar dampaknya.

Balasan yang salah pada issue publik menjadi komentar dengan nama yang dikenali tim Anda, dan GitHub mengirimkannya melalui email kepada semua orang yang berlangganan segera setelah komentar tersebut diposting. Menghapus komentar tidak membatalkan email yang sudah terkirim. Hal yang sama berlaku untuk notifikasi Slack. Rencanakan sistem untuk menghadapi jawaban yang salah di ruang publik, bukan hanya jawaban yang benar secara internal.

Empat pilihan membatasi dampaknya. Pilihan ini lebih penting daripada prompt apa pun yang Anda tulis.

  • Jalankan dalam mode ask, sehingga agent mengusulkan, seseorang menyetujui, dan rencana yang salah hanya memerlukan satu klik untuk dihentikan.
  • Biarkan preparePullRequestBranch tetap menggunakan nilai default false, sehingga dampak terburuk dari eksekusi yang buruk adalah komentar yang salah, bukan branch yang salah.
  • Awali dengan mengikat satu repository dan satu channel. Runner menolak setiap eksekusi yang target project-nya berada di luar allowlist lokal, sehingga repository yang tidak terikat tidak dapat memanggil agent ke dalamnya.
  • Pisahkan token untuk memberikan komentar dari token untuk apply, sehingga pencabutan akses tulis tidak menghentikan proses triage.

Slack memiliki perintah /stop untuk menghentikan run yang bergerak ke arah yang salah. Setiap run juga meninggalkan catatan audit yang memuat mention yang memulainya dan tindakan agent. Catatan inilah yang Anda baca setelahnya untuk mengetahui bagian yang mengalami kesalahan.

Aspek sosial sama pentingnya dengan konfigurasi. Tempatkan bot di satu channel yang memang digunakan untuk bot dan tempat orang memahami bahwa bot dapat melakukan kesalahan. Jawaban salah yang disampaikan dengan yakin di channel berisi empat puluh orang yang mengira jawaban tersebut telah ditinjau manusia dapat menimbulkan dampak lebih besar daripada waktu yang dihemat oleh triage. Tuliskan pada deskripsi channel siapa yang bertanggung jawab atas bot dan siapa yang memeriksa output-nya.

Pencadangan, pemutakhiran, dan pin versi

Dua path menyimpan semuanya: /home/opentag/.config/opentag/config.json dan /home/opentag/.local/state/opentag. Path pertama berisi kredensial Anda, sedangkan path kedua berisi riwayat eksekusi dan file database. Cadangkan keduanya dengan mode 600, lalu simpan di luar server. Jika keduanya hilang, Anda harus membuat ulang token dan binding, bukan membangun ulang server.

Pemutakhiran berarti menaikkan versi dan melakukan restart.

sudo npm install -g @opentag/cli@0.9.0
sudo -iu opentag opentag service stop
sudo -iu opentag opentag service start
sudo -iu opentag opentag doctor

Tetapkan versi secara tetap, bukan dengan mengikuti @latest. Perangkat lunak ini menjalankan agen coding pada repositori Anda dengan token aktif. Karena itu, rilis yang dipublikasikan tanpa peninjauan pada malam hari menjadi perubahan yang tidak ditinjau terhadap repositori tersebut. Kebijakan keamanan tidak melakukan backport. Perbaikan hanya masuk ke rilis terbaru. Karena itu, pin versi berarti Anda membaca changelog lalu melakukan pemutakhiran secara sengaja. Ini bukan berarti tetap menggunakan v0.9.0 selamanya. Riwayat hingga July 2026 menunjukkan beberapa rilis setiap bulan. Itu menjadi alasan yang baik untuk membaca catatan rilis sebelum setiap pemutakhiran.

FAQ

Apakah saya memerlukan VPS untuk menjalankan OpenTag, atau laptop sudah cukup?

Laptop sudah cukup untuk Slack saja karena Socket Mode membuka WebSocket keluar dan tidak memerlukan port masuk. GitHub berbeda. Webhook repositori dikirim melalui HTTP masuk ke URL yang Anda daftarkan satu kali. Karena itu, alamat tersebut harus tetap sama dan harus merespons saat Anda sedang tidur. Host tunnel dari akun gratis berubah setiap kali restart, sedangkan GitHub terus mengirim ke alamat lama. Hal ini terlihat sebagai entri yang gagal pada tab Recent Deliveries repositori dan sebagai tidak adanya respons di thread. VPS dengan nama DNS tetap dan sertifikat mengatasi kedua masalah tersebut.

Izin GitHub apa yang diperlukan OpenTag?

Gunakan personal access token fine-grained yang dibatasi ke Only select repositories, dengan Issues: Read and write serta Pull requests: Read and write. Izin tersebut mencakup pembacaan mention dan pengiriman balasan di thread. Akses write ke code tidak diperlukan, kecuali Anda menetapkan preparePullRequestBranch ke true agar OpenTag melakukan push branch. Tersedia githubApplyToken terpisah agar token untuk menulis code tidak tercampur dengan token untuk memberikan komentar. Hindari token untuk semua repositori dengan izin contents write karena siapa pun yang dapat memberikan komentar pada salah satu repositori tersebut kemudian dapat mengarahkan agent yang memiliki kemampuan untuk melakukan commit.

Bagaimana cara menghentikan run yang berjalan tidak semestinya?

Slack memiliki command /stop khusus untuk keperluan ini. Pada server, opentag status menampilkan proses yang sedang berjalan, sedangkan opentag service stop menghentikan daemon. Perintah tersebut mengakhiri seluruh pipeline, bukan hanya satu run. Agar Anda tidak perlu menggunakan keduanya, tetapkan approvalMode ke ask sehingga run berhenti sementara untuk menunggu persetujuan sebelum mengubah apa pun. Biarkan preparePullRequestBranch tetap false agar run yang bermasalah menghasilkan komentar, bukan branch.

Mengapa webhook saya mengembalikan 502 sementara thread tetap tidak merespons?

502 berasal dari nginx, bukan dari OpenTag. Artinya, proxy tidak dapat menjangkau listener. /var/log/nginx/error.log akan menampilkan connect() failed (111: Connection refused) while connecting to upstream. Listener mungkin berhenti, atau berjalan pada port yang berbeda dari yang tercantum pada baris proxy_pass. Jalankan sudo ss -tlnp dan pastikan ada proses yang listening pada 127.0.0.1:3050 untuk GitHub dan 127.0.0.1:3040 untuk Slack. Selanjutnya, jalankan opentag doctor untuk memeriksa binding dan executor.

#opentag#ai-agents#slack#github#webhooks#self-hosting