Belltower
Docker app from Bernie_Sandler's Community Applications
Overview
Readme
View on GitHub
Belltower
Self-hosted ticketing for homelabs and small teams.
Ring the bell when something breaks.
Built with TypeScript Built with React Built with Fastify Built with SQLite Built with Docker
Live Demo
Try it without installing anything: the demo runs entirely in your browser, and your changes stay there.
Belltower is a lightweight ticket tracker for the people who keep things running: whoever runs the home server, the small-office IT person, the friend everyone texts when Plex goes down. It gives you one place to see what's broken, what you're in the middle of, and what's coming up, and to look up how you fixed it last time.
Most tickets are ones you write yourself. A drive starts throwing errors, a container won't update, you've been meaning to move to 10GbE. Make a card for it, drag it across the board as the work moves, and jot down what you tried along the way. When the same thing happens six months later, search finds the card and the note that fixed it.
Tickets can also come from other people through a submit page, or from monitoring tools when something fails, and they land on the same board.
It's built for small setups where a full help desk is overkill and a sticky note isn't enough.
What it's for
- Tracking problems: write down what's wrong, mark how urgent it is, and close it with a note on how it ended
- Planning bigger jobs: keep the tickets for something like "Upgrade Plex" together under one work card, and see what's blocking what
- Staying on top of maintenance: have a monthly parity check or a quarterly look at SMART data show up as a ticket when it's due
- Keeping a record: look back at what changed and when, so you're not relying on memory the next time something acts up
Features
- Board view: a Trello-style board for moving tickets from Triage to Done, with columns you can rename, add, or reorder
- Detailed tickets: priority, severity, due dates, checklists (each step done, failed or unverified), attachments, and links between related tickets
- Labels: tag tickets by area, like Network, Storage, or Docker
- History and work log: every change is recorded automatically, and you can add your own notes, backdated if needed
- Search and calendar: search everything, including archived tickets, or see what was due and what got done by month or week
- Seen this before?: an open ticket lists similar finished ones and how each was fixed
- Ring the bell: a simple page where other people can submit a ticket, without a login or access to your board, and check on it later through a status link
- Automation: Uptime Kuma, Unraid, Home Assistant, or your own scripts can open tickets when something fails, and dashboards like Homepage can show ticket counts
- Notifications: hear about urgent and blocked tickets, plus a daily summary of what's due, through Discord, ntfy, Gotify or any webhook
- Claude drafting (optional): with your own Anthropic API key, describe a problem in your own words and review the ticket Claude writes
- JSON import: bring in existing tickets in bulk
- Backups: nightly snapshots, plus export and restore from the app
- Phone-friendly: add it to your Home Screen and it opens full-screen like an app
- Self-hosted: runs on your own server, so your data stays with you
Status
Belltower is stable. Updates within 1.x never break your data, backups or automation; see what 1.0 promises.
Quick start (Unraid)
- Clone this repository somewhere outside your data folder, for example
/mnt/user/appdata/belltower-src. - Copy
.env.exampleto.env. The defaults are fine for most setups. - In Docker → Compose, add a stack pointing at that folder and press Compose Up (or run
docker compose up -d). - Open
http://tower:8080. - Grab the one-time setup code from the container log and choose a username and password.
The full walkthrough (where the data should live, every setting) is in docs/INSTALL.md.
Documentation
| Install and configure | Setting it up on Unraid, .env settings, troubleshooting |
| Upgrading | Updating, picking a version, rolling back |
| Using Belltower | A tour of the board, cards, work cards, history, search and settings |
| Phone and remote access | Tailscale, Nginx Proxy Manager, the Home Screen app |
| Single sign-on | Signing in with Authentik, Authelia or another OIDC provider |
| Backups | Snapshots, export and restore, moving to a new server |
| Submit page | Letting other people file tickets and check on them |
| Notifications | Discord, ntfy, Gotify and webhooks: what gets announced and how to set it up |
| Automation | Uptime Kuma, Unraid, Home Assistant, scripts and dashboards |
| Claude drafting | Turning a description into tickets, cost and privacy |
| Card import format | Creating cards from JSON (handy with any AI chat) |
| Automation API (v1) | The stable API contract for tools and scripts |
| Backup file format | What's inside an export |
| Development | Building, testing and releasing |
| Security | What the app protects and what's up to you |
| Changelog | What changed in each version |
Versions
Tagged releases are published as images at ghcr.io/bernie-sandler/belltower. Pick a version with TT_VERSION in
.env: latest for stable releases, or an exact version like 1.2.3. Updating is
docker compose pull && docker compose up -d; the database upgrades itself after saving a copy. See
docs/UPGRADING.md.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/bernie-sandler/belltower:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8080]/- Network
bridge- Shell
sh- Privileged
- false
- Extra Params
--init --stop-timeout=30
Template configuration
Port to open the app on, e.g. http://tower:8080.
- Target
- 8080
- Default
- 8080
- Value
- 8080
Database, attachments and backups. SQLite should not go through Unraid's user-share (FUSE) layer: keep this share on a pool with Exclusive access, or use the pool path directly (e.g. /mnt/cache/appdata/belltower).
- Target
- /data
- Default
- /mnt/user/appdata/belltower
- Value
- /mnt/user/appdata/belltower
Optional. If set, this is the login password and it can't be changed in the app. Leave empty to choose a password in the browser using the setup code from the container log.
- Target
- APP_PASSWORD
Optional. Turns on Claude drafting in Add ticket (see docs/AI-DRAFTING.md for what is sent and what it costs). Empty keeps the app fully offline.
- Target
- ANTHROPIC_API_KEY
Only if a reverse proxy (e.g. Nginx Proxy Manager) sits in front of the app: its IP address(es) or CIDR ranges, comma-separated, e.g. 192.168.1.20. Never 'true'.
- Target
- TRUST_PROXY
Largest attachment allowed, in MB.
- Target
- MAX_UPLOAD_MB
- Default
- 25
- Value
- 25
User ID that owns the files in Data (Unraid default: 99 = nobody).
- Default
- 99
- Value
- 99
Group ID that owns the files in Data (Unraid default: 100 = users).
- Default
- 100
- Value
- 100
File-creation mask for new files in Data.
- Default
- 0002
- Value
- 0002