Update project docs and problem notes

This commit is contained in:
2026-04-29 09:38:47 -04:00
parent d371c3c602
commit e319a5d092
13 changed files with 1507 additions and 53 deletions

View File

@@ -0,0 +1,272 @@
# Deployment Guide
## Requirements
- Docker 24.0+
- Docker Compose 2.20+
- 1GB RAM minimum (2GB recommended)
- 10GB disk space
- TLS certificate (Let's Encrypt or custom)
## Quick Start
```bash
# Clone repository
git clone https://github.com/your-org/md-hub-secure.git
cd md-hub-secure
# Copy and edit configuration
cp .env.example .env
# Edit .env with your domain, email, Postmark API key
# Start services
docker-compose up -d
# Verify health
curl https://your-domain.com/health
```
## Configuration
### Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DOMAIN` | Yes | — | Public domain name |
| `DB_PATH` | No | `/data/db.sqlite` | Database file path |
| `FILESTORE_PATH` | No | `/data/files` | Content-addressed file storage |
| `NOTES_PATH` | No | `/notes` | Watched markdown directory |
| `POSTMARK_API_KEY` | Yes | — | Postmark server API token |
| `POSTMARK_FROM` | No | `notifications@DOMAIN` | From email address |
| `SESSION_SECRET` | Yes | — | 32-byte hex for session signing |
| `ENV` | No | `production` | `development` or `production` |
### Docker Compose
```yaml
version: "3.8"
services:
app:
build: .
ports:
- "8080:8080"
volumes:
- ./data:/data
- ./notes:/notes:ro
environment:
- DOMAIN=${DOMAIN}
- DB_PATH=/data/db.sqlite
- FILESTORE_PATH=/data/files
- NOTES_PATH=/notes
- POSTMARK_API_KEY=${POSTMARK_API_KEY}
- SESSION_SECRET=${SESSION_SECRET}
env_file:
- .env
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:noexec,nosuid,size=100m
# Optional: Traefik for auto-HTTPS
traefik:
image: traefik:v3.0
command:
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=${EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
restart: unless-stopped
```
## Production Checklist
### Pre-Deployment
- [ ] Change default `SESSION_SECRET` (generate: `openssl rand -hex 32`)
- [ ] Configure `POSTMARK_API_KEY` with valid token
- [ ] Set `DOMAIN` to public hostname
- [ ] Configure DNS A/AAAA records
- [ ] Set up SPF and DKIM for email domain
- [ ] Review `.env` file — no default secrets
### Security
- [ ] TLS 1.3 enforced (Traefik or reverse proxy)
- [ ] HSTS header configured
- [ ] Firewall rules: only 80/443 open
- [ ] Fail2ban or rate limiting on SSH
- [ ] Automatic security updates enabled
- [ ] Backup encryption key stored securely
### Monitoring
- [ ] Health check endpoint accessible
- [ ] Log rotation configured
- [ ] Disk space alerting (>80%)
- [ ] Memory usage alerting
- [ ] Uptime monitoring (external)
## Backup Procedures
### Automated Backup
```bash
#!/bin/bash
# backup.sh
BACKUP_DIR="/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/md-hub-$TIMESTAMP.tar.gz"
# Create backup
tar czf "$BACKUP_FILE" \
-C /data \
db.sqlite \
files/
# Encrypt (optional)
gpg --symmetric --cipher-algo AES256 "$BACKUP_FILE"
rm "$BACKUP_FILE"
# Keep only last 30 days
find "$BACKUP_DIR" -name "md-hub-*.tar.gz.gpg" -mtime +30 -delete
```
**Cron**: `0 2 * * * /opt/md-hub-secure/backup.sh`
### Restore from Backup
```bash
# Stop application
docker-compose stop app
# Extract backup
tar xzf md-hub-20240115_020000.tar.gz -C /data
# Restart
docker-compose up -d app
# Verify
curl https://your-domain.com/health
```
## Upgrade Procedures
### Minor Update (patch version)
```bash
docker-compose pull
docker-compose up -d
```
### Major Update
1. Read release notes for breaking changes
2. Create backup: `./backup.sh`
3. Pull new image: `docker-compose pull`
4. Run database migrations (auto on startup)
5. Update configuration if needed
6. Deploy: `docker-compose up -d`
7. Verify health and functionality
8. Rollback if issues: restore from backup
## Troubleshooting
### Application Won't Start
```bash
# Check logs
docker-compose logs -f app
# Verify configuration
docker-compose exec app /server -check-config
# Test database
docker-compose exec app sqlite3 /data/db.sqlite ".tables"
```
### Sync Not Working
```bash
# Check file watcher
docker-compose exec app ls -la /notes
# Verify WebSocket
curl -i -N \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
-H "Sec-WebSocket-Version: 13" \
https://your-domain.com/ws
```
### Email Not Sending
```bash
# Test Postmark connection
curl -X POST \
https://api.postmarkapp.com/server \
-H "X-Postmark-Server-Token: YOUR_TOKEN" \
-H "Accept: application/json"
# Check email queue
docker-compose exec app sqlite3 /data/db.sqlite \
"SELECT * FROM email_queue WHERE status='failed'"
```
## Scaling
### Vertical Scaling
- Increase container memory/CPU limits
- SQLite WAL mode handles concurrent reads well
- For heavy write loads, consider libsql replication
### Horizontal Scaling (Advanced)
```yaml
# Requires shared storage and load balancer
services:
app1:
# ... same config ...
environment:
- DB_PATH=/shared/db.sqlite
- FILESTORE_PATH=/shared/files
app2:
# ... same config ...
environment:
- DB_PATH=/shared/db.sqlite
- FILESTORE_PATH=/shared/files
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
```
**Note**: Horizontal scaling requires:
- Shared filesystem (NFS, EFS)
- libsql replication or external database
- Sticky sessions for WebSocket
## Support
- **Documentation**: `/docs` route (when authenticated)
- **Health Check**: `GET /health`
- **Metrics**: `GET /metrics` (Prometheus format)
- **Logs**: `docker-compose logs -f app`
- **Issues**: https://github.com/your-org/md-hub-secure/issues