⚡ Solo Miner Monitoring & Alerting System (n8n + Umbrel)

:page_facing_up: 1. Executive Summary

This is a modular, extensible Bitcoin solo miner monitoring and alerting system built entirely in n8n, designed to run locally using Umbrel OS and a suite of miner-related apps. It checks the health, hashrate, and block status of your miners in two physical locations — generically labeled Location A and Location B.

It can:

  • Retry failed health checks up to a threshold
  • Detect offline miners or abnormal performance
  • Send human-readable email alerts
  • Notify when a block is successfully found :tada:

No cloud APIs are required — the system runs fully offline (aside from email delivery), perfect for DIYers running Bitaxe or other home solo mining gear.


:bullseye: 2. Why This Exists & Why It’s Interesting

Solo mining is a high-variance endeavor. This tool ensures:

  • Peace of mind: You’ll know if a miner goes offline
  • Fast response: Retry logic gives recovery room before alarming
  • Celebration: Detects and emails you when a block is mined
  • Total privacy: Runs 100% self-hosted

It’s a decentralized, local-first, extensible solution that requires no third-party monitoring service, and it’s built using accessible no-code logic (n8n + HTTP).


:gear: 3. System Requirements (w/ Links & Explanations)

Install these Umbrel apps in this order, and ensure each dependency is met before moving to the next.


1. Umbrel OS

Install on your own hardware or buy the Umbrel Home

  • Hosts all apps below
  • Required to run n8n, Bitcoin node, and miner stats apps
  • You can use Raspberry Pi, mini PC, or x86 machine but carefully research requirements for normal deployment success as this solution just builds on top of the existing platform.

2. Bitcoin App (Knots)

  • Full Bitcoin node (Knots implementation)
  • Required for Mempool and Public Pool
  • Must sync fully before other apps function

3. Mempool App

  • Visualizes transactions, block propagation, and mining activity
  • Required for Public Pool App
  • Dependent on the Bitcoin Knots node

4. Public Pool App

  • The “target pool” for your solo miners (e.g., Bitaxe)
  • Exposes /api/stats and /api/pool endpoints for:
    • Miner health
    • Hashrate tracking
    • Block discovery
  • Miners must mine to this app for full functionality

5. n8n App

  • Workflow engine that runs:
    • Health checks
    • Retry logic
    • Email delivery
  • Import the provided .json files here

:light_bulb: Email Node Notes

Using Gmail in n8n?

  • The Gmail Send Message node uses OAuth2, which can be difficult to set up.
  • You must:
    • Enable Gmail API in Google Cloud Console
    • Configure OAuth client ID/secret
    • Authorize n8n to send email

:books: Refer to the n8n Docs – Gmail OAuth Setup. This can be a super painful experience so put your patience hat on or skip and use alternate.

:white_check_mark: Possible Simpler Alternative:

  • Use the “SMTP” node with:
    • Mailgun
    • Fastmail
    • Self-hosted Postfix
    • App-specific Gmail password (legacy method)

(Note: I have not used these. Your mileage may vary)


:file_folder: 4. Workflow Files

Filename Purpose
StartMinerCheck.json Entry point — launches check for both regions
Miner_Retry_Check_Logic.json Main retry logic & miner validation
Miner_Online_Check_Notify_Me.json Sends email alert or celebration

:magnifying_glass_tilted_right: 5. Detailed Workflow and Nodes


:hammer_and_wrench: StartMinerCheck.json

Purpose: Entry trigger for the monitoring system. Defines payloads for Location A and B. Mine are in two countries and so I need to check both servers and apps.

Key Nodes:

Node What It Does
Set Timestamp Generates a unique session timestamp
Set Location A Adds region “a”, and builds payload
Set Location B Adds region “b”, and builds payload
Merge Payloads Combines A + B into an array
Split In Batches Ensures one payload per HTTP call
Call Retry Flow Sends each to the /webhook/retry-check endpoint

:repeat_button: Miner_Retry_Check_Logic.json

Purpose: Core retry loop to check miners’ stats, validate conditions, and route to notify. A query might fail, a miner might have a bad ‘poll’, and so I want to give it three chances to fail before getting too concerned.

Core Flow:

Node Description
Reset Counter Start Initializes retry tracking based on sequenceId
Recheck Miner Calls /api/stats on the Public Pool
Combine Session + Miner Merges request & response
If Block Found :white_check_mark: Checks if blocksFound.length > 0
Notify Block Found :tada: Sends celebration email immediately
If Failure Detected Checks for: low TH/s or zero miners. (You’ll need to set your TH/s)
Loop Back Loops again if conditions still warrant retry. Either miner not found or TH/s low
Exit Loop Exits and forwards to Notify Me workflow if retries complete

:megaphone: Miner_Online_Check_Notify_Me.json

Purpose: Sends human-friendly emails for both problem & celebration cases.

Key Nodes:

Node Function
Payload Flatten Makes nested data flat & usable. A major pain with n8n.
Split In Batches One action/email per JSON item; aka miner
Trigger Email Sends either :police_car_light: problem or :tada: success email (for Block) else silent

:envelope_with_arrow: 6. Example Emails


:police_car_light: Miner Offline (0 miners)

Subject:

⚠️ Miner Warning – A – ~04:38 UTC – Miner Not Detected

Body:

<h2>⚠️ Miner Alert – A</h2>
<p><strong>Problem Detected At:</strong> Tuesday, Apr 16, 2025 – 04:38 UTC</p>
<p><strong>Region:</strong> A</p>
<p><strong>Total Miners:</strong> 0</p>
<p><strong>Hashrate:</strong> 0.00 TH/s</p>
<p style="color: red;">🚨 Reason: Miner Not Detected</p>

:warning: Low TH/s

Subject:

⚠️ Miner Warning – B – ~07:10 UTC – Low TH/s

Body:

<h2>⚠️ Miner Alert – B</h2>
<p><strong>Total Miners:</strong> 1</p>
<p><strong>Hashrate:</strong> 1.74 TH/s</p>
<p style="color: red;">🚨 Reason: Low TH/s Performance</p>

:tada: Block Found!

Subject:

🎉 Block Found – A – Height 847221

Body:

<h2>🎉 BLOCK FOUND!</h2>
<p><strong>Region:</strong> A</p>
<p><strong>Block Height:</strong> 847221</p>
<p><strong>Hashrate:</strong> 9.47 TH/s</p>
<p><strong>Detected At:</strong> Tuesday, Apr 16, 2025 – 06:44 UTC</p>
<p><strong>Miner Count:</strong> 4</p>
<p><strong>Pool Fee:</strong> 0%</p>

:test_tube: 7. How to Use It

  1. Import all 3 .json workflows into the n8n app
  2. Update any local IPs or webhook URLs if needed
  3. Configure the email node of your choice
  4. Run StartMinerCheck manually or on a cron schedule
  5. Watch for:
  • Emails when things break else is silent OR
  • :tada: Emails if you hit a block

:locked_with_key: 8. Security Considerations

  • Webhooks are all local (e.g., 192.168.x.x) — Or your LAN
  • No secrets or API keys are stored in the shared files.
  • Be cautious when exposing webhook endpoints externally (use auth if needed)

:white_check_mark: 9. Summary

This monitoring system is a powerful solo miner companion, built for privacy, extensibility, and real-world reliability. It allows:

  • On-device monitoring
  • Triggered alerts with no monthly fees
  • Decentralized data ownership
  • Celebratory moments when solo luck pays off

:file_folder: 10. Files

  • You’ll want to open up the N8N app and import these files
  • Import files into the gui and modify to meet your needs
Summary

StartMinerCheck_SANITIZED.txt (3.5 KB)
Miner_Online_Check_Notify_Me_SANITIZED.txt (4.8 KB)
Miner_Retry_Check_Logic_SANITIZED.txt (17.5 KB)

:t_rex:************************ Time To Customize *************************:t_rex:

:white_check_mark: Post-Import Setup Checklist (n8n)

After importing the three JSON workflows into n8n, follow this checklist:


:puzzle_piece: 1. Check for Imported Workflows

Ensure you see these three workflows in your n8n UI:

  • StartMinerCheck
  • Miner_Retry_Check_Logic
  • Miner_Online_Check_Notify_Me

:compass: 2. Update Webhook URLs (if needed)

If your local IP or n8n hostname is not http://192.168.1.1:5678, update these:

  • In StartMinerCheck → Call Retry Flow
  • In Miner_Retry_Check_Logic → Notify Check Results (HTTP node)
  • In both cases, the webhook URL should point to your n8n instance, not Umbrel’s proxy, unless explicitly configured.

:wrench: Example:

http://localhost:5678/webhook/email-trigger-test

or

http://umbrel.local:5678/webhook/retry-check

:incoming_envelope: 3. Configure the Email Node

Go to the Trigger Email node inside Miner_Online_Check_Notify_Me and configure:

Option A: Gmail

  • Set up OAuth2 credentials per n8n’s Gmail node docs
  • May require a Google Cloud project, consent screen, and redirect URI setup.

:white_check_mark: If successful, test by sending a manual test email.

Option B: SMTP (Recommended for simplicity)

  • Use the SMTP node instead of Gmail
  • Provide:
    • SMTP host (e.g., smtp.mailgun.org)
    • Port (587)
    • Username (email address)
    • App-specific password or token
  • Update the node to format the same output as the Gmail node.

:test_tube: 4. Test the Webhook Triggers

Run the StartMinerCheck workflow once manually:

  • It should fire two HTTP POST requests (Location A & B)
  • Monitor if these show up correctly in the Miner_Retry_Check_Logic
  • If only one location runs: check that the Loop Over Items node in StartMinerCheck is looped back to itself :white_check_mark:

:repeat_button: 5. Verify Retry Flow Logic

In Miner_Retry_Check_Logic:

  • Check that miners are retried 3x on failure
  • Check that failure paths trigger the email node in the next workflow
  • Confirm block detection via the If Block Found node (test with dummy blocks if needed)

:love_letter: 6. Confirm Email Formatting

Check a sample email:

  • :white_check_mark: Subject line uses region and time
  • :white_check_mark: Body includes correct TH/s, miner count, and diagnostic logs
  • :white_check_mark: Test both low TH/s and 0 miners scenarios

:tada: Bonus: Manually simulate a block found by inserting mock data at the blocksFound node to verify celebration email.


:three_o_clock: 7. Optional: Add Scheduling

To automate the checks (e.g. every 30 minutes):

  • Open StartMinerCheck
  • Add a Cron Node or Schedule Trigger
  • Example config:
    • Every 30 minutes
    • Timezone: UTC

:soap: 8. Final Sanity Checks

Item Should Be
Sequence IDs Valid per session (not undefined)
totalMiners, totalHashRate Accurately passed between flows
Email timestamps In UTC, formatted correctly
Debug logs Joined in readable format
SplitInBatches node Used before email/webhook