Six months ago I was manually refreshing my client's website after every deployment, praying it stayed up.
That's when I decided to build WhistleBlower — a real-time uptime monitoring tool with alerts, status pages, and incident tracking.
Here's what I built and what I learned.
What WhistleBlower does
- 🔴 HTTP, TCP, PING, and DNS monitoring — not just websites
- 📧 Instant alerts via email, Slack, Discord, and SMS
- 📊 Public status pages — your users always know what's up
- 💓 Heartbeat monitoring — know when your cron jobs die silently
- 🔒 SSL certificate expiry alerts — never get caught with an expired cert
- 👥 Team & on-call scheduling for agencies
The tech stack
- Frontend: Next.js 14 + Tailwind CSS
- Backend: Node.js + Express + TypeScript
- Database: MySQL (Railway)
- Emails: Resend
- Payments: Razorpay
- Deploy: Vercel (frontend) + Railway (backend)
- Cron worker: GitHub Actions (free!)
The hardest part
ICMP ping is blocked on containerized environments like Railway and Docker. My PING monitors were silently failing in production while working fine locally.
The fix? A 3-strategy fallback:
- ICMP ping (works on bare metal / GitHub Actions)
- TCP connect to port 443, then 80
- DNS lookup as final fallback
async function checkPing(host: string): Promise<CheckResult> {
// Strategy 1: ICMP
const icmpResult = await tryICMP(host);
if (icmpResult.isUp) return icmpResult;
// Strategy 2: TCP fallback (containers block ICMP)
for (const port of [443, 80]) {
const tcp = await tryTCP(host, port);
if (tcp.isUp) return tcp;
}
// Strategy 3: DNS
return tryDNS(host);
}
What I'd do differently
- Start with a free tier plan from day one — I almost didn't add one
- Deploy earlier — I spent too long perfecting locally
- GitHub Actions as a cron runner is genuinely brilliant for side projects
Try it free
👉 whistle-blower-two.vercel.app
Free plan includes 5 monitors, 5-minute checks, email alerts — no credit card needed.
Would love your feedback in the comments! 🚀
Top comments (0)