- Add Express.js backend with REST API - Implement comprehensive security measures (helmet, rate limiting, input validation) - Add Docker volume support for persistent JSON storage - Update container security (non-root user, minimal Alpine) - Add deployment and security documentation - Configure production-ready Docker setup with Coolify compatibility 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
174 lines
4.2 KiB
Markdown
174 lines
4.2 KiB
Markdown
# Docker Volume JSON Storage Deployment Guide
|
|
|
|
The Reading Tracker app now supports persistent JSON storage using Docker volumes, enabling multi-device access and data persistence across container restarts.
|
|
|
|
## Architecture Overview
|
|
|
|
The application now consists of:
|
|
- **Frontend**: React SPA (served by Express in production)
|
|
- **Backend**: Express.js server with API endpoints
|
|
- **Storage**: JSON files in Docker volume (`/app/data`)
|
|
- **Fallback**: localStorage for offline/server unavailable scenarios
|
|
|
|
## Docker Deployment
|
|
|
|
### Quick Start with Docker Compose
|
|
|
|
```bash
|
|
# Build and start the application
|
|
docker-compose up -d
|
|
|
|
# The app will be available at http://localhost:8080
|
|
```
|
|
|
|
### Manual Docker Commands
|
|
|
|
```bash
|
|
# Build the image
|
|
docker build -t reading-tracker:latest .
|
|
|
|
# Run with persistent storage
|
|
docker run -d \
|
|
--name reading-tracker \
|
|
-p 8080:80 \
|
|
-v reading-data:/app/data \
|
|
--restart unless-stopped \
|
|
reading-tracker:latest
|
|
```
|
|
|
|
### For Coolify or Similar Platforms
|
|
|
|
Use these settings:
|
|
- **Port**: 80 (internal), map to your desired external port
|
|
- **Volume Mount**: `/app/data` (for JSON storage)
|
|
- **Health Check**: `GET /api/health`
|
|
- **Environment Variables**:
|
|
- `NODE_ENV=production`
|
|
- `DATA_DIR=/app/data` (optional, defaults to `/app/data`)
|
|
- `ALLOWED_ORIGINS=https://your-domain.com` (comma-separated for production CORS)
|
|
|
|
## API Endpoints
|
|
|
|
- `GET /api/books` - Load all books from JSON storage
|
|
- `POST /api/books` - Save books array to JSON storage
|
|
- `GET /api/health` - Health check endpoint
|
|
|
|
## Data Storage Details
|
|
|
|
### File Location
|
|
- **Production**: `/app/data/books.json` (Docker volume)
|
|
- **Development**: `./data/books.json` (local directory)
|
|
|
|
### JSON Format
|
|
```json
|
|
{
|
|
"books": [
|
|
{
|
|
"id": 1,
|
|
"title": "Book Title",
|
|
"author": "Author Name",
|
|
"totalPages": 300,
|
|
"currentPage": 150,
|
|
"startDate": "2025-01-01",
|
|
"targetDate": "2025-02-01",
|
|
"readingHistory": {
|
|
"2025-01-01": 10,
|
|
"2025-01-02": 25
|
|
},
|
|
"createdAt": "2025-01-01T00:00:00.000Z"
|
|
}
|
|
],
|
|
"lastModified": "2025-08-17T21:46:52.274Z",
|
|
"version": "1.0"
|
|
}
|
|
```
|
|
|
|
### Security Features
|
|
- **Security Headers**: Helmet.js with CSP, anti-clickjacking, MIME protection
|
|
- **Rate Limiting**: 100 req/15min general, 20 req/15min for saves
|
|
- **Input Validation**: String limits, numeric bounds, date format validation
|
|
- **CORS Protection**: Configurable origins for production
|
|
- **Error Disclosure Prevention**: Generic error messages, sanitized logs
|
|
- **Container Security**: Non-root user, minimal Alpine base image
|
|
|
|
📋 **See [SECURITY.md](./SECURITY.md) for complete security documentation**
|
|
|
|
## Fallback Behavior
|
|
|
|
The app gracefully handles server unavailability:
|
|
|
|
1. **Load Priority**: Server JSON → localStorage fallback
|
|
2. **Save Priority**: Server JSON → localStorage backup
|
|
3. **Offline Mode**: Continues working with localStorage
|
|
4. **Auto-Recovery**: Syncs with server when available
|
|
|
|
## Development
|
|
|
|
### Local Development
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Start both frontend and backend
|
|
npm run dev
|
|
|
|
# Frontend: http://localhost:5173
|
|
# Backend: http://localhost:3001
|
|
```
|
|
|
|
### Backend Only
|
|
```bash
|
|
npm run server
|
|
```
|
|
|
|
## Volume Management
|
|
|
|
### Backup Data
|
|
```bash
|
|
# Create backup
|
|
docker cp reading-tracker:/app/data/books.json ./backup-books.json
|
|
|
|
# Restore backup
|
|
docker cp ./backup-books.json reading-tracker:/app/data/books.json
|
|
```
|
|
|
|
### View Volume Contents
|
|
```bash
|
|
# List volume contents
|
|
docker exec reading-tracker ls -la /app/data
|
|
|
|
# View current data
|
|
docker exec reading-tracker cat /app/data/books.json
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Health Check
|
|
```bash
|
|
curl http://localhost:8080/api/health
|
|
```
|
|
|
|
### Check Logs
|
|
```bash
|
|
docker logs reading-tracker
|
|
```
|
|
|
|
### Volume Issues
|
|
```bash
|
|
# Verify volume mount
|
|
docker inspect reading-tracker | grep -A 10 "Mounts"
|
|
|
|
# Recreate volume if needed
|
|
docker volume rm reading-data
|
|
docker-compose up -d
|
|
```
|
|
|
|
## Migration from localStorage
|
|
|
|
When first deploying, the app will:
|
|
1. Try to load from server (empty initially)
|
|
2. Fall back to localStorage if available
|
|
3. Save localStorage data to server on first interaction
|
|
4. Continue using server storage for all subsequent operations
|
|
|
|
No manual migration needed - the fallback system handles it automatically! |