A visual diary for meals, places, and moments. Built with Node.js, Express, and SQLite.
- Food Posts — Upload multiple images + optional video, with notes, author, location, rating, and tags
- Collections & Tags — Organize posts into collections and tag them for filtering
- Comments & Reactions — Emoji reactions and comments on posts
- AI Chat — Built-in AI chat assistant with Claude, OpenAI, and custom provider support (docs)
- PDF Merge — Merge multiple PDFs into one (docs)
- User Auth — Registration with email verification, role-based access control
- Admin Panel — User management, audit logs, per-user tool permissions
- Auto-Backup — Periodic database and uploads backup with configurable retention
- Performance — Gzip compression, image optimization, SQLite WAL mode, optional Redis caching
| Layer | Technology |
|---|---|
| Backend | Node.js 22+, Express |
| Database | SQLite3 (WAL mode) |
| Templates | EJS |
| Frontend | Vanilla JS, CSS |
| Storage | Local filesystem or Cloudflare R2 |
| Caching | Optional Redis |
# Install dependencies
npm install
# Copy and configure environment
cp .env.example .env
# Edit .env with your settings (at minimum: SESSION_SECRET, SMTP_*)
# Start the server
npm startOpen http://localhost:3000. The first verified user becomes admin.
Copy .env.example to .env. Key settings:
| Variable | Description |
|---|---|
SESSION_SECRET |
Session encryption secret (use a strong random value) |
SMTP_HOST |
SMTP server for email verification |
SMTP_PORT |
SMTP port (default 587) |
SMTP_USER |
SMTP username |
SMTP_PASS |
SMTP password |
SMTP_FROM |
Sender email address |
| Variable | Default | Description |
|---|---|---|
DB_PATH |
./data.db |
SQLite database path |
MAX_IMAGES_PER_POST |
10 |
Max images per post |
MAX_UPLOAD_FILE_SIZE_MB |
10 |
Max image upload size |
MAX_VIDEO_FILE_SIZE_MB |
50 |
Max video upload size |
POSTS_PER_PAGE |
20 |
Posts per page |
CACHE_ENABLED |
true |
Enable Redis caching |
REDIS_URL |
— | Redis connection URL |
BACKUP_ENABLED |
true |
Enable auto-backup |
BACKUP_INTERVAL_HOURS |
24 |
Hours between backups |
See .env.example for the full list.
Set at least one API key to enable the AI chat tool:
ANTHROPIC_API_KEY=sk-ant-... # Claude
OPENAI_API_KEY=sk-... # OpenAI
CUSTOM_LLM_BASE_URL=https://... # Any OpenAI-compatible endpoint
CUSTOM_LLM_API_KEY=...
CUSTOM_LLM_MODELS=model-1,model-2See docs/ai-chat.md for full setup details.
# Video transcoding
brew install ffmpeg
# PDF merge tool
brew install ghostscriptdocker compose up --build- Point DNS to your server
- Configure
.env(setSESSION_SECRET,SITE_DOMAIN,ACME_EMAIL, SMTP vars) - Run:
docker compose -f deploy/docker-compose.prod.yml --env-file .env up -d --buildTools are registered through a modular registry. To add a new tool:
- Create a module in
src/tools/(seepdf-merge-tool.jsas reference) - Register it in
server.jswithtoolRegistry.register(...) - It automatically appears in
/toolswith admin-managed per-user access
Tool documentation: docs/
Auto-backup runs every 24 hours (configurable) and stores backups in ./backups/.
Manual backup/restore:
sh back.sh # create backup
sh timeback.sh 3 # restore to nearest backup from 3 days ago
sh timeback.sh 3 --yes # non-interactive restoreserver.js # Main application
src/
framework/tool-registry.js # Tool plugin system
tools/ # Tool implementations
backup-manager.js # Auto-backup
cache-manager.js # Redis cache layer
views/ # EJS templates
public/ # Static assets (JS, CSS)
deploy/ # Docker + Caddy production config
docs/ # Tool documentation
MIT