$ aoox

DocsInfrastruktur

Notifikasi

Mengirim kabar deploy, backup, job, container mati, disk menipis, dan sertifikat gagal ke Telegram, Slack, Discord, webhook, atau email.

Channel
Telegram · Slack · Discord · Webhook · Email
Event
7 toggle per channel
Lingkup
Platform-wide, owner/admin

Alur

  1. 01eventdeploy, backup, job, container mati, disk, sertifikat
  2. 02filterchannel dengan toggle event itu aktif
  3. 03formatpayload per platform: HTML, attachments, embeds, JSON, email
  4. 04kirimfetch dengan timeout 10 detik; gagal hanya dicatat di log

Channel yang didukung

TipeYang diisiCara mendapatkannya
TelegramBot token + Chat IDBuat bot lewat @BotFather (token 123456789:AAH…). Chat ID: kirim pesan ke bot lalu buka https://api.telegram.org/bot<token>/getUpdates; grup/channel biasanya diawali -100…. Bot harus ada di grup itu.
SlackWebhook URLSlack app → Incoming Webhooks → Add New Webhook to Workspace → pilih channel.
DiscordWebhook URLChannel → Edit → Integrations → Webhooks → New Webhook → Copy URL.
WebhookWebhook URL (https://…) + Secret opsionalEndpoint apa pun yang menerima POST JSON — n8n, Zapier, aplikasi sendiri. Secret mengaktifkan tanda tangan HMAC.
EmailHost SMTP, Port, Username, Password, Pengirim, PenerimaPenerima dipisah koma. Port 465 = TLS implisit, 587 = STARTTLS. Untuk Gmail pakai app password.

Menambahkan channel

  1. Settings → Notifikasi → Channel notifikasi baru (owner/admin)

    Isi Nama, pilih Tipe, isi field-nya, dan nyalakan toggle event yang diinginkan. Token/URL/ password disimpan terenkripsi dan tidak ditampilkan lagi — daftar channel hanya menunjukkan petunjuk target (mis. chat id, domain).

  2. Kirim tes

    Tombol tes mengirim pesan contoh ke channel itu. Error provider ditampilkan apa adanya — mis. Telegram chat not found (bot belum di grup / chat id salah) atau SMTP 535 Authentication failed.

  3. Picu event sungguhan

    Deploy sekali, atau jalankan job yang sengaja gagal (exit 1) untuk memastikan toggle bekerja.

Event

ToggleTerpicu saatIsi pesan
Deploy suksesDeployment aplikasi berakhir success (termasuk rollback).Aplikasi, project, image, durasi, tautan ke halaman aplikasi.
Deploy gagalDeployment aplikasi atau stack compose gagal.Sama + potongan pesan error (500 karakter).
Backup gagalBackup database/volume (manual atau terjadwal) gagal, termasuk gagal unggah ke S3.Database/aplikasi, pemicu (manual/terjadwal), error.
Job gagalScheduled job berstatus failed atau timeout.Nama job, perintah (200 karakter), 500 karakter terakhir output.
Container matiContainer aplikasi/database berhenti tak terduga — lihat aturan di Monitoring.Nama container, exit code, apakah sedang restart.
Disk hampir penuhPemakaian filesystem Docker melewati ambang (default 90 %, DISK_ALERT_PERCENT); diperiksa sekali sehari.Persentase terpakai, ambang, ruang tersisa.
Sertifikat gagalTraefik gagal menerbitkan/memperbarui sertifikat sebuah domain (diperiksa tiap 10 menit).Domain dan pesan error dari ACME.
  • Tautan ke halaman aplikasi disertakan bila WEB_ORIGIN terisi.
  • Kegagalan kirim ke satu channel hanya dicatat di log API dan tidak mempengaruhi channel lain maupun proses yang memicunya (deploy tidak pernah gagal karena notifikasi).
  • Container mati: maksimal 1 notifikasi per container per 10 menit.

Payload webhook generik

Channel Webhook mengirim POST dengan Content-Type: application/json. Field umum: title, level (success / failure / info), url, lalu field khusus event:

deployment.success / deployment.failure
{
  "title": "Deployment succeeded: shop",
  "level": "success",
  "url": "https://panel.example.com/applications/…",
  "event": "deployment.success",
  "deploymentId": "…",
  "kind": "deploy",
  "applicationId": "…",
  "application": "shop",
  "imageRef": "localhost:5000/toko/shop:a1b2c3d4e5f6",
  "error": null,
  "finishedAt": "2026-09-22T04:30:00.000Z"
}
container.down
{
  "title": "Container down: aoox-app-shop",
  "level": "failure",
  "event": "container.down",
  "container": "aoox-app-shop",
  "exitCode": 137,
  "restarting": true
}

Contoh penerima (Node.js)

app.post("/hooks/aoox", express.json(), (req, res) => {
  const { event, level, title } = req.body
  if (event === "deployment.failure") alertOnCall(title)
  res.sendStatus(204)
})

Header & tanda tangan

HeaderIsi
X-Aoox-EventNama event, mis. deployment.success.
X-Aoox-DeliveryID unik pengiriman — pakai untuk idempotensi.
X-Aoox-SignatureHanya bila Secret diisi: sha256=HMAC-SHA256(secret, raw body), skema yang sama dengan GitHub.
Verifikasi di penerima (Node.js)
const sig = req.get("X-Aoox-Signature")
const mine = "sha256=" + createHmac("sha256", SECRET).update(rawBody).digest("hex")
if (!sig || !timingSafeEqual(Buffer.from(sig), Buffer.from(mine))) return res.sendStatus(401)
Hitung HMAC atas byte body mentah, bukan hasilJSON.stringify ulang. Tanpa secret, amankan endpoint dengan URL yang sulit ditebak. Webhook keluar bisa mencapai alamat internal (SSRF by design) — itulah sebabnya hanya owner/admin yang boleh menambah channel.

Jebakan umum

GejalaPenyebab & solusi
Tes sukses tapi event tidak pernah masukToggle event belum dinyalakan di channel itu, atau event memang tidak terjadi (mis. container mati di server remote tidak terdeteksi).
Telegram: chat not found / bot was blockedBot belum ditambahkan ke grup, chat id tanpa prefix -100 untuk supergroup, atau pengguna belum /start.
Discord/Slack 4xxURL webhook kedaluwarsa/dihapus di provider. Buat ulang dan perbarui channel.
Email tidak sampai, tes suksesMasuk spam, atau Pengirim tidak diizinkan domain SMTP (SPF/DKIM). Pakai alamat pengirim milik domain SMTP.
TimeoutEndpoint lambat > 10 detik atau tidak terjangkau dari container API. Balas cepat (204) lalu proses async.
Belum tersedia
Notifikasi per project atau per aplikasi (channel berlaku platform-wide); event untuk stack compose selain deploy gagal; ringkasan harian.

Langkah berikutnya

Ada yang keliru? Edit halaman ini di GitLab ↗