SSD Nodes Learn 🎉 VPS dari $5.50/bln
Panduan Matt ConnorOleh Matt Connor

Cara Self-host OpenAnalytics pada VPS Linux

Ketahui keperluan sebenar sebelum memasang OpenAnalytics: 4 GB RAM, 25 GB ruang cakera, Docker, dan empat rekod DNS. Artikel ini membincangkan penggunaan ClickHouse dan Valkey.

Tapak pemasangan, sebelum langkah pertama

Untuk mengehos sendiri OpenAnalytics, anda memerlukan VPS Linux dengan kira-kira 4 GB RAM, 25 GB ruang cakera kosong, Docker dengan pemalam Compose, dan empat rekod DNS yang sudah menghala ke pelayan tersebut. Ini adalah kenyataan sebenar, dan ia perlu diletakkan sebelum arahan pertama dan bukannya selepasnya.

Stak ini terdiri daripada enam servis aplikasi dan tiga stor data. Postgres menyimpan satah kawalan: akaun, tapak, kunci API dan pautan perkongsian. ClickHouse menyimpan peristiwa mentah dan data terkumpul yang dibaca oleh papan pemuka. Valkey dijalankan dua kali, sekali sebagai baris gilir peristiwa yang tahan lama dan sekali lagi sebagai cache yang sistem boleh korbankan, kerana kedua-dua tugas ini memerlukan polisi pengusiran (eviction policies) yang bertentangan. Hanya satu proses, iaitu gerbang pertanyaan (query gateway), dibenarkan membaca ClickHouse, dan ia mengesahkan tandatangan Ed25519 pada setiap sampul pertanyaan sebelum melaksanakannya.

Jika apa yang anda mahukan ialah satu binari dan satu fail konfigurasi, ini bukan pilihannya. GoatCounter ialah pilihan binari tunggal dalam kategori ini: satu boleh laku Go, SQLite secara lalai, tanpa pangkalan data luaran langsung. Stak yang lebih berat ini memberikan anda corong (funnels), web vitals, atribusi hasil daripada akaun Stripe anda sendiri, dan pelayan MCP (model context protocol). Memilih antara alat analitik yang dihoskan sendiri ialah catatan yang menimbang pertukaran tersebut. Panduan ini mengandaikan anda telah membuat keputusan.

Halakan empat rekod DNS ke pelayan terlebih dahulu

Empat subdomain mesti diselesaikan (resolve) kepada alamat IP awam pelayan sebelum anda memulakan sebarang langkah, kerana Caddy akan meminta sijil Let's Encrypt pada pelancaran pertama dan cabaran tersebut akan gagal jika nama domain belum diselesaikan.

  • app.example.com menyediakan papan pemuka (dashboard).
  • api.example.com menyediakan API dan panggil balik (callback) OAuth.
  • c.example.com menyediakan pengumpul (collector) dan skrip penjejak.
  • rt.example.com menyediakan strim masa nyata.

Gunakan empat rekod A, atau satu rekod A dan tiga CNAME yang menghala kepadanya. Sahkan dengan dig +short app.example.com sebelum anda meneruskan. Nama yang anda tambah sebentar tadi mungkin masih disimpan dalam cache sebagai NXDOMAIN oleh mana-mana resolver yang digunakan oleh Let's Encrypt, jadi jika percubaan sijil pertama gagal, anda perlu menunggu dan menyemak log Caddy. Menjalankan semula pemasangan tidak akan mempercepatkan penyebaran (propagation) DNS.

Cara mengehos sendiri OpenAnalytics dengan Docker Compose

Semak keluar (checkout) release yang bertanda. Cawangan lalai (default branch) ialah tempat pembangunan berlaku, dan tag release adalah perkara yang sebenarnya dipadankan oleh imej yang diterbitkan. Perintah di bawah mengandaikan Docker dan pemalam Compose sudah dipasang, yang diliputi dalam menjalankan servis Docker Compose pada VPS.

git clone https://github.com/OpenLabs-so/openanalytics
cd openanalytics
git checkout "$(git tag -l 'v*' --sort=-v:refname | sed '/-/d' | head -1)"
cd infra/selfhost
./generate-secrets.sh --domain example.com --email you@example.com --with-geoip
docker compose pull && docker compose up -d

sed '/-/d' dalam baris checkout menggugurkan tag pra-keluaran, supaya anda mendarat pada versi stabil terkini dan bukannya calon keluaran (release candidate). --with-geoip mengambil pangkalan data bandar DB-IP semasa penjanaan. Langkau langkah ini dan setiap acara akan membawa negara null, jadi paparan geografi tidak menunjukkan apa-apa langsung. Anda boleh menambahnya kemudian dengan menjalankan infra/selfhost/geoip/fetch-dbip.sh, menetapkan GEOIP_DB_PATH=/geoip/dbip-city-lite.mmdb dalam env/collector.env, kemudian mencipta semula pengumpul (collector) dengan docker compose up -d --force-recreate collector. Pangkalan data itu disegarkan setiap bulan, jadi ulangi pengambilan tersebut setiap bulan atau data bandar anda akan menjadi tidak tepat.

Sandarkan rahsia yang dijana sebelum meneruskan langkah seterusnya

Penjana tersebut menulis tiga perkara. .env menyimpan nama domain dan rujukan imej. env/*.env menyimpan satu fail rahsia bagi setiap servis. docker-compose.override.yml menyimpan tiga pasangan kunci Ed25519 sebagai skalar blok YAML, kerana PEM berbilang baris tidak boleh diletakkan di dalam fail env. Kesemuanya diabaikan oleh git, dan tiada satu pun daripadanya boleh dijana semula kepada nilai yang sama.

Salin fail-fail tersebut keluar dari mesin sekarang. Setiap kehilangan membawa kesan yang khusus:

  • Kehilangan kata laluan storan menyebabkan anda terkunci daripada Postgres dan ClickHouse, yang hanya boleh ditetapkan semula dari dalam kontena.
  • Kehilangan OA_CREDENTIAL_KEYRING menyebabkan setiap kelayakan pihak ketiga yang disimpan tidak dapat dipulihkan, jadi sesiapa yang telah menyambungkan akaun Stripe perlu menyambungkannya semula.
  • Kehilangan ANONYMOUS_IDENTITY_SECRET menyebabkan identiti pelawat ditetapkan semula: semua pelawat semalam dikira sebagai pelawat baharu, dan gangguan ini akan kelihatan pada carta.
  • Kehilangan AUTH_SECRET menyebabkan setiap sesi dibatalkan, jadi semua orang perlu log masuk semula.
  • Kehilangan kunci peribadi penandatangan (signing private key) bermakna anda perlu menukar pasangan kunci tersebut. Tiada data yang hilang.

Dua rahsia mesti mempunyai bait yang sama (byte-identical) merentasi dua fail setiap satu. ANONYMOUS_IDENTITY_SECRET muncul dalam collector.env dan worker.env, kerana pengumpul (collector) mengira hash pelawat dan pekerja (worker) menulisnya. OA_CREDENTIAL_KEYRING muncul dalam api.env dan worker.env. Segala rahsia lain dihadkan kepada hanya satu servis secara sengaja, dan servis yang menerima rahsia yang tidak sepatutnya dipegang akan berhenti (exit) dan bukannya bermula.

Jalankan stack dan buat semakan

grep OA_IMAGE .env
docker compose pull
docker compose up -d
docker compose logs -f migrate
docker compose ps

migrate menggunakan skema Postgres dan ClickHouse kemudian berhenti, jadi bekas migrate yang berhenti adalah keadaan akhir yang betul. tracker-build menyusun oa.js ke dalam volum yang dihidangkan oleh Caddy dan turut berhenti. Semua servis lain sepatutnya memaparkan healthy dalam docker compose ps. Servis yang memulakan semula dalam gelung hampir pasti gagal dalam pengesahan persekitaran, dan log mencetak setiap masalah dalam satu senarai dan bukannya satu demi satu setiap kali dimulakan semula. Dua punca biasa ialah pemboleh ubah yang dibiarkan kosong, yang ditolak dan bukannya dianggap tidak ditetapkan, serta rahsia yang diletakkan dalam fail servis yang salah.

Pada arm64, atau daripada cawangan (branch), tiada imej yang diterbitkan dan anda perlu membina secara setempat dengan docker compose up -d --build. Hos 4 GB akan kehabisan memori semasa proses binaan tersebut. Tambah swap terlebih dahulu, yang hanya diperlukan semasa membina:

fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

Proses membina mengambil masa kira-kira sepuluh minit. Proses menarik (pulling) mengambil masa beberapa minit, itulah sebabnya imej keluaran disediakan.

Tuntut akaun pertama dengan segera

Buka https://app.example.com. Peluncuran yang belum pernah dilog masuk tidak akan memaparkan borang log masuk: ia menawarkan untuk mencipta akaun pertama. Akaun tersebut kekal sebagai akaun berkeistimewaan dan merupakan satu-satunya akaun yang boleh melihat skrin tetapan peluncuran. Sebaik sahaja akaun itu wujud, laluan tersebut akan menjawab 409, supaya tiada sesiapa boleh masuk selepas anda. Lakukan perkara ini sebaik sahaja stack berada dalam keadaan sihat, bukan pada minggu berikutnya.

Memasang penjejak

Tambah tapak dalam papan pemuka dan ia akan memberikan anda tag tersebut. Bentuknya adalah tetap:

<script
  async
  src="https://c.example.com/oa.js"
  data-key="YOUR_TRACKING_KEY"
  data-collector="https://c.example.com"
></script>

Letakkannya di bahagian head halaman. Kunci penjejakan adalah awam mengikut reka bentuk, jadi ia sepatutnya berada dalam HTML anda di mana sesiapa sahaja boleh membacanya. Skrip tersebut memasang window.oa, dan panggilan seperti oa("track", ...) akan diletakkan dalam baris gilir oleh stub dan dihantar sebaik sahaja fail dimuatkan, jadi peristiwa tersuai yang dicetuskan lebih awal tidak akan digugurkan. Jika sesuatu yang lain pada halaman tersebut sudah memiliki window.oa, penjejak akan dipasang sebagai window.openanalytics sebaliknya.

Kemudian periksa keseluruhan laluan dari hujung ke hujung:

curl -s https://c.example.com/oa.js -o /dev/null -w '%{http_code} %{size_download}\n'
curl -s https://api.example.com/health | head -c 200
docker compose logs --tail=50 worker | grep -i batch

Yang pertama sepatutnya mencetak 200 dan beberapa kilobait. Muatkan halaman pada tapak anda, kemudian cari baris kelompok dalam log pekerja dalam masa beberapa saat. Pengumpul akan menjawab 202 sebaik sahaja ia menerima sesuatu peristiwa, dan 202 bermaksud dalam baris gilir, bukan disimpan. Pekerja adalah komponen yang memindahkan peristiwa ke dalam ClickHouse. Peristiwa yang diterima tetapi tidak muncul dalam papan pemuka bermaksud pekerja disekat, dan kedalaman baris gilir Valkey yang terus meningkat mengesahkan perkara ini. Punca biasa adalah kelayakan ClickHouse yang salah dalam worker.env, atau pemberian kebenaran (grant) yang hilang pada jadual yang baru sahaja ditambah oleh migrasi.

Pastikan pengumpul kekal awam dan papan pemuka di sebalik pengesahan

Caddy disertakan di dalam fail compose dan memperoleh sijil untuk kesemua empat nama secara automatik, jadi laluan lalai tidak memerlukan sebarang kerja proksi daripada anda. Jika pelayan sudah menjalankan proksi terbalik nginx, gunakan infra/selfhost/nginx.conf.example yang dibekalkan untuk bahagian hadapan tindanan tersebut, dan pastikan pengendalian pengepala (header) dikekalkan:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header CF-Connecting-IP "";
proxy_set_header True-Client-IP "";
proxy_set_header Fly-Client-IP "";

Pengumpul memperoleh hash pelawat harian daripada IP pelanggan, jadi ia mesti mengambil alamat tersebut daripada sambungan dan bukan daripada pengepala. Meluluskan CF-Connecting-IP daripada hop yang tidak dipercayai membolehkan mana-mana pemanggil menuntut sebarang alamat, yang akan merosakkan geolokasi dan meningkatkan kiraan pelawat secara serentak.

Akses dibahagikan dengan jelas mengikut nama hos. c. dan rt. mesti boleh dicapai oleh setiap pelawat bagi setiap tapak yang anda ukur, jadi jangan sekali-kali meletakkan pengesahan asas (basic auth) atau senarai putih IP di hadapan kedua-duanya. app. dan api. hanya perlu boleh dicapai oleh pengguna yang log masuk. Pengesahan aplikasi itu sendiri yang melindungi papan pemuka: log masuk kata laluan diaktifkan secara lalai melalui AUTH_PASSWORD_SIGNIN=enabled dalam env/api.env, dan butang Google atau GitHub hanya muncul apabila kedua-dua ID pelanggan dan rahsia pelanggan wujud untuk penyedia tersebut. Pautan ajaib (magic links) memerlukan pengangkutan mel, dan tanpanya API hanya menulis penghantaran ke peti keluar, jadi tiada apa-apa yang dihantar dan tiada ralat berlaku.

Satu tetapan menentukan sama ada papan pemuka berfungsi atau tidak. AUTH_TRUSTED_ORIGINS dalam env/api.env mesti sepadan dengan asal papan pemuka dengan tepat. Jika salah atau tiada, API tidak mengeluarkan pengepala CORS (cross-origin resource sharing), pelayar menolak setiap panggilan, dan anda mendapat papan pemuka yang memaparkan reka letak tetapi tidak menunjukkan data, sedangkan docker compose ps melaporkan semuanya dalam keadaan baik.

Semasa anda berada dalam konfigurasi proksi, uruskan trafik automatik. Perangkak (crawler) mencapai pengumpul seperti trafik lain, dan paparan halaman mereka akan masuk ke dalam ClickHouse serta angka anda. Menyekat perangkak AI di pelayan menghalang sebahagian daripada trafik tersebut daripada masuk ke pangkalan data sebelum ia menjejaskan ketepatan dan penggunaan cakera anda.

Apakah maksud tanpa kuki di sini, dan apakah kosnya

Tiada kuki digunakan. Identiti pelawat ialah hash yang disaltkan, salt tersebut bertukar setiap hari, dan alamat IP mentah tidak pernah disimpan. Geolokasi diselesaikan secara setempat menggunakan fail DB-IP pada cakera anda sendiri, jadi tiada carian tentang pelawat yang keluar daripada hos.

Kelebihannya ialah ketiadaan pengecam yang dikekalkan pada peranti pelawat, iaitu perkara khusus yang menarik penjejak ke dalam peraturan persetujuan ePrivacy EU. Persediaan yang hanya menggunakan data agregat seperti ini biasanya dijalankan tanpa sepanduk persetujuan atas sebab tersebut. GDPR masih mengawal apa sahaja yang anda simpan dan untuk berapa lama, dan peguam anda sendiri yang menentukan kes anda, bukan fail README.

Kosnya ialah identiti merentas hari. Pertukaran salt bermakna seseorang yang melawat pada hari Isnin dan sekali lagi pada hari Rabu akan dikira sebagai dua pelawat, mengikut reka bentuk dan tiada jalan penyelesaian. Kiraan unik harian adalah tepat. Kiraan unik mingguan dan bulanan dibina daripada kiraan harian dan akan melebihkan jangkauan, jadi sebarang angka "pelawat kembali" bagi tempoh yang panjang tidak mengukur apa yang dilabelkan. Sesi dan perjalanan adalah boleh dipercayai dalam satu hari. Pertukaran ANONYMOUS_IDENTITY_SECRET mempunyai kesan yang sama seperti sempadan hari, jadi anggap pertukaran itu sebagai perubahan data dan bukannya sebagai rutin kebersihan.

Pengumpul menghormati Do Not Track dan Global Privacy Control, iaitu isyarat pelayar yang memberitahu tapak supaya tidak menjual atau berkongsi data peribadi. Tag skrip membawa suisnya sendiri untuk tujuan yang sama: data-respect-gpc, data-respect-dnt, dan data-require-consent, yang menahan semua pengumpulan sehingga persetujuan diberikan dan mengingati jawapan dalam localStorage di bawah kunci oa.consent. Menetapkan data-storage="none" mematikan storan pelayar sepenuhnya.

Mengapa cakera penuh selepas enam bulan

Ini adalah punca utama kegagalan pelayan analitik yang dihoskan sendiri, dan biasanya ia bukan disebabkan oleh data acara.

Mulakan dengan imej. Satu keluaran menerbitkan sepuluh imej, dan saiznya mencecah kira-kira 13 GB pada cakera. Proses naik taraf akan menarik generasi baharu sebelum membuang yang lama, jadi untuk seketika anda menyimpan dua generasi. Ini merupakan sebahagian besar daripada keperluan 25 GB, sebelum satu pun paparan halaman diterima.

Kemudian, syot kilas (snapshots). snapshot.sh menghentikan tindanan (stack), mengarkibkan kedua-dua volum data berserta setiap rahsia, dan memulakan semula. Salinan sejuk (cold copies) adalah satu-satunya jenis yang selamat di sini, kerana ClickHouse menggabungkan bahagian di latar belakang dan salinan yang diambil semasa proses penggabungan tidak akan konsisten. upgrade.sh mengambil satu salinan secara automatik sebelum setiap naik taraf, jadi arkib akan terkumpul pada cakera yang sama sehingga anda mengehadkannya.

./snapshot.sh create --label before-something-risky
./snapshot.sh list
./snapshot.sh --keep 3

Pada hos yang hampir mencapai had, tuntut semula generasi sebelumnya sebelum melakukan naik taraf. Ini selamat dilakukan semasa tindanan sedang berjalan, kerana imej yang menyokong kontena yang sedang berjalan masih dirujuk:

docker image prune -a -f

Seterusnya, data acara itu sendiri. ClickHouse memampatkan data kolumnar dengan sangat padat, jadi volum data acara mentah berkembang lebih perlahan daripada jangkaan kebanyakan orang, dan jadual ringkasan (rollup tables) yang dibaca oleh papan pemuka adalah kecil berbanding jadual mentah. Ukur dan jangan sekadar meneka:

docker system df -v
docker compose exec clickhouse df -h /var/lib/clickhouse

Untuk angka bagi setiap jadual, jalankan arahan ini dengan kelayakan ClickHouse yang ditulis oleh penjana di bawah infra/selfhost/env/:

SELECT table, formatReadableSize(sum(bytes_on_disk)) AS size, sum(rows) AS row_count
FROM system.parts
WHERE active
GROUP BY table
ORDER BY sum(bytes_on_disk) DESC;

Ambil bacaan tersebut pada minggu pertama dan sekali lagi pada minggu keempat. Dua titik data memberikan anda kadar pertumbuhan, dan kadar pertumbuhan memberitahu anda bila volum perlu diubah saiznya. Panduan hos sendiri tidak mendokumentasikan sebarang tetapan pengekalan atau tempoh hayat (time-to-live) untuk acara mentah setakat Ogos 2026, jadi tetapkan saiz cakera berdasarkan kadar yang anda ukur dan jangan menganggap baris lama akan luput dengan sendirinya.

Satu perangkap pemadaman perlu diketahui sebelum ia menjejaskan anda. Memadamkan tapak atau akaun akan meletakkan tugasan dalam baris gilir untuk pekerja (worker), dan pekerja tersebut memerlukan CLICKHOUSE_MAINTENANCE_USER dan CLICKHOUSE_MAINTENANCE_PASSWORD ditetapkan, dengan pengguna oa_maintenance yang sepadan wujud dalam ClickHouse. Tanpanya, pemadaman akan berada dalam baris gilir selama-lamanya. Tapak tersebut hilang daripada papan pemuka tetapi setiap baris data kekal pada cakera, jadi anda mendapat gambaran seolah-olah pembersihan telah berlaku sedangkan tiada ruang yang dikosongkan.

Naik taraf, dan tiga kos yang terlibat

git fetch --tags
git checkout "$(git tag -l 'v*' --sort=-v:refname | sed '/-/d' | head -1)"
cd infra/selfhost
./upgrade.sh

upgrade.sh memaparkan tiga kos sebelum ia bertindak. Downtime adalah nyata: peristiwa yang dicuba semasa pengumpul (collector) tidak berfungsi akan hilang, kerana penjejak (tracker) tidak melakukan percubaan semula. Rollback menyebabkan kehilangan data, kerana rollback.sh --to backups/<snapshot> menggantikan kedua-dua storan secara keseluruhan dan membuang setiap baris yang ditulis selepas snapshot tersebut diambil. Cakera adalah kos ketiga, iaitu timbunan snapshot yang diterangkan di atas.

Dua peraturan mulakan semula (restart) mudah disalah anggap. Hidupkan query gateway sebelum API, kerana API yang lebih baharu menghantar medan pertanyaan yang ditolak oleh gateway yang lebih lama. Dan ClickHouse memerlukan penciptaan semula (recreate) dan bukannya mulakan semula, kerana docker compose restart menggunakan semula persekitaran asal kontena dan mengabaikan suntingan anda secara senyap:

docker compose up -d --force-recreate clickhouse

Papan pemuka (dashboard) mempunyai bentuk perangkap yang sama. Tiga asal (origin) NEXT_PUBLIC_* dalam env/web.env dikompilasikan ke dalam bundle pelayar dan digantikan apabila kontena bermula, jadi papan pemuka yang memanggil hostname yang salah diperbetulkan dengan docker compose up -d --force-recreate web dan bukannya restart. Log kontena web mencetak asal yang digunakan semasa ia bermula, yang merupakan cara terpantas untuk mengesahkan pembetulan telah berjaya.

Jika ClickHouse enggan bermula selepas suntingan konfigurasi, baca baris pertama lognya. Baris yang bermula dengan oa-entrypoint: adalah titik masuk (entrypoint) yang menolak nilai yang anda tetapkan. Sebarang perkara lain biasanya bermaksud fail konfigurasi adalah XML yang tidak sah, dan punca paling biasa ialah tanda sempang berganda di dalam komen XML, yang tidak dibenarkan di situ.

AGPL-3.0, dan nama

Kod ini dilesenkan di bawah AGPL-3.0. Menjalankan kod ini tanpa pengubahsuaian untuk laman web anda sendiri tidak mewujudkan sebarang obligasi penerbitan. Obligasi bermula apabila anda mengubah suai kod tersebut dan menjalankan versi yang diubah suai itu sebagai servis rangkaian: lesen tersebut kemudiannya mewajibkan anda untuk menawarkan kod sumber yang telah diubah suai kepada pengguna servis tersebut. Ini merangkumi pemberian papan pemuka kepada pelanggan pada instans anda, dan ia merangkumi penggabungan kod tersebut ke dalam sesuatu yang anda jual. Menyimpan perubahan anda dalam fork awam sudah memadai tanpa sebarang proses lanjut.

Jenama adalah berasingan daripada kod. Nama "OpenAnalytics" dan domain yang dihoskan oleh projek tersebut mengenal pasti instans yang dikendalikan oleh penulisnya, dan ia bukan sebahagian daripada pemberian lesen. Penempatan anda menjalankan perisian tersebut tanpa membawa jenama berkenaan, jadi berikan nama tersendiri kepada servis tersebut sebelum anda menawarkannya kepada pelanggan berbayar.

FAQ

Bolehkah saya menjalankan OpenAnalytics pada VPS 1 GB?

Tidak. Projek ini memerlukan kira-kira 4 GB RAM dan 25 GB ruang cakera kosong, kerana satu deployment menjalankan enam servis aplikasi di samping Postgres, ClickHouse dan dua instance Valkey. ClickHouse sahaja bukanlah proses yang ringan. Pada pelayan 1 GB, container akan bermula tetapi kernel out-of-memory killer akan menamatkan salah satu daripadanya, biasanya ClickHouse. Jika pelan 1 GB adalah kekangan mutlak, gunakan alat binari tunggal seperti GoatCounter, yang berjalan pada SQLite tanpa pangkalan data luaran.

Adakah saya memerlukan sepanduk kuki dengan OpenAnalytics?

Itu adalah soalan untuk peguam anda, dan fakta teknikal menyebelahi anda. Tiada kuki digunakan, identiti pelawat adalah hash bersalt yang bertukar setiap hari, dan alamat IP mentah tidak pernah disimpan, jadi tiada data kekal ditulis untuk mengenal pasti pelawat. GDPR masih mengawal perkara yang anda simpan dan tempoh anda menyimpannya. Jika anda mahu pengumpulan data dilakukan secara eksplisit, tetapkan data-require-consent pada tag skrip: penjejak tidak akan mengumpul apa-apa sehingga kebenaran diberikan dan menyimpan jawapan tersebut dalam localStorage di bawah oa.consent.

Mengapa acara mengembalikan 202 tetapi tidak pernah muncul dalam papan pemuka?

202 bermaksud pengumpul telah menerima dan meletakkan acara dalam baris gilir, bukan bermaksud ia telah menyimpannya. Pekerja (worker) akan mengosongkan baris gilir tersebut ke dalam ClickHouse, jadi papan pemuka yang kosong dengan permintaan yang berjaya menunjukkan masalah pada pekerja. Baca docker compose logs --tail=50 worker dan pantau kedalaman baris gilir Valkey. Baris gilir yang terus berkembang bermakna pekerja disekat, dan punca biasa ialah kelayakan ClickHouse yang salah dalam worker.env atau kebenaran (grant) yang hilang pada jadual yang dicipta oleh migrasi terkini.

Mengapa papan pemuka kosong sedangkan setiap container sihat?

Semak AUTH_TRUSTED_ORIGINS dalam env/api.env terlebih dahulu. Ia mestilah sepadan dengan origin papan pemuka dengan tepat, dan jika tidak, API tidak akan mengeluarkan header CORS, jadi pelayar akan menolak setiap panggilan dan anda akan melihat susun atur yang berfungsi tanpa data. Perkara kedua untuk diperiksa ialah tiga nilai NEXT_PUBLIC_* dalam env/web.env, yang digantikan apabila container web bermula. Membetulkannya memerlukan docker compose up -d --force-recreate web, kerana restart biasa akan mengekalkan nilai lama.

Adakah AGPL-3.0 menghalang saya menawarkan ini kepada pelanggan?

Tidak, ia hanya mengenakan satu syarat. Jalankan kod tanpa diubah suai dan anda tidak berhutang apa-apa kepada sesiapa. Ubah suai kod tersebut dan jalankan versi yang diubah suai itu sebagai servis yang digunakan oleh orang lain, maka anda mesti menawarkan sumber yang diubah suai itu kepada pengguna tersebut, yang boleh dipenuhi melalui fork awam. Secara berasingan, nama "OpenAnalytics" tidak dilesenkan bersama kod tersebut, jadi apa-apa yang anda jual perlu menggunakan nama sendiri.