A local-first email system for private networks.
Sandesh provides a complete, self-hosted email experience without requiring internet connectivity or external mail servers. Perfect for office intranets, home labs, development environments, and air-gapped networks.
- 📧 Full Email Experience - Send, receive, organize, and search emails
- 🔐 Local Authentication - No external auth providers needed
- 📁 Folder Management - Inbox, Sent, Trash, plus custom folders
- 👥 Multi-user Support - Create accounts for your team
- 🎨 Modern UI - Gmail-inspired interface with dark/light themes
- 🔧 Admin Console - Manage users and system settings
- 📦 Docker Ready - Single container deployment
- 🌐 No Internet Required - Works completely offline
- Docker and Docker Compose installed
- Port 8000 (web) and 2525 (SMTP) available
git clone https://github.com/yourusername/sandesh.git
cd sandesh
docker compose up --build -dOpen http://localhost:8000 in your browser.
Default credentials:
- Username:
admin - Password:
admin123
⚠️ Change the admin password in production by setting environment variables.
Set these in docker-compose.yml or your deployment environment:
| Variable | Description | Default |
|---|---|---|
SANDESH_NAMESPACE |
Email domain (e.g., office) |
local |
SANDESH_ADMIN_USER |
Admin username | admin |
SANDESH_ADMIN_PASSWORD |
Admin password | admin123 |
DATABASE_URL |
SQLite database path | sqlite:////data/sandesh.db |
version: '3.8'
services:
sandesh:
build: .
ports:
- "8000:8000" # Web UI
- "2525:2525" # SMTP
volumes:
- sandesh_data:/data
environment:
- SANDESH_NAMESPACE=office
- SANDESH_ADMIN_USER=admin
- SANDESH_ADMIN_PASSWORD=supersecret123
- DATABASE_URL=sqlite:////data/sandesh.db
volumes:
sandesh_data:- Open http://localhost:8000
- Login with admin credentials
- You'll see the main inbox view
- Click your username in the bottom-left sidebar
- Select "Your Profile"
- Set your Display Name (how you appear in emails)
- Add an optional Email Signature
- Save changes
- Click "Admin Console" in the sidebar
- Click "Add User"
- Enter username (becomes part of their email address)
- Enter a password
- Optionally set their display name
- Click "Create User"
Understanding Email Addresses:
- Username:
alice - Namespace:
office - Email:
alice@office
- Click your username → "System Settings"
- Set Instance Name (shown on login page)
- Set Mail Namespace (changes all email addresses)
⚠️ Changing namespace affects all users
- Save with confirmation
- Click the Compose button
- Enter recipient:
username@namespace - Add subject and message
- Click Send
Sandesh uses a clear identity model:
| Field | Editable By | Description |
|---|---|---|
| Username | Nobody | Permanent unique identifier |
| Display Name | User | Friendly name shown in UI and emails |
| Email Address | Admin only | Generated: username@namespace |
| Signature | User | Auto-appended to outgoing emails |
From: Alice Johnson <alice@office>
To: bob@office
Subject: Hello!
Hi Bob, ...
--
Alice Johnson
Engineering Team
See DOCUMENTATION.md for complete API reference.
Login:
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'Get Profile:
curl http://localhost:8000/api/users/me \
-H "Authorization: Bearer YOUR_TOKEN"Send Email:
curl -X POST http://localhost:8000/api/mail/send \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":["bob@office"],"subject":"Hello","body":"Hi there!"}'- Frontend: React, React Router, Lucide Icons
- Backend: FastAPI, SQLAlchemy, Pydantic
- Database: SQLite
- SMTP: aiosmtpd
- Auth: JWT tokens, bcrypt
- Deployment: Docker, multi-stage build
# Backend
cd backend
pip install -r requirements.txt
uvicorn backend.main:app --reload
# Frontend
cd frontend
npm install
npm run devsandesh/
├── backend/
│ ├── api/ # REST endpoints
│ ├── core/ # Domain entities, exceptions
│ ├── infrastructure/ # DB, SMTP, security
│ ├── services/ # Business logic
│ ├── main.py # FastAPI app
│ └── config.py # Configuration
├── frontend/
│ ├── src/
│ │ ├── components/ # UI components
│ │ ├── pages/ # Page views
│ │ └── api.js # API client
│ └── index.html
├── docker-compose.yml
├── Dockerfile
├── DOCUMENTATION.md
└── README.md
# Check what's using ports 8000 or 2525
lsof -i :8000
lsof -i :2525# View logs
docker logs sandesh
# Rebuild from scratch
docker compose down -v
docker compose up --build# Stop container
docker compose down
# Delete database (loses all data!)
docker volume rm sandesh_sandesh_data
# Restart with new password in environment
docker compose up -d- Change default admin credentials in production
- Use HTTPS reverse proxy for production deployments
- Database is stored in Docker volume - back it up regularly
- Passwords are hashed with bcrypt
- JWT tokens expire after 60 minutes by default
MIT License - see LICENSE for details.
Contributions welcome! Please read the contribution guidelines first.
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
Built with ❤️ for local-first email