Deployment notifications
A good deployment is three events: “started”, “finished”, “smoke tests passed”. If any stage doesn’t appear within a reasonable time — something is stuck.
Simple deploy.sh with notifications
Section titled “Simple deploy.sh with notifications”#!/usr/bin/env bashset -euset -a; source /etc/notifly.env; set +aSVC="${1:?service name}"TAG="${2:?image tag}"HOST=$(hostname -s)START=$(date +%s)
notify() { local title="$1" msg="$2" prio="${3:-5}" curl -s --max-time 5 \ "$NOTIFLY_URL/message?token=$NOTIFLY_TOKEN" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg t "$title" --arg m "$msg" --argjson p "$prio" \ '{title:$t, message:$m, priority:$p}')" >/dev/null}
trap 'notify "❌ Deploy $SVC FAILED" "Tag: $TAG, host: $HOST, line: $LINENO" 9' ERR
notify "🚀 Deploy $SVC started" "Tag: $TAG → $HOST" 5
docker pull "myrepo/$SVC:$TAG"docker stop "$SVC" || truedocker rm "$SVC" || truedocker run -d --name "$SVC" --restart unless-stopped \ -p 8080:8080 "myrepo/$SVC:$TAG"
# smoke testsleep 5if curl -fs --max-time 5 http://localhost:8080/health >/dev/null; then DUR=$(( $(date +%s) - START )) notify "✅ Deploy $SVC OK" "Tag: $TAG, ${DUR}s, smoke OK" 4else notify "❌ Deploy $SVC: smoke-test failed" \ "Tag: $TAG, host: $HOST. /health не отвечает." 9 exit 1fiUsage:
./deploy.sh api 1.42.0Kubernetes
Section titled “Kubernetes”After kubectl rollout:
SVC="api"NS="prod"TAG="1.42.0"
kubectl -n "$NS" set image deployment/"$SVC" "$SVC=myrepo/$SVC:$TAG"
if kubectl -n "$NS" rollout status deployment/"$SVC" --timeout=5m; then notify "✅ k8s rollout $SVC=$TAG OK" "ns=$NS" 4else notify "❌ k8s rollout $SVC=$TAG FAILED" "ns=$NS — авто-rollback?" 9 kubectl -n "$NS" rollout undo deployment/"$SVC"fiVercel / Netlify / similar PaaS
Section titled “Vercel / Netlify / similar PaaS”They have webhooks for deploy events. The simplest way is to run a thin proxy endpoint on your side that accepts the webhook and sends it to Notifly:
export default async function (req, res) { const {state, name, deploy_url} = req.body || {}; const ok = state === 'ready' || state === 'success'; await fetch(`${process.env.NOTIFLY_URL}/message?token=${process.env.NOTIFLY_TOKEN}`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ title: (ok ? '✅' : '❌') + ` ${name}: ${state}`, message: `URL: ${deploy_url || '-'}`, priority: ok ? 4 : 9, }), }); res.status(204).end();}In Vercel/Netlify settings add the webhook URL pointing to this endpoint.
Smoke test after deployment
Section titled “Smoke test after deployment”Don’t trust only the healthcheck — add a “business check”:
RESP=$(curl -s -o /dev/null -w "%{http_code}" \ -H "X-Test: 1" \ https://api.example.com/v1/users/me)[ "$RESP" = "401" ] && notify "✅ Smoke OK ($RESP)" "/users/me требует auth — норм" 3 || \ notify "❌ Smoke FAIL ($RESP)" "/users/me ответил неожиданным кодом" 9Benefits
Section titled “Benefits”- You can see the flow. Start-to-end, duration of each stage.
- Smoke test is built into the notification — if you don’t get the ”✅”, something is stuck.
- A canary for PaaS: if there hasn’t been a single
readyin a week, something’s wrong with CI or with connectivity.
What to improve next
Section titled “What to improve next”- Send the diff of commits between deployments (
git log $OLD..$NEW --oneline). - Separate Notifly channels for prod / staging — different sounds and colors.
- On rollback — send the reason: “rollback because smoke /users/me returned 500”.