- Add Dockerfile with AlmaLinux 9 base, Nginx reverse proxy, and PM2 - Support Node.js versions 18, 20, 22 with automated installation - Implement memory-optimized configuration (256MB minimum, 512MB recommended) - Add Memcached session storage for development environments - Create comprehensive documentation (README, USER-GUIDE, MEMORY-GUIDE, CLAUDE.md) - Include example applications (simple website and REST API) - Add Gitea CI/CD pipeline for automated multi-version builds - Provide local development script with helper utilities - Implement health monitoring, log rotation, and backup systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
229 lines
6.3 KiB
Markdown
229 lines
6.3 KiB
Markdown
# Memory Usage Guide - Cloud Node Container
|
|
|
|
## Memory Requirements & Recommendations
|
|
|
|
### Minimum RAM Requirements
|
|
|
|
| Configuration | Minimum RAM | Recommended RAM | Use Case |
|
|
|---------------|-------------|-----------------|----------|
|
|
| **Production (Basic)** | 256MB | 512MB | Simple websites, APIs with <100 concurrent users |
|
|
| **Production (Standard)** | 512MB | 1GB | Standard web applications, APIs with moderate traffic |
|
|
| **Development** | 512MB | 1GB | Local development with all services (Memcached, logging) |
|
|
| **High Traffic** | 1GB | 2GB+ | Applications with >500 concurrent users or heavy processing |
|
|
|
|
### Memory Breakdown (Optimized Configuration)
|
|
|
|
| Component | Memory Usage | Notes |
|
|
|-----------|--------------|-------|
|
|
| **Base AlmaLinux 9** | ~80-120MB | Minimal base system |
|
|
| **Node.js Runtime** | ~30-50MB | V8 JavaScript engine |
|
|
| **PM2 Process Manager** | ~15-25MB | Process monitoring and management |
|
|
| **Nginx (Optimized)** | ~8-15MB | Single worker, limited buffers |
|
|
| **User Application** | ~50-200MB | Depends on application complexity |
|
|
| **Memcached (DEV mode)** | ~10-15MB | 32MB memory limit, actual usage varies |
|
|
| **System Overhead** | ~30-50MB | Logging, cron, system processes |
|
|
|
|
**Total Typical Usage:** 220-480MB
|
|
|
|
## Memory Optimizations Applied
|
|
|
|
### Container-Level Optimizations
|
|
|
|
1. **Node.js Heap Limit**: Set to 200MB via `--max-old-space-size=200`
|
|
2. **PM2 Memory Restart**: Applications restart at 256MB usage
|
|
3. **Memcached Limit**: 32MB maximum cache size
|
|
4. **Nginx Workers**: Single worker process for memory efficiency
|
|
5. **Buffer Limits**: Reduced client buffer sizes
|
|
6. **Log Buffering**: 2-minute flush intervals to reduce I/O
|
|
|
|
### Application-Level Recommendations
|
|
|
|
```javascript
|
|
// Memory-efficient application practices
|
|
const express = require('express');
|
|
const app = express();
|
|
|
|
// Use compression to reduce memory for responses
|
|
app.use(require('compression')());
|
|
|
|
// Limit request size
|
|
app.use(express.json({ limit: '1mb' }));
|
|
app.use(express.urlencoded({ limit: '1mb', extended: true }));
|
|
|
|
// Stream large files instead of loading into memory
|
|
const fs = require('fs');
|
|
app.get('/large-file', (req, res) => {
|
|
const stream = fs.createReadStream('large-file.pdf');
|
|
stream.pipe(res);
|
|
});
|
|
```
|
|
|
|
## Memory Monitoring
|
|
|
|
### Built-in Monitoring Scripts
|
|
|
|
```bash
|
|
# Check current memory usage
|
|
docker exec container-name /scripts/memory-info.sh
|
|
|
|
# Monitor PM2 processes
|
|
docker exec container-name pm2 monit
|
|
|
|
# View memory usage over time
|
|
docker stats container-name
|
|
```
|
|
|
|
### Memory Alerts & Automatic Restarts
|
|
|
|
The container includes automatic memory management:
|
|
|
|
- **PM2 Restart**: Apps restart if they exceed 256MB
|
|
- **Health Checks**: Container monitors `/ping` endpoint
|
|
- **Process Recovery**: Failed processes automatically restart
|
|
- **Memory Leak Protection**: Regular restarts prevent memory buildup
|
|
|
|
## Scaling Guidelines
|
|
|
|
### When to Scale UP (More RAM):
|
|
|
|
- PM2 shows frequent memory restarts
|
|
- Response times increase significantly
|
|
- Multiple applications in one container
|
|
- Heavy data processing or file handling
|
|
- High concurrent user count (>200 simultaneous)
|
|
|
|
### When to Scale OUT (More Containers):
|
|
|
|
- CPU usage consistently >80%
|
|
- Memory usage consistently >80% of allocation
|
|
- Need for geographic distribution
|
|
- Fault tolerance requirements
|
|
|
|
### Memory-Efficient Application Patterns
|
|
|
|
**Good Practices:**
|
|
```javascript
|
|
// Stream processing instead of loading entire files
|
|
const stream = require('stream');
|
|
|
|
// Use connection pooling for databases
|
|
const mysql = require('mysql2');
|
|
const pool = mysql.createPool({
|
|
host: 'localhost',
|
|
user: 'user',
|
|
password: 'password',
|
|
database: 'db',
|
|
connectionLimit: 5, // Limit connections
|
|
acquireTimeout: 60000,
|
|
timeout: 60000
|
|
});
|
|
|
|
// Clean up intervals and timeouts
|
|
const cleanup = () => {
|
|
clearInterval(myInterval);
|
|
clearTimeout(myTimeout);
|
|
};
|
|
|
|
process.on('SIGTERM', cleanup);
|
|
process.on('SIGINT', cleanup);
|
|
```
|
|
|
|
**Avoid These Memory Patterns:**
|
|
```javascript
|
|
// DON'T: Store large amounts in memory
|
|
let globalCache = {}; // Can grow unbounded
|
|
|
|
// DON'T: Create memory leaks with closures
|
|
setInterval(() => {
|
|
const largeData = new Array(1000000).fill('data');
|
|
// largeData never gets garbage collected
|
|
}, 1000);
|
|
|
|
// DON'T: Load entire files into memory
|
|
const fs = require('fs');
|
|
const hugeFile = fs.readFileSync('huge-file.txt'); // Use streams instead
|
|
```
|
|
|
|
## Container Resource Limits
|
|
|
|
### Setting Memory Limits
|
|
|
|
```bash
|
|
# Limit container memory usage
|
|
docker run --memory=512m --memory-swap=512m your-container
|
|
|
|
# Or in docker-compose.yml
|
|
services:
|
|
node-app:
|
|
mem_limit: 512m
|
|
memswap_limit: 512m
|
|
```
|
|
|
|
### Monitoring Memory Usage
|
|
|
|
```bash
|
|
# Real-time memory stats
|
|
docker exec container-name cat /proc/meminfo
|
|
|
|
# Process-specific memory
|
|
docker exec container-name ps aux --sort=-%mem
|
|
|
|
# Application memory usage
|
|
docker exec container-name pm2 show app-name
|
|
```
|
|
|
|
## Troubleshooting Memory Issues
|
|
|
|
### Common Memory Problems
|
|
|
|
1. **Container OOM (Out of Memory)**
|
|
- **Symptom**: Container suddenly stops
|
|
- **Solution**: Increase container memory or optimize application
|
|
|
|
2. **Application Memory Leaks**
|
|
- **Symptom**: Memory usage steadily increases
|
|
- **Solution**: Use PM2 memory restart feature, fix code leaks
|
|
|
|
3. **Slow Performance**
|
|
- **Symptom**: High response times, high memory usage
|
|
- **Solution**: Enable compression, optimize database queries
|
|
|
|
### Memory Debugging Tools
|
|
|
|
```bash
|
|
# Inside container - check memory usage
|
|
free -h
|
|
cat /proc/meminfo
|
|
ps aux --sort=-%mem
|
|
|
|
# PM2 memory monitoring
|
|
pm2 monit
|
|
pm2 show app-name
|
|
|
|
# Node.js heap snapshots (development)
|
|
# Add to your app:
|
|
const v8 = require('v8');
|
|
const fs = require('fs');
|
|
const heapSnapshot = v8.writeHeapSnapshot();
|
|
console.log('Heap snapshot written to', heapSnapshot);
|
|
```
|
|
|
|
## Production Memory Recommendations
|
|
|
|
### Small Applications (< 50 concurrent users)
|
|
- **Container RAM**: 512MB
|
|
- **Node.js Heap**: 200MB (default)
|
|
- **Expected Usage**: 250-350MB
|
|
|
|
### Medium Applications (50-200 concurrent users)
|
|
- **Container RAM**: 1GB
|
|
- **Node.js Heap**: 400MB (`--max-old-space-size=400`)
|
|
- **Expected Usage**: 500-700MB
|
|
|
|
### Large Applications (200+ concurrent users)
|
|
- **Container RAM**: 2GB+
|
|
- **Node.js Heap**: 800MB+ (`--max-old-space-size=800`)
|
|
- **Expected Usage**: 1-1.5GB
|
|
- **Consider**: Multiple container instances with load balancing
|
|
|
|
The container is optimized for efficient memory usage while maintaining good performance and reliability. |