552 líneas
10 KiB
Markdown
552 líneas
10 KiB
Markdown
# Deployment Guide
|
|
|
|
This guide covers deploying the Hasher application to production.
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 18.x or higher
|
|
- Redis 6.x or higher
|
|
- Domain name (optional, for custom domain)
|
|
- SSL certificate (recommended for production)
|
|
|
|
## Deployment Options
|
|
|
|
### Option 1: Vercel (Recommended for Next.js)
|
|
|
|
Vercel provides seamless deployment for Next.js applications.
|
|
|
|
#### Steps:
|
|
|
|
1. **Install Vercel CLI**:
|
|
```bash
|
|
npm install -g vercel
|
|
```
|
|
|
|
2. **Login to Vercel**:
|
|
```bash
|
|
vercel login
|
|
```
|
|
|
|
3. **Deploy**:
|
|
```bash
|
|
vercel
|
|
```
|
|
|
|
4. **Set Environment Variables**:
|
|
- Go to your project settings on Vercel
|
|
- Add environment variables:
|
|
- `REDIS_HOST=your-redis-host.com`
|
|
- `REDIS_PORT=6379`
|
|
- `REDIS_PASSWORD=your-secure-password` (if using authentication)
|
|
- Redeploy: `vercel --prod`
|
|
|
|
#### Important Notes:
|
|
- Ensure Redis is accessible from Vercel's servers
|
|
- Consider using [Upstash](https://upstash.com) or [Redis Cloud](https://redis.com/try-free/) for managed Redis
|
|
- Use environment variables for sensitive configuration
|
|
|
|
---
|
|
|
|
### Option 2: Docker
|
|
|
|
Deploy using Docker containers.
|
|
|
|
#### Create Dockerfile:
|
|
|
|
```dockerfile
|
|
# Create this file: Dockerfile
|
|
FROM node:18-alpine AS base
|
|
|
|
# Install dependencies only when needed
|
|
FROM base AS deps
|
|
RUN apk add --no-cache libc6-compat
|
|
WORKDIR /app
|
|
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm ci
|
|
|
|
# Rebuild the source code only when needed
|
|
FROM base AS builder
|
|
WORKDIR /app
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY . .
|
|
|
|
RUN npm run build
|
|
|
|
# Production image, copy all the files and run next
|
|
FROM base AS runner
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV production
|
|
|
|
RUN addgroup --system --gid 1001 nodejs
|
|
RUN adduser --system --uid 1001 nextjs
|
|
|
|
COPY --from=builder /app/public ./public
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
|
|
USER nextjs
|
|
|
|
EXPOSE 3000
|
|
|
|
ENV PORT 3000
|
|
|
|
CMD ["node", "server.js"]
|
|
```
|
|
|
|
#### Build and Run:
|
|
|
|
```bash
|
|
# Build the Docker image
|
|
docker build -t hasher:latest .
|
|
|
|
# Run the container
|
|
docker run -d \
|
|
-p 3000:3000 \
|
|
-e REDIS_HOST=redis \
|
|
-e REDIS_PORT=6379 \
|
|
-e REDIS_PASSWORD=your-password \
|
|
--name hasher \
|
|
hasher:latest
|
|
```
|
|
|
|
#### Docker Compose:
|
|
|
|
Create `docker-compose.yml`:
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
app:
|
|
build: .
|
|
ports:
|
|
- "3000:3000"
|
|
environment:
|
|
- REDIS_HOST=redis
|
|
- REDIS_PORT=6379
|
|
- REDIS_PASSWORD=your-secure-password
|
|
depends_on:
|
|
- redis
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
command: redis-server --requirepass your-secure-password --appendonly yes
|
|
ports:
|
|
- "6379:6379"
|
|
volumes:
|
|
- redis-data:/data
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
redis-data:
|
|
```
|
|
|
|
Run with:
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
---
|
|
|
|
### Option 3: Traditional VPS (Ubuntu/Debian)
|
|
|
|
Deploy to a traditional server.
|
|
|
|
#### 1. Install Node.js:
|
|
|
|
```bash
|
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
|
sudo apt-get install -y nodejs
|
|
```
|
|
|
|
#### 2. Install Redis:
|
|
|
|
```bash
|
|
sudo apt-get update
|
|
sudo apt-get install redis-server
|
|
|
|
# Configure Redis
|
|
sudo nano /etc/redis/redis.conf
|
|
# Set: requirepass your-strong-password
|
|
|
|
# Start Redis
|
|
sudo systemctl start redis-server
|
|
sudo systemctl enable redis-server
|
|
```
|
|
|
|
#### 3. Install PM2 (Process Manager):
|
|
|
|
```bash
|
|
sudo npm install -g pm2
|
|
```
|
|
|
|
#### 4. Clone and Build:
|
|
|
|
```bash
|
|
cd /var/www
|
|
git clone <your-repo-url> hasher
|
|
cd hasher
|
|
npm install
|
|
npm run build
|
|
```
|
|
|
|
#### 5. Configure Environment:
|
|
|
|
```bash
|
|
cat > .env.local << EOF
|
|
REDIS_HOST=localhost
|
|
REDIS_PORT=6379
|
|
REDIS_PASSWORD=your-strong-password
|
|
NODE_ENV=production
|
|
EOF
|
|
```
|
|
|
|
#### 6. Start with PM2:
|
|
|
|
```bash
|
|
pm2 start npm --name "hasher" -- start
|
|
pm2 save
|
|
pm2 startup
|
|
```
|
|
|
|
#### 7. Configure Nginx (Optional):
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name your-domain.com;
|
|
|
|
location / {
|
|
proxy_pass http://localhost:3000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
}
|
|
```
|
|
|
|
Enable the site:
|
|
```bash
|
|
sudo ln -s /etc/nginx/sites-available/hasher /etc/nginx/sites-enabled/
|
|
sudo nginx -t
|
|
sudo systemctl reload nginx
|
|
```
|
|
|
|
---
|
|
|
|
## Redis Setup
|
|
|
|
### Option 1: Managed Redis (Recommended)
|
|
|
|
#### Upstash (Serverless Redis)
|
|
1. Sign up at [Upstash](https://upstash.com)
|
|
2. Create a database
|
|
3. Copy connection details
|
|
4. Update environment variables
|
|
|
|
#### Redis Cloud
|
|
1. Sign up at [Redis Cloud](https://redis.com/try-free/)
|
|
2. Create a database
|
|
3. Note the endpoint and password
|
|
4. Update `REDIS_HOST`, `REDIS_PORT`, and `REDIS_PASSWORD`
|
|
|
|
### Option 2: Self-Hosted Redis
|
|
|
|
```bash
|
|
# Ubuntu/Debian
|
|
sudo apt-get update
|
|
sudo apt-get install redis-server
|
|
|
|
# Configure Redis security
|
|
sudo nano /etc/redis/redis.conf
|
|
|
|
# Important settings:
|
|
# bind 127.0.0.1 ::1 # Only local connections (remove for remote)
|
|
# requirepass your-strong-password
|
|
# maxmemory 256mb
|
|
# maxmemory-policy allkeys-lru
|
|
|
|
# Start Redis
|
|
sudo systemctl start redis-server
|
|
sudo systemctl enable redis-server
|
|
|
|
# Test connection
|
|
redis-cli -a your-strong-password ping
|
|
```
|
|
|
|
---
|
|
|
|
## Security Considerations
|
|
|
|
### 1. Redis Security
|
|
|
|
- **Always** use a strong password with `requirepass`
|
|
- Bind Redis to localhost if possible (`bind 127.0.0.1`)
|
|
- Use TLS/SSL for remote connections (Redis 6+)
|
|
- Disable dangerous commands:
|
|
```
|
|
rename-command FLUSHDB ""
|
|
rename-command FLUSHALL ""
|
|
rename-command CONFIG ""
|
|
```
|
|
- Set memory limits to prevent OOM
|
|
|
|
### 2. Application Security
|
|
|
|
- Use environment variables for secrets
|
|
- Enable HTTPS (SSL/TLS)
|
|
- Implement rate limiting
|
|
- Add CORS restrictions
|
|
- Monitor logs for suspicious activity
|
|
|
|
### 3. Network Security
|
|
|
|
```bash
|
|
# Example UFW firewall rules
|
|
sudo ufw allow 80/tcp
|
|
sudo ufw allow 443/tcp
|
|
sudo ufw allow from YOUR_IP to any port 6379 # Redis (if remote)
|
|
sudo ufw enable
|
|
```
|
|
|
|
---
|
|
|
|
## Monitoring
|
|
|
|
### Application Monitoring
|
|
|
|
```bash
|
|
# PM2 monitoring
|
|
pm2 monit
|
|
|
|
# View logs
|
|
pm2 logs hasher
|
|
```
|
|
|
|
### Redis Monitoring
|
|
|
|
```bash
|
|
# Test connection
|
|
redis-cli ping
|
|
|
|
# Get server info
|
|
redis-cli INFO
|
|
|
|
# Monitor commands
|
|
redis-cli MONITOR
|
|
|
|
# Check memory usage
|
|
redis-cli INFO memory
|
|
|
|
# Check stats
|
|
redis-cli INFO stats
|
|
```
|
|
|
|
---
|
|
|
|
## Backup and Recovery
|
|
|
|
### Redis Persistence
|
|
|
|
Redis offers two persistence options:
|
|
|
|
#### RDB (Redis Database Backup)
|
|
```bash
|
|
# Configure in redis.conf
|
|
save 900 1 # Save if 1 key changed in 15 minutes
|
|
save 300 10 # Save if 10 keys changed in 5 minutes
|
|
save 60 10000 # Save if 10000 keys changed in 1 minute
|
|
|
|
# Manual snapshot
|
|
redis-cli SAVE
|
|
|
|
# Backup file location
|
|
/var/lib/redis/dump.rdb
|
|
```
|
|
|
|
#### AOF (Append Only File)
|
|
```bash
|
|
# Enable in redis.conf
|
|
appendonly yes
|
|
appendfilename "appendonly.aof"
|
|
|
|
# Sync options
|
|
appendfsync everysec # Good balance
|
|
|
|
# Backup file location
|
|
/var/lib/redis/appendonly.aof
|
|
```
|
|
|
|
### Backup Script
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# backup-redis.sh
|
|
|
|
BACKUP_DIR="/backup/redis"
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|
|
|
# Create backup directory
|
|
mkdir -p $BACKUP_DIR
|
|
|
|
# Trigger Redis save
|
|
redis-cli -a your-password SAVE
|
|
|
|
# Copy RDB file
|
|
cp /var/lib/redis/dump.rdb $BACKUP_DIR/dump_$DATE.rdb
|
|
|
|
# Keep only last 7 days
|
|
find $BACKUP_DIR -name "dump_*.rdb" -mtime +7 -delete
|
|
|
|
echo "Backup completed: dump_$DATE.rdb"
|
|
```
|
|
|
|
### Restore from Backup
|
|
|
|
```bash
|
|
# Stop Redis
|
|
sudo systemctl stop redis-server
|
|
|
|
# Replace dump file
|
|
sudo cp /backup/redis/dump_YYYYMMDD_HHMMSS.rdb /var/lib/redis/dump.rdb
|
|
sudo chown redis:redis /var/lib/redis/dump.rdb
|
|
|
|
# Start Redis
|
|
sudo systemctl start redis-server
|
|
```
|
|
|
|
---
|
|
|
|
## Scaling
|
|
|
|
### Horizontal Scaling
|
|
|
|
1. Deploy multiple Next.js instances
|
|
2. Use a load balancer (nginx, HAProxy, Cloudflare)
|
|
3. Share the same Redis instance
|
|
|
|
### Redis Scaling Options
|
|
|
|
#### 1. Redis Cluster
|
|
- Automatic sharding across multiple nodes
|
|
- High availability with automatic failover
|
|
- Good for very large datasets
|
|
|
|
#### 2. Redis Sentinel
|
|
- High availability without sharding
|
|
- Automatic failover
|
|
- Monitoring and notifications
|
|
|
|
#### 3. Read Replicas
|
|
- Separate read and write operations
|
|
- Scale read capacity
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Check Application Status
|
|
|
|
```bash
|
|
pm2 status
|
|
pm2 logs hasher --lines 100
|
|
```
|
|
|
|
### Check Redis
|
|
|
|
```bash
|
|
# Test connection
|
|
redis-cli ping
|
|
|
|
# Check memory
|
|
redis-cli INFO memory
|
|
|
|
# Count keys
|
|
redis-cli DBSIZE
|
|
|
|
# Get stats
|
|
redis-cli INFO stats
|
|
```
|
|
|
|
### Common Issues
|
|
|
|
**Issue**: Cannot connect to Redis
|
|
- Check if Redis is running: `sudo systemctl status redis-server`
|
|
- Verify firewall rules
|
|
- Check `REDIS_HOST` and `REDIS_PORT` environment variables
|
|
- Verify password is correct
|
|
|
|
**Issue**: Out of memory
|
|
- Increase Node.js memory: `NODE_OPTIONS=--max-old-space-size=4096`
|
|
- Configure Redis maxmemory
|
|
- Set appropriate eviction policy
|
|
|
|
**Issue**: Slow searches
|
|
- Check Redis memory usage
|
|
- Verify O(1) key lookups are being used
|
|
- Monitor Redis with `redis-cli MONITOR`
|
|
- Consider Redis Cluster for very large datasets
|
|
|
|
---
|
|
|
|
## Performance Optimization
|
|
|
|
1. **Enable Next.js Static Optimization**
|
|
2. **Use CDN for static assets**
|
|
3. **Configure Redis pipelining** (already implemented)
|
|
4. **Set appropriate maxmemory and eviction policy**
|
|
5. **Use SSD storage for Redis persistence**
|
|
6. **Enable connection pooling** (already implemented)
|
|
7. **Monitor and optimize Redis memory usage**
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Description | Default | Required |
|
|
|----------|-------------|---------|----------|
|
|
| `REDIS_HOST` | Redis server hostname | `localhost` | No |
|
|
| `REDIS_PORT` | Redis server port | `6379` | No |
|
|
| `REDIS_PASSWORD` | Redis authentication password | - | No* |
|
|
| `NODE_ENV` | Node environment | `development` | No |
|
|
| `PORT` | Application port | `3000` | No |
|
|
|
|
*Required if Redis has authentication enabled
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
For deployment issues, check:
|
|
- [Next.js Deployment Docs](https://nextjs.org/docs/deployment)
|
|
- [Redis Documentation](https://redis.io/docs/)
|
|
- [Upstash Documentation](https://docs.upstash.com/)
|
|
- Project GitHub Issues
|
|
|
|
---
|
|
|
|
## Deployment Checklist
|
|
|
|
Before going live:
|
|
|
|
- [ ] Redis is secured with password
|
|
- [ ] Environment variables are configured
|
|
- [ ] SSL/TLS certificates are installed
|
|
- [ ] Firewall rules are configured
|
|
- [ ] Monitoring is set up
|
|
- [ ] Backup strategy is in place
|
|
- [ ] Load testing completed
|
|
- [ ] Error logging configured
|
|
- [ ] Redis persistence (RDB/AOF) configured
|
|
- [ ] Rate limiting implemented (if needed)
|
|
- [ ] Documentation is up to date
|
|
|
|
---
|
|
|
|
**Ready to deploy! 🚀**
|