7.2 KiB
MinIO Setup Technical Specification
Project Status
Starting MinIO integration from scratch. Previous implementation had compatibility issues with bucket policies in SNSD mode. New implementation uses SNMD (Single Node Multi Drive) configuration with presigned URLs for reliable file access.
Architecture Overview
Storage Strategy
- Mode: SNMD (4 virtual drives) for full S3 compatibility
- Access Method: Presigned URLs only (no bucket policies)
- Bucket Structure: Single bucket
banatiewith path-based organization - File Organization:
orgId/projectId/category/year-month/filename
Technology Stack
- MinIO latest (
quay.io/minio/minio:latest) - Docker Compose for orchestration
- PostgreSQL for application data
- Express.js API with TypeScript
Configuration Files Status
Completed Files
docker-compose.yml- SNMD configuration with 4 virtual drives.env.docker- Environment variables for developmentsrc/services/MinioStorageService.ts- Updated service implementationsrc/services/StorageFactory.ts- Service factory configurationsrc/routes/images.ts- Presigned URL endpoints
Integration Requirements
1. Update Application Router
Add images router to main application in src/app.ts:
import { imagesRouter } from './routes/images';
// Add to routes section
app.use('/api', imagesRouter);
2. Environment Variables Update
Update existing .env file with MinIO configuration:
# Add to existing .env file
MINIO_ROOT_USER=banatie_admin
MINIO_ROOT_PASSWORD=banatie_storage_secure_key_2024
STORAGE_TYPE=minio
MINIO_ENDPOINT=minio:9000
MINIO_ACCESS_KEY=banatie_service
MINIO_SECRET_KEY=banatie_service_key_2024
MINIO_USE_SSL=false
MINIO_BUCKET_NAME=banatie
MINIO_PUBLIC_URL=http://localhost:9000
API_BASE_URL=http://localhost:3000
DEFAULT_ORG_ID=default
DEFAULT_PROJECT_ID=main
DEFAULT_USER_ID=system
PRESIGNED_URL_EXPIRY=86400
3. Database Script Update
Update scripts/init-db.sql to use new database name banatie instead of previous naming.
4. Service Dependencies Update
Update existing image generation services to use new storage configuration:
// In ImageGenService.ts or similar
const storageService = StorageFactory.getInstance();
const uploadResult = await storageService.uploadFile(
orgId,
projectId,
'generated',
filename,
buffer,
'image/png',
);
// Use uploadResult.url (returns API URL for presigned access)
Setup Instructions
1. Directory Structure
Create required directories:
mkdir -p data/storage/{drive1,drive2,drive3,drive4}
mkdir -p data/postgres
2. Service Startup
# Start all services
docker-compose up -d
# Verify services are healthy
docker-compose ps
# Check MinIO logs
docker logs banatie-storage
# Check initialization logs
docker logs banatie-storage-init
3. Verification Steps
MinIO Console Access
- URL: http://localhost:9001
- Username: banatie_admin
- Password: banatie_storage_secure_key_2024
Test Presigned URL Generation
# Test image upload endpoint
curl -X POST http://localhost:3000/api/upload \
-F "files=@test.png" \
-F "category=generated"
# Test presigned URL access
curl -I "http://localhost:3000/api/images/default/main/generated/test-image.png"
# Should return 302 redirect to presigned URL
Verify SNMD Mode
# Check MinIO is in erasure coding mode
docker exec banatie-storage mc admin info local
# Should show 4 drives and erasure coding information
Integration Testing
Required Tests
-
Storage Service Initialization
- Verify StorageFactory creates MinioStorageService
- Confirm bucket creation and accessibility
-
File Upload/Download Cycle
- Upload file via StorageService
- Generate presigned URL
- Verify file accessibility via presigned URL
-
API Endpoint Testing
- Test
/api/images/:orgId/:projectId/:category/:filename - Verify 302 redirect to presigned URL
- Test fallback direct streaming
- Test
-
Error Handling
- Test invalid file paths
- Test expired presigned URLs
- Test MinIO connection failures
Test Script Template
#!/bin/bash
# test-minio-integration.sh
echo "Testing MinIO Integration"
# Test 1: Upload file
UPLOAD_RESPONSE=$(curl -s -X POST http://localhost:3000/api/upload \
-F "files=@test.png" \
-F "category=generated")
echo "Upload Response: $UPLOAD_RESPONSE"
# Extract URL from response
FILE_URL=$(echo "$UPLOAD_RESPONSE" | jq -r '.files[0].url')
# Test 2: Access via presigned URL
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$FILE_URL")
if [ "$HTTP_CODE" = "302" ]; then
echo "SUCCESS: Presigned URL redirect working"
else
echo "FAILURE: Expected 302, got $HTTP_CODE"
fi
Production Considerations
Environment Differences
Development and production use identical configuration with different values:
# Production .env differences
API_BASE_URL=https://api.yourdomain.com
MINIO_PUBLIC_URL=https://storage.yourdomain.com:9000
MINIO_USE_SSL=true
Security Notes
- All passwords use environment variables (no hardcoded values)
- Presigned URLs expire after 24 hours by default
- Service user has minimal required permissions
- MinIO admin access separate from application access
Scaling Path
- Current SNMD setup supports development and small production loads
- Can migrate to distributed MinIO cluster when needed
- Presigned URL architecture remains unchanged during scaling
Troubleshooting
Common Issues
- 403 Errors: Check presigned URL generation and MinIO service user permissions
- 404 Errors: Verify file paths and bucket configuration
- Connection Errors: Confirm MinIO service health and network connectivity
Debug Commands
# Check MinIO health
docker exec banatie-storage mc admin info local
# List bucket contents
docker exec banatie-storage mc ls storage/banatie --recursive
# Check service logs
docker logs banatie-storage
docker logs banatie-app
Recovery Procedures
# Reset MinIO data (development only)
docker-compose down
rm -rf data/storage/*
docker-compose up -d
# Recreate bucket structure
docker exec banatie-storage mc mb storage/banatie
Implementation Priority
Phase 1 (Immediate)
- Update app.ts with images router
- Update environment configuration
- Test basic upload/download functionality
Phase 2 (Next)
- Update existing image generation services
- Implement comprehensive error handling
- Add integration tests
Phase 3 (Future)
- Add monitoring and logging
- Implement file cleanup policies
- Add CDN integration capability
Acceptance Criteria
Integration is complete when:
- All services start successfully via docker-compose
- MinIO operates in SNMD mode with 4 drives
- Image upload returns API URL format
- API URLs redirect to working presigned URLs
- Generated images accessible via presigned URLs
- Error handling provides meaningful responses
- Integration tests pass consistently
Notes
This implementation prioritizes simplicity and reliability over advanced features. The presigned URL approach ensures consistent behavior across different MinIO configurations and provides a foundation for future enhancements without requiring architectural changes.