A modern, secure, and feature-rich personal notes application with a React SPA frontend and Node.js/Express API backend.
Click to view screenshots
Login with username/password or one-click Google Sign-In
Organize notes with tags, search, favorites, and pinning
Rich markdown editor with live preview
Track tasks with priorities and due dates
Beautiful dark theme with glassmorphism design
Clean, modern design with Apple-inspired glassmorphism
NotesPage & TasksPage:
- Removed redundant elements for cleaner interface
- Consistent modern design across both pages
- Improved mobile experience with better dock positioning
- Enhanced folder management with glassmorphism effects
Mobile Navigation:
- Fixed minimized dock visibility on mobile landscape
- Scrollable expanded dock for small screens
- Improved tap targets and touch interactions
Folder Management:
- Always visible 3-dot menu on mobile
- Glassmorphism design with smooth animations
- Confirmation modal for safe deletions
- Improved context menu positioning
π Detailed Changes: See UI Improvements Documentation
One-click sign-in with automatic account creation
Disable 2FA without entering OTP code (already authenticated via JWT)
User management with 2FA recovery tools
Admins can disable user 2FA for account recovery (lost devices, emergencies)
Note: To add actual screenshots, see Screenshot Capture Guide
| Layer | Technology |
|---|---|
| Frontend | Vite + React 19 + TypeScript |
| Backend | Node.js + Express |
| ORM | Sequelize |
| Database | SQLite (dev) / MySQL (prod) |
| Replication | Read replicas (MySQL + SQLite) |
| Caching | Redis (optional) |
| Search | Elasticsearch (optional) |
| Authentication | JWT + Google OAuth 2.0 (optional) |
| API | RESTful with JWT authentication |
| Reverse Proxy | Traefik v2.11 (automatic routing) |
| Monitoring | Prometheus + Grafana |
| Logging | Winston + Graylog (optional) |
| Deployment | Docker + Traefik + Hetzner VPS |
| CI/CD | GitHub Actions + GitHub Pages |
- π¨ Modern Design System - Apple-inspired glassmorphism across the application
- Consistent modern header design on Notes and Tasks pages
- Removed redundant UI elements for cleaner interface
- Enhanced visual hierarchy with gradient badges and modern buttons
- π± Mobile Experience - Significantly improved mobile usability
- Fixed dock positioning on mobile landscape view
- Scrollable navigation dock for small screens
- Improved touch targets and tap actions
- Better folder management on mobile devices
- π Folder Management - Enhanced folder interaction and safety
- Always visible 3-dot menu on mobile (hover on desktop)
- Glassmorphism effects with smooth animations
- Confirmation modal prevents accidental deletions
- Increased spacing and improved context menu positioning
- β¨ See Detailed UI Changes Documentation
- π Traefik Integration - Migrated from nginx to Traefik for better container-native routing
- Automatic service discovery via Docker labels
- Dynamic configuration without restarts
- SSL/HTTPS enabled by default with automatic Let's Encrypt certificates
- HTTP to HTTPS redirect with HSTS security headers
- Modern dashboard and monitoring
β οΈ Using a custom domain? See TROUBLESHOOTING_SSL.md to fix certificate warnings
- π Prometheus + Grafana Monitoring - Complete observability stack
- Real-time application metrics (requests, latency, errors)
- System metrics (CPU, memory, disk, network)
- Container metrics via cAdvisor
- Pre-built Grafana dashboards
- Optimized for 2GB RAM VPS (~1GB overhead)
- No port conflicts with NoteHub or Drone CI
- See MONITORING_QUICKSTART.md for setup
- β‘ 10x Faster Queries - Redis caching reduces note list operations from 80ms to 8ms
- π 5x Faster Search - Elasticsearch integration improves search from 150ms to 30ms
- ποΈ SQL Optimization - Added 4 composite indexes for complex query patterns
- π Database Replication - Read replicas for improved performance and high availability
- π Performance Benchmarks:
Operation Before After Improvement List notes 80ms 8ms 10x Search notes 150ms 30ms 5x Get tags 40ms 4ms 10x Read operations (with replicas) 80ms 25ms 3x
- π Strengthened Password Hashing - Upgraded from bcrypt 12 to 14 rounds (4x more secure)
- π Automatic Hash Upgrades - Opportunistic rehashing on login (transparent to users)
- π Simplified 2FA Management - Remove 2FA without entering OTP code
- π¨βπΌ Admin 2FA Recovery - Admins can disable user 2FA for account recovery
- π Privacy-Compliant Logging - GDPR/CCPA compliant audit trails
- π Google OAuth SSO - One-click sign-in with automatic account creation
- π§ͺ Comprehensive Test Suite - 94+ tests covering all features and security
- π Extensive Documentation - 50K+ words of guides and technical docs
- βοΈ Configuration Management - Centralized, environment-tunable settings
All new features are optional and designed for graceful degradation. NoteHub continues to work perfectly in SQL-only mode.
- π Rich Markdown Editor - Full markdown support with live preview
- π·οΈ Smart Organization - Tags, favorites, pinning, and powerful search
- β Task Management - Create and track tasks with priorities and due dates
- π₯ Collaboration - Share notes with other users with view/edit permissions
- π¨ Customizable UI - Light/dark mode, responsive glassmorphism design
- π Internationalization (i18n) - Multi-language support (English, German, Vietnamese, Japanese)
- π± Mobile-Friendly - Works seamlessly on all devices, installable as PWA
- π€ User Profiles - Customizable profiles with themes and bio
- π Offline Mode - Full offline support with automatic sync when reconnected
- π Two-Factor Authentication - TOTP-based 2FA with QR code setup and simplified management
- π Google OAuth Single Sign-On - One-click sign-in with automatic account creation
- π Strengthened Password Security - bcrypt with 14 rounds (4x more secure) and automatic hash upgrades
- π‘οΈ Admin Controls - Admin dashboard with user management and 2FA recovery tools
- π Audit Logging - Comprehensive security event logging (GDPR/CCPA compliant)
- β‘ Redis Caching - Optional 10x performance boost for frequently accessed data
- π Elasticsearch Integration - Optional full-text search with fuzzy matching (5x faster)
- ποΈ SQL Query Optimization - Composite indexes for complex query patterns
- π Performance Monitoring - Built-in query performance tracking
- πΎ IndexedDB Storage - Large offline data capacity with automatic caching
- π§ͺ Comprehensive Test Suite - 34 frontend tests with snapshot testing, 60+ backend integration tests
- π§ TypeScript Support - Full type safety across the frontend
- π¦ Modular Architecture - Clean separation of concerns with service layers
- π Extensive Documentation - 50K+ words covering all features and setup
- Node.js 18+ and npm
- Git
- Redis (optional, for caching)
- Elasticsearch (optional, for full-text search)
- Google OAuth credentials (optional, for SSO)
git clone https://github.com/thienng-it/note-hub.git
cd note-hubcd backend
# Install dependencies
npm install
# Configure environment (copy from example)
cp .env.example .env
nano .env # Edit with your values
# Required settings:
export JWT_SECRET="your-secret-key-here"
export NOTES_ADMIN_PASSWORD="your-secure-password"
# Optional performance enhancements:
export REDIS_URL="redis://localhost:6379" # 10x faster queries
export ELASTICSEARCH_NODE="http://localhost:9200" # 5x faster search
# Optional Google OAuth SSO:
export GOOGLE_CLIENT_ID="your-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-secret"
export GOOGLE_REDIRECT_URI="http://localhost:3000/auth/google/callback"
# Run the backend API
npm run dev
# Backend API runs at http://localhost:5000Note: All optional services (Redis, Elasticsearch, Google OAuth) are designed for graceful degradation. The app works perfectly without them, falling back to SQL-only mode.
cd frontend
# Install dependencies
npm install
# Configure environment (copy from example)
cp .env.example .env
# Edit .env and set VITE_API_URL to your backend URL
# For development: VITE_API_URL=http://localhost:5000
# For production: Leave empty to use same origin
nano .env
# Run development server
npm run dev
# Frontend runs at http://localhost:5173Important for Chat Feature: The
VITE_API_URLenvironment variable is required in development for WebSocket connections to work. Without it, Socket.io will try to connect to the frontend dev server instead of the backend.
NoteHub supports multiple deployment modes:
Recommended: Use docker-compose.dev.yml (no registry cache issues)
# Copy and configure environment (REQUIRED)
cp .env.example .env
nano .env # Set NOTES_ADMIN_PASSWORD and other values
# Build and run with simplified development configuration
docker compose -f docker-compose.dev.yml up -d
# Seed the database with sample data
docker compose -f docker-compose.dev.yml exec backend node scripts/seed_db.js
# Access at http://localhost
# Note: Uses HTTP for simple local development (no certificate warnings)Alternative: Use standard docker-compose.yml
# If docker-compose.dev.yml doesn't work, use standard compose file
# Note: May show registry cache warnings (403 Forbidden from ghcr.io) - these can be ignored
docker compose up -d
# Seed the database
docker compose exec backend node scripts/seed_db.js# Set required MySQL credentials in .env first
# MYSQL_ROOT_PASSWORD, MYSQL_USER, MYSQL_PASSWORD
# Run with MySQL profile
docker compose --profile mysql up -d
# Seed the MySQL database
docker compose exec backend-mysql node scripts/seed_db.js
# Access at http://localhost or https://localhost (production config uses HTTPS)For production deployments connecting to external databases (PlanetScale, AWS RDS, etc.):
# Configure production environment
cp .env.example .env
nano .env
# Set these variables for production:
# SECRET_KEY=<strong-random-key>
# DATABASE_URL=mysql://user:password@your-cloud-db:3306/notehub
# NOTES_ADMIN_PASSWORD=<secure-admin-password>
# ACME_EMAIL=admin@yourdomain.com # For Let's Encrypt SSL certificates
# Run with production profile
docker compose --profile production up -d
# NOTE: Do NOT run seed script in production!
# Database should be pre-configured via cloud provider's management console.
# Access at https://yourdomain.com (automatic SSL via Let's Encrypt)
# Ensure your domain points to your server and ports 80/443 are openImportant: The seed script is blocked in production mode to prevent accidental data modification. Use your cloud database provider's tools to manage production data.
Or build individual images:
# Build backend
docker build -f Dockerfile.backend.node -t notehub-backend .
# Build frontend
docker build -f Dockerfile.frontend -t notehub-frontend .After running the seed script, use these credentials to login:
- Admin:
admin/ (password set inNOTES_ADMIN_PASSWORDenv var) - Demo:
demo/Demo12345678!
note-hub/
βββ frontend/ # Vite + React frontend (SPA)
β βββ src/
β β βββ api/ # API client with JWT handling
β β βββ components/ # React components
β β βββ context/ # Auth and Theme contexts
β β βββ pages/ # Page components
β β βββ types/ # TypeScript types
β β βββ test/ # Test setup
β βββ public/ # Static assets
β βββ vite.config.ts # Vite + Vitest configuration
β βββ package.json # Frontend dependencies
βββ backend/ # Node.js/Express API
β βββ src/
β β βββ routes/ # API route handlers
β β βββ services/ # Business logic
β β βββ middleware/ # Authentication middleware
β β βββ config/ # Database configuration
β β βββ index.js # Application entry point
β βββ tests/ # Backend test suite
β βββ package.json # Backend dependencies
βββ scripts/ # Utility scripts
β βββ seed_db.js # Database seeding script
βββ docker/ # Docker configuration
β βββ nginx.conf # nginx config for frontend
βββ docker-compose.yml # Full stack deployment
βββ Dockerfile.backend.node # Backend Docker image
βββ Dockerfile.frontend # Frontend Docker image
NoteHub includes a comprehensive test suite with 94+ tests covering frontend UI, backend integration, and security features.
# Frontend tests (34 tests)
cd frontend
npm test # Run all tests
npm run test:coverage # With coverage report
# Backend tests (60+ tests)
cd backend
npm test # Run all tests
npm test -- --coverage # With coverage report
# Lint and type-check
cd frontend
npm run lint # ESLint
npm run type-check # TypeScript compilation
cd backend
npm run lint # ESLint- β Frontend: Snapshot tests, user interactions, OAuth flows, error handling
- β Backend: Authentication, 2FA management, Google OAuth, Redis caching, Elasticsearch search
- β Security: Password hash upgrades, audit logging, admin controls
- β Integration: E2E flows for all major features
See Test Suite Summary for complete details.
The frontend is automatically deployed to GitHub Pages on push to main.
Configure the API URL via VITE_API_URL environment variable.
~β¬3.50/month with unlimited bandwidth!
| Component | Cost | Benefits |
|---|---|---|
| Hetzner VPS | β¬3.29/mo | 2 vCPU, 2GB RAM, 40GB SSD |
| Cloudflare Tunnel | Free | Unlimited bandwidth, DDoS protection, CDN |
# On your VPS
git clone https://github.com/thienng-it/note-hub.git
cd note-hub
# Configure
cp .env.example .env
nano .env
# Deploy
docker compose up -dSee Hetzner Deployment Guide for complete setup.
Deploy Drone CI as a standalone, independent CI/CD platform with automated deployment to production. Drone CI does not depend on NoteHub and can be deployed on the same server, a different server, or completely independently.
π Note: Drone CI is a completely independent application with its own services, configuration, network, and data storage. It can be deployed anywhere, with or without NoteHub.
Key Features:
- π³ Container-native CI/CD platform
- π Automatic GitHub integration
- π Parallel pipeline execution
- π Beautiful web UI on port 8080
- β Completely independent from NoteHub
- π’ Automated deployment to production on push to main
Automated Deployment Pipeline:
Push to main β Tests β Build β Deploy to VPS
β Backend tests
β Frontend tests
β Linting
β Type checking
β
Auto-deploy to production
β Zero-downtime deployment
β Automatic backups
β Health checks
# Setup Drone CI (independent deployment)
cp .env.drone.example .env.drone
nano .env.drone # Configure GitHub OAuth and secrets (separate from NoteHub)
# Deploy Drone CI
docker compose --env-file .env.drone -f docker-compose.drone.yml up -d
# Access Drone CI at http://your-server:8080
# Configure deployment secrets in Drone UI
# Push to main branch β Automatic deployment!Documentation:
- DRONE_CI_DEPLOYMENT.md - β Complete automated deployment guide
- DRONE_CI_DEPLOYMENT_QUICK.md - Quick 5-minute setup
- DRONE_CI_README.md - Quick start and overview
- DRONE_CI_UI_IMPLEMENTATION.md - UI features and verification
- DRONE_CI_STANDALONE.md - Complete independence documentation
- DRONE_CI_SETUP.md - Detailed setup guide
The API uses JWT authentication with optional Google OAuth 2.0 SSO. Key endpoints:
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/login |
Login, get JWT token |
| POST | /api/auth/refresh |
Refresh access token |
| GET | /api/auth/google/status |
Check if Google OAuth enabled |
| GET | /api/auth/google |
Get Google OAuth URL |
| POST | /api/auth/google/callback |
Complete Google OAuth flow |
| POST | /api/auth/2fa/disable |
Disable 2FA (no OTP required) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/notes |
List user's notes (cached if Redis enabled) |
| POST | /api/notes |
Create new note |
| GET | /api/notes/search |
Full-text search (uses Elasticsearch if enabled) |
| GET | /api/notes/:id |
Get note by ID |
| PATCH | /api/notes/:id |
Update note |
| DELETE | /api/notes/:id |
Delete note |
| GET | /api/tasks |
List user's tasks |
| POST | /api/tasks |
Create new task |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/admin/users/:userId/disable-2fa |
Admin disable user 2FA |
See API Documentation for full reference.
| Document | Description |
|---|---|
| Hetzner Deployment | Deploy to Hetzner VPS |
| Custom Domain SSL Setup | Fix "not secure" certificate warnings |
| SSL/HTTPS Setup | SSL certificate configuration |
| Drone CI README | Quick start for independent Drone CI |
| Drone CI UI Implementation | UI features, architecture, and verification |
| Drone CI Standalone | Complete independence documentation |
| Drone CI Setup | Detailed Drone CI setup guide |
| Environment Configuration | .env setup and management |
| Logging Configuration | Structured logging setup |
| Graylog Setup | Centralized log aggregation and search |
| Database Replication | Read replicas for MySQL & SQLite |
| Caching & Search Setup | Redis & Elasticsearch setup |
| Google OAuth Setup | Configure Google Single Sign-On |
| Internationalization (i18n) | Multi-language support guide |
| Contributing | Development guidelines |
| Document | Description |
|---|---|
| Architecture | System design |
| API Documentation | REST API reference |
| Security Guide | Security best practices |
| Password Security | Password hashing improvements |
| 2FA Improvements | 2FA management changes |
| Document | Description |
|---|---|
| NoSQL Investigation | SQL vs NoSQL analysis |
| SQL vs NoSQL Comparison | Detailed comparison |
| Implementation Summary | Performance enhancements |
| Test Suite Summary | Complete test documentation |
All documentation is available in both Markdown and HTML formats for better readability:
- Documentation Portal - Beautiful web interface with search functionality
- Complete Index - Full list of all documentation files
- Getting Started - Project overview and quick start
The documentation is automatically converted from Markdown to HTML during deployment. To build locally:
# Install dependencies
npm install
# Convert all markdown files to HTML
npm run build:docsThis generates HTML files with consistent styling, syntax highlighting, and easy navigation between documents.
If you see errors like failed to authorize: failed to fetch anonymous token: 403 Forbidden when building:
# Solution 1: Use docker-compose.dev.yml (recommended for local development)
docker compose -f docker-compose.dev.yml up -d
# Solution 2: Use docker-compose.local.yml override
docker compose -f docker-compose.yml -f docker-compose.local.yml up -d
# Solution 3: Ignore the warnings and let the build continue
# The errors are warnings about cache, the build will still succeed
docker compose up -dWhy this happens: The main docker-compose.yml includes cache_from directives that reference GitHub Container Registry (ghcr.io) for faster builds in CI/CD. These require authentication, but local development doesn't need them. The docker-compose.dev.yml file removes these directives.
If Alpine package manager (apk) fails with "Permission denied" or timeout errors:
# This is usually a temporary network issue. Try:
# 1. Wait a few minutes and retry
docker compose -f docker-compose.dev.yml up -d --build
# 2. Use different DNS (if on Linux)
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
# 3. Check your internet connection and firewall settings# Make sure you've copied and configured .env file
cp .env.example .env
nano .env # Set NOTES_ADMIN_PASSWORD to a secure password
# Then restart
docker compose -f docker-compose.dev.yml down
docker compose -f docker-compose.dev.yml up -dFor the best local development experience, we recommend running the backend and frontend directly with npm instead of Docker:
# Terminal 1: Backend
cd backend
npm install
cp .env.example .env # Configure your .env
npm run dev
# Terminal 2: Frontend
cd frontend
npm install
cp .env.example .env # Set VITE_API_URL=http://localhost:5000
npm run devThis provides:
- β Faster rebuilds (no Docker layer caching needed)
- β Hot module replacement for instant changes
- β Better debugging experience
- β Direct access to logs
Docker Compose is recommended for:
- Production-like testing
- Testing Traefik routing
- Testing with MySQL instead of SQLite
- Multi-service integration testing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'feat: add amazing feature' - Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.