- Extract ADR documents for architectural decisions (SQLite, FastAPI, React, APScheduler, Scheduler) - Refactor setup.py: improve code structure and readability - Add IP validation utilities with test coverage - Update frontend components (BanTable, HistoryPage) - Add pre-commit hooks and CONTRIBUTING.md - Add .editorconfig for consistent coding standards
1.9 KiB
1.9 KiB
ADR-001: SQLite as the Application Database
Status
Accepted
Context
BanGUI needs a database to store application state: configuration, session records, blocklist sources, import logs, and ban history archives.
Decision
Use SQLite (via aiosqlite) as BanGUI's application database, persisted to a
volume mounted from the host or a named Docker volume.
Rationale
Why SQLite over PostgreSQL?
- Zero-infrastructure: No separate DB server process, no connection pooling, no credentials to manage. Ships in the Docker container with no additional configuration.
- Fail2ban-compatible: The fail2ban database itself is SQLite. BanGUI already depends on SQLite; adding a second database engine would increase operational complexity for no benefit.
- Single-instance deployment: BanGUI runs as a single service with one
background scheduler (enforced by
BANGUI_WORKERS=1). Horizontal scaling is not a design goal. - Async I/O:
aiosqliteprovides full async support, avoiding blocking I/O in the FastAPI async request handlers.
Why not PostgreSQL?
- Requires a separate service or sidecar container.
- Adds connection overhead (TCP, connection pools, auth).
- Over-engineered for a single-instance web app.
Trade-offs
- Not suitable for multi-worker deployments. SQLite's file-level locking means
only one process can write at a time. This is explicitly enforced:
BANGUI_WORKERS=1is validated at startup, andscheduler_lockprevents duplicate schedulers in restarts. - For future multi-instance deployments, BanGUI would need to migrate to PostgreSQL or add a distributed lock layer (Redis + job store).
Consequences
- Application database is a single file (
bangui.db) in the container's data volume. - Backup is a file copy. No
pg_dumpequivalent needed. - Schema migrations managed via
app/startup.pystartup DAG.