diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..4339630 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,182 @@ +# Installation Guide + +## Prerequisites + +- Docker (or Docker Compose) +- A Linux host (x86_64 or ARM64, e.g. Synology NAS) + +## Quick Install + +```bash +# Clone the repo +git clone https://git.aholck.net/anders-pub/markdown-hub.git +cd markdown-hub + +# Build the image +docker build -t markdownhub . + +# Run +docker run -d \ + --name markdownhub \ + --restart unless-stopped \ + -p 8080:8080 \ + -v /path/to/data:/app/data \ + -e MH_SECRET="$(openssl rand -hex 32)" \ + -e MH_ADMIN_EMAIL="you@example.com" \ + -e MH_ADMIN_PASSWORD="changeme" \ + markdownhub +``` + +Open `http://your-host:8080` and log in with the admin credentials above. + +**Change your password immediately** in ⚙️ Preferences after first login. + +## Environment Variables + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `MH_SECRET` | **Yes** | `dev-secret-change-me` | JWT signing key. Generate with `openssl rand -hex 32` | +| `MH_ADMIN_EMAIL` | No | `admin@localhost` | Admin email (only used on first run) | +| `MH_ADMIN_PASSWORD` | No | `admin` | Admin password (only used on first run) | +| `MH_PORT` | No | `8080` | Internal port (change the `-p` mapping instead) | +| `MH_DATA_DIR` | No | `/app/data` | Data directory inside container | +| `MH_AI_ENDPOINT` | No | — | LiteLLM/OpenAI-compatible API URL for AI features | +| `MH_AI_API_KEY` | No | — | API key for AI endpoint | +| `MH_AI_MODEL` | No | `gpt-4` | Default model name | + +## Data Volume + +Mount a persistent volume to `/app/data`. This contains: + +``` +/app/data/ +├── db/ +│ └── markdownhub.db # SQLite database (users, permissions, jobs) +└── files/ + └── {user-id}/ # Each user's markdown files + git repo +``` + +## Reverse Proxy (HTTPS) + +Put behind nginx/Caddy/Traefik for HTTPS. Example nginx config: + +```nginx +server { + listen 443 ssl; + server_name md.example.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + # WebSocket for real-time collab + location /ws/ { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + } +} +``` + +## Synology NAS + +1. Install Docker from Package Center +2. SSH into your NAS or use Task Scheduler +3. Run the commands from Quick Install above +4. Use `/volume1/docker/markdownhub/data` as your data path + +For ARM-based Synology (e.g. DS124), build with: +```bash +docker build --platform linux/arm64 -t markdownhub . +``` + +## Updating + +```bash +cd markdown-hub +git pull +docker build -t markdownhub . +docker rm -f markdownhub +docker run -d \ + --name markdownhub \ + --restart unless-stopped \ + -p 8080:8080 \ + -v /path/to/data:/app/data \ + -e MH_SECRET="your-existing-secret" \ + markdownhub +``` + +Your data persists in the volume — only the app binary and frontend are replaced. + +## Backup + +```bash +# Stop (optional, for consistency) +docker stop markdownhub + +# Copy data +cp -r /path/to/data /path/to/backup/markdownhub-$(date +%Y%m%d) + +# Restart +docker start markdownhub +``` + +## Restore + +```bash +docker stop markdownhub +rm -rf /path/to/data +cp -r /path/to/backup/markdownhub-YYYYMMDD /path/to/data +docker start markdownhub +``` + +## Build Daemon (Optional) + +For the AI build pipeline, run the daemon on a machine with Pi installed: + +```bash +export MH_URL=https://md.example.com +export MH_DAEMON_TOKEN=your-api-token +export MH_WORKSPACE=~/builds +python3 daemon/build_daemon.py +``` + +Or run in screen/tmux: +```bash +screen -dmS mh-daemon python3 daemon/build_daemon.py +``` + +## CLI Tool (Optional) + +Build the `mdsync` CLI: + +```bash +cd markdown-hub +go build -o mdsync ./cmd/mdsync +sudo mv mdsync /usr/local/bin/ +``` + +Usage: +```bash +mdsync login https://md.example.com you@example.com yourpassword +mdsync pull . # Download all files to current directory +mdsync push . # Upload local .md files to server +mdsync status # Check git sync status +``` + +## Troubleshooting + +**Can't login**: Check `MH_SECRET` hasn't changed between restarts. If it has, existing tokens are invalid — just login again. + +**Port in use**: Change the host port: `-p 9090:8080` + +**Permission denied on data volume**: Ensure the directory is writable: `chmod 777 /path/to/data` + +**WebSocket not connecting (collab)**: Make sure your reverse proxy forwards `/ws/` with upgrade headers (see nginx example above).