docs-plus/docs.plus
A real-time community collaboration platform
📚 docs.plus
docs.plus is a free, real-time collaboration tool built on open-source technologies. It empowers communities to share and organize information logically and hierarchically, making teamwork and knowledge sharing straightforward and effective.
🏗️ Architecture
┌─────────────────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌────────────────────┐ │
│ │ Webapp │ │ Admin Dashboard │ │ TipTap Extensions │ │
│ │ (Next.js) │ │ (Next.js) │ │ hyperlink, media │ │
│ │ Port 3000 │ │ Port 3100 │ │ indent, code │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────────────────┘ │
│ │ │ │
└────────────┼───────────────────────┼─────────────────────────────────────────┘
│ HTTP/WS │ HTTP
▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ BACKEND LAYER │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ REST API │ │ WebSocket │ │ Worker │ │
│ │ (Hono) │ │ (Hocuspocus) │ │ (BullMQ) │ │
│ │ Port 4000 │ │ Port 4001 │ │ Port 4002 │ │
│ │ │ │ │ │ │ │
│ │ • Auth │ │ • Real-time │ │ • Doc storage │ │
│ │ • Documents │ │ collaboration │ │ • Email queue │ │
│ │ • Workspaces │ │ • Y.js sync │ │ • Push notifs │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │ │
└────────────┼───────────────────────┼───────────────────────┼────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ DATA LAYER │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ ┌───────────────────────────────┐ │
│ │ PostgreSQL │ │ Redis │ │
│ │ (Supabase) │ │ │ │
│ │ Port 5432 │ │ Port 6379 │ │
│ │ │ │ │ │
│ │ • Users & Auth │ │ • Job queues (BullMQ) │ │
│ │ • Documents & Workspaces │ │ • Pub/Sub (WS sync) │ │
│ │ • Realtime subscriptions │ │ • Session cache │ │
│ │ • Row Level Security │ │ • Rate limiting │ │
│ └───────────────────────────────┘ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ Supabase Studio │
│ Port 54323 │
│ (Dev only) │
└─────────────────┘
Monorepo Structure:
- 🌐
packages/webapp- Next.js frontend with TipTap editor - 🖥️
packages/admin-dashboard- Admin panel for platform management - ⚡
packages/hocuspocus.server- REST API, WebSocket server, and background workers - 🗄️
packages/supabase- Database migrations and Supabase configuration - 🔌
packages/extension-*- TipTap extensions (hyperlink, multimedia, indent, inline-code) - 📦
packages/eslint-config- Shared ESLint configurations
Tech Stack:
- Runtime: 🚀 Bun 1.3.7+
- Frontend: ⚛️ Next.js 15/16, React 19, TipTap 3, Tailwind CSS 4
- Backend: 🔧 Hono, Hocuspocus (Y.js), BullMQ, Prisma ORM
- Database: 🐘 PostgreSQL 17, 🔴 Redis
- Infrastructure: 🐳 Docker Compose, Supabase
- Real-time: 🔌 WebSocket (Hocuspocus), Supabase Realtime
📋 Prerequisites
- 🐳 Docker & Docker Compose v2+ - Install
⚠️ macOS Silicon users: Docker Desktop has IO performance issues. Use OrbStack instead (drop-in replacement, faster, lighter).
- 🚀 Bun >=1.3.7 - Install
- 🗄️ Supabase CLI - Install
🚀 Quick Start
1️⃣ Clone & Install
git clone https://github.com/docs-plus/docs.plus.git
cd docs.plus
bun install2️⃣ Environment Configuration
Create environment files based on your development mode:
# Required: Create .env.development first (used by Docker dev and as base for local dev)
cp .env.example .env.developmentEnvironment File Mapping:
| Docker Compose File | Environment File | Usage |
|---|---|---|
docker-compose.prod.yml |
.env.production |
Production deployment |
docker-compose.dev.yml |
.env.development |
Docker development (all services in containers) |
docker-compose.local.yml |
.env.local |
Local development (infra in Docker, apps native) |
Important Differences:
.env.development (Docker Development):
- Uses Docker service names for inter-container communication:
SERVER_RESTAPI_URL=http://rest-api:4000/api(Docker service name)REDIS_HOST=redis(Docker service name)DATABASE_URLis set by Docker Compose (not in file)
.env.local (Local Development):
- Uses localhost for native apps connecting to Docker infrastructure:
SERVER_RESTAPI_URL=http://localhost:4000/api(localhost)REDIS_HOST=localhost(localhost)DATABASE_URL=postgresql://...@localhost:5432/...(explicit connection string)
- Auto-created from
.env.developmentwhen you runmake dev-localormake infra-up - Gitignored - safe for local customizations
Note: .env.local is automatically created from .env.development on first run. You only need to create .env.development manually.
3️⃣ Initialize Supabase
🗄️ Option A: Local Supabase Setup (One-time, ~5-10 min)
Step 1: Start Supabase 🚀
make supabase-startFirst run downloads Docker images. Verify with make supabase-status.
Step 2: Activate Extensions 🔌
- Open Supabase Studio
- Go to Integrations
- Activate: pg_cron and pgmq (Queues)
Step 3: Run Migrations 📊
- Open SQL Editor
- Execute scripts from
packages/supabase/scripts/in order:01-enum.sqlthrough17-database-extensions.sql
Step 4: Configure Queues ⚙️
- Queue Settings → Enable "Expose Queues via PostgREST"
- Queues → Select
message_counter→ Manage permissions - Enable Select/Insert/Update/Delete for:
authenticated,postgres,service_role - Add RLS policy: "Allow anon and authenticated to access messages from queue"
☁️ Option B: Supabase Cloud Setup
If you prefer not to run Supabase locally, you can use a cloud project instead:
Step 1: Create Supabase Project 🚀
- Go to Supabase Dashboard
- Create a new project
- Copy your project URL and anon key from Settings → API
Step 2: Update Environment Variables ⚙️
Update .env.development with your cloud project credentials:
# Server-side (containers → Supabase Cloud)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key-here
# Client-side (browser → Supabase Cloud)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_WS_URL=wss://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-hereStep 3: Configure Extensions & Migrations 📊
You still need to configure your cloud project:
- Activate pg_cron and pgmq (Queues) extensions in the Dashboard
- Run SQL scripts from
packages/supabase/scripts/in order via SQL Editor - Configure queues and permissions (same as local setup)
Backend Environment Variables:
# Supabase connection (for pgmq polling)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# VAPID keys for Web Push
VAPID_PUBLIC_KEY=your-vapid-public-key
VAPID_PRIVATE_KEY=your-vapid-private-key
VAPID_SUBJECT=mailto:support@yourdomain.comGenerate VAPID keys: npx web-push generate-vapid-keys
See docs/PUSH_NOTIFICATION_PGMQ.md for detailed architecture.
Step 5: Configure OAuth Redirect URLs 🔐
Go to Authentication → URL Configuration in Supabase Dashboard and add your Redirect URLs:
https://yourdomain.com
https://yourdomain.com/*
https://admin.yourdomain.com
https://admin.yourdomain.com/*
Replace yourdomain.com with your actual domain.
Step 6: Add Admin Users 👤
Only users in the admin_users table can access the admin dashboard. Run this SQL to grant access:
-- Add admin user by email
INSERT INTO public.admin_users (user_id, created_at)
SELECT id, now() FROM auth.users WHERE email = 'your-admin@example.com';
-- Verify admin users
SELECT u.email, a.created_at
FROM public.admin_users a
JOIN auth.users u ON a.user_id = u.id;Note: Make sure your Supabase project allows connections from your Docker network or configure network settings accordingly.
4️⃣ Start Development Environment
Choose one of three options:
🐳 Option A: Full Docker (Default)
All services run in Docker containers. Best for consistent environments.
make up-devServices: 🎯
- 🌐 Webapp: http://localhost:3000
- 🔌 REST API: http://localhost:4000
- ⚡ WebSocket: ws://localhost:4001
- 👷 Worker: http://localhost:4002
- 🐘 PostgreSQL: localhost:5432
- 🔴 Redis: localhost:6379
- 🗄️ Supabase Studio: http://127.0.0.1:54323
💻 Option B: Local Development (macOS-friendly, No Docker IO)
Best for macOS users - Avoids Docker volume IO performance issues. Only infrastructure (PostgreSQL, Redis) runs in Docker. Apps run natively with hot reload.
Step 1: Start Infrastructure 🚀
make infra-upStep 2: Start Supabase 🗄️
make supabase-startStep 3: Start Apps 💻
Option 3a: All in one command (recommended)
bun run dev:localOption 3b: Separate terminals (better for debugging)
# Terminal 1 - Backend REST API
cd packages/hocuspocus.server && bun run dev:rest
# Terminal 2 - Backend WebSocket
cd packages/hocuspocus.server && bun run dev:hocuspocus.server
# Terminal 3 - Backend Worker
cd packages/hocuspocus.server && bun run dev:hocuspocus.worker
# Terminal 4 - Frontend
cd packages/webapp && bun run devOr use convenience scripts:
bun run dev:backend # Start all backend services
bun run dev:webapp # Start frontend onlyEnvironment Variables:
- ✅
.env.localfile at root - automatically created from.env.developmenton first run .env.development- Used bydocker-compose.dev.yml(Docker service names:rest-api:4000,redis).env.local- Used bydocker-compose.local.ymland native apps (localhost addresses, gitignored)- Scripts automatically load root
.env.local:- Backend: Uses
bun --env-file ../../.env.local - Frontend: Uses
dotenv-clito load root.env.local
- Backend: Uses
- Key differences:
.env.localuseslocalhostinstead of Docker service names:SERVER_RESTAPI_URL=http://localhost:4000/api(vshttp://rest-api:4000/apiin.env.development)REDIS_HOST=localhost(vsredisin.env.development)DATABASE_URL=postgresql://...@localhost:5432/...(explicit, vs set by Docker Compose in.env.development)
- See Step 2: Environment Configuration section above for complete details
Benefits:
- ✅ Native file system performance (no Docker volume overhead)
- ✅ Faster hot reload
- ✅ Better debugging experience
- ✅ Lower resource usage
Access points:
- 🌐 Webapp: http://localhost:3000
- 🔌 REST API: http://localhost:4000
- ⚡ WebSocket: ws://localhost:4001
- 👷 Worker: http://localhost:4002
- 🐘 PostgreSQL: localhost:5432
- 🔴 Redis: localhost:6379
- 🗄️ Supabase Studio: http://127.0.0.1:54323
Stop infrastructure:
make infra-down🚀 Production Deployment
Production-ready setup for mid-level scale deployments (small-medium teams, moderate traffic).
Architecture: 🏗️
- 📈 Horizontal scaling: REST API (2), WebSocket (2), Worker (2), Webapp (2)
- 🔀 Traefik v3 reverse proxy with automatic SSL (Let's Encrypt) and load balancing
- ⚡ Resource limits, health checks, and zero-downtime blue-green deploys
- 📊 Production-optimized logging and connection pooling
Setup
-
⚙️ Configure Environment
cp .env.example .env.production
Important:
.env.productionis used bydocker-compose.prod.ymlfor production deployment.Update: database credentials, JWT secret, Supabase URLs, storage credentials, CORS origins.
-
🔨 Build & Deploy
make build make up-prod
-
📈 Scaling
Adjust replicas in.env.production:REST_REPLICAS=2 WS_REPLICAS=3 WORKER_REPLICAS=2 WEBAPP_REPLICAS=2
Production Recommendations: 💡
- 🗄️ Use managed database (AWS RDS, DigitalOcean, Supabase Cloud)
- 🔒 Configure SSL/TLS certificates
- 📊 Set up monitoring (Prometheus, Grafana)
- 💾 Implement database backups
- 🔐 Secure all secrets and credentials
📖 Command Reference
# Building
make build # Production build
make build-dev # Development build
# Running (Full Docker)
make up-prod # Start production
make up-dev # Start development (all in Docker)
# Running (Local Development - macOS-friendly)
make infra-up # Start infrastructure only (postgres, redis)
make infra-down # Stop infrastructure
make infra-logs # View infrastructure logs
make dev-local # Start all services (backend + frontend)
make dev-backend # Start backend services (REST, WS, Worker)
make dev-webapp # Start frontend only
make dev-rest # Start REST API only
make dev-ws # Start WebSocket server only
make dev-worker # Start Worker only
make migrate # Run database migrations
# Management
make down # Stop services (auto-detects env)
make restart # Restart services (auto-detects env)
make logs # All logs
make logs-webapp # Webapp logs
make logs-backend # Backend logs
make ps # Container status
make stats # Resource usage
make clean # ⚠️ Cleanup + delete volumes (DATA LOSS!)
# Scaling (production)
make scale-webapp # Scale webapp to 3 replicas
make scale-hocuspocus # Scale backend services
# Supabase (uses .env.local)
make supabase-start # Start local Supabase
make supabase-stop # Stop local Supabase
make supabase-status # Show Supabase statusRun make help for complete command list.
📁 Project Structure
docs.plus/
├── packages/
│ ├── webapp/ # 🌐 Next.js frontend
│ ├── hocuspocus.server/ # ⚡ REST API, WebSocket, Workers
│ ├── supabase/ # 🗄️ Database migrations
│ └── extension-*/ # 🔌 TipTap extensions
├── docker-compose.dev.yml # 🐳 Development orchestration
├── docker-compose.prod.yml # 🚀 Production orchestration
├── Makefile # 🛠️ Build & deployment commands
└── .env.example # ⚙️ Environment template
🤝 Contributing
PRs welcome! See contributing guidelines for details.
First contribution? Start here:
- Pick an issue labeled good first issue or help wanted.
- Confirm your setup with
bun run checkbefore opening a PR. - Use our issue and PR templates to speed up review.
📄 License
MIT License - See LICENSE.md
💬 Support
- 💬 Discord: Join our server
- 🐦 Twitter: @docsdotplus
- 🐙 GitHub: docs.plus
- 📧 Email: contact@newspeak.house