412 lines
8.2 KiB
Markdown
412 lines
8.2 KiB
Markdown
# Production Deployment Guide
|
|
|
|
## 🚀 Production-Ready Features
|
|
|
|
This project is now production-ready with:
|
|
|
|
- ✅ **Security**: Helmet, CORS, rate limiting, input validation
|
|
- ✅ **Logging**: Structured logging with privacy protection
|
|
- ✅ **Error Handling**: Comprehensive error handling and recovery
|
|
- ✅ **Environment Config**: Secure environment variable management
|
|
- ✅ **Validation**: Zod schema validation for all inputs
|
|
- ✅ **Monitoring**: Health checks and request logging
|
|
- ✅ **Performance**: Rate limiting and request size limits
|
|
|
|
## 📋 Pre-Deployment Checklist
|
|
|
|
### 1. Environment Setup
|
|
```bash
|
|
# Copy environment template
|
|
cp .env.example .env
|
|
|
|
# Edit with your values
|
|
nano .env
|
|
```
|
|
|
|
Required environment variables:
|
|
```env
|
|
RESEND_API_KEY=re_your_actual_api_key
|
|
FROM_DOMAIN=yourdomain.com
|
|
FROM_EMAIL=noreply@yourdomain.com
|
|
NODE_ENV=production
|
|
PORT=3001
|
|
```
|
|
|
|
### 2. Domain Verification
|
|
- [ ] Verify your domain in Resend dashboard
|
|
- [ ] Add SPF record: `v=spf1 include:_spf.resend.com ~all`
|
|
- [ ] Add DKIM records (provided by Resend)
|
|
- [ ] Test email delivery
|
|
|
|
### 3. Security Configuration
|
|
- [ ] Set strong CORS origin
|
|
- [ ] Configure rate limiting for your needs
|
|
- [ ] Review helmet security headers
|
|
- [ ] Set up SSL/TLS certificates
|
|
|
|
## 🏗️ Deployment Options
|
|
|
|
### Option 1: Node.js Server (Recommended)
|
|
|
|
#### Development
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Start development server (with hot reload)
|
|
npm run server:dev
|
|
|
|
# Start frontend (separate terminal)
|
|
npm run dev
|
|
```
|
|
|
|
#### Production
|
|
```bash
|
|
# Build the project
|
|
npm run build
|
|
|
|
# Start production server
|
|
npm start
|
|
```
|
|
|
|
### Option 2: Docker Deployment
|
|
|
|
Create `Dockerfile`:
|
|
```dockerfile
|
|
FROM node:18-alpine
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy package files
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
|
|
# Copy source code
|
|
COPY . .
|
|
|
|
# Build the application
|
|
RUN npm run build
|
|
|
|
# Expose port
|
|
EXPOSE 3001
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD curl -f http://localhost:3001/health || exit 1
|
|
|
|
# Start the server
|
|
CMD ["npm", "start"]
|
|
```
|
|
|
|
Build and run:
|
|
```bash
|
|
# Build image
|
|
docker build -t email-service .
|
|
|
|
# Run container
|
|
docker run -d \
|
|
--name email-service \
|
|
-p 3001:3001 \
|
|
--env-file .env \
|
|
email-service
|
|
```
|
|
|
|
### Option 3: Cloud Deployment
|
|
|
|
#### Vercel
|
|
```json
|
|
// vercel.json
|
|
{
|
|
"version": 2,
|
|
"builds": [
|
|
{
|
|
"src": "server.ts",
|
|
"use": "@vercel/node"
|
|
}
|
|
],
|
|
"routes": [
|
|
{
|
|
"src": "/(.*)",
|
|
"dest": "/server.ts"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### Railway
|
|
```bash
|
|
# Install Railway CLI
|
|
npm install -g @railway/cli
|
|
|
|
# Login and deploy
|
|
railway login
|
|
railway init
|
|
railway up
|
|
```
|
|
|
|
#### Heroku
|
|
```json
|
|
// Procfile
|
|
web: npm start
|
|
```
|
|
|
|
## 🔧 Configuration
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Required | Default | Description |
|
|
|----------|----------|---------|-------------|
|
|
| `RESEND_API_KEY` | ✅ | - | Your Resend API key |
|
|
| `FROM_DOMAIN` | ✅ | - | Verified sending domain |
|
|
| `FROM_EMAIL` | ❌ | `noreply@{FROM_DOMAIN}` | Default from email |
|
|
| `NODE_ENV` | ❌ | `development` | Environment mode |
|
|
| `PORT` | ❌ | `3001` | Server port |
|
|
| `RATE_LIMIT_MAX` | ❌ | `10` | Max emails per window |
|
|
| `RATE_LIMIT_WINDOW_MS` | ❌ | `900000` | Rate limit window (15min) |
|
|
| `CORS_ORIGIN` | ❌ | `http://localhost:3000` | Allowed CORS origin |
|
|
| `LOG_LEVEL` | ❌ | `info` | Logging level |
|
|
|
|
### Rate Limiting Configuration
|
|
|
|
Adjust based on your needs:
|
|
```env
|
|
# Conservative (good for small apps)
|
|
RATE_LIMIT_MAX=5
|
|
RATE_LIMIT_WINDOW_MS=900000 # 15 minutes
|
|
|
|
# Moderate (good for medium apps)
|
|
RATE_LIMIT_MAX=20
|
|
RATE_LIMIT_WINDOW_MS=600000 # 10 minutes
|
|
|
|
# Liberal (good for high-volume apps)
|
|
RATE_LIMIT_MAX=100
|
|
RATE_LIMIT_WINDOW_MS=300000 # 5 minutes
|
|
```
|
|
|
|
## 📊 API Endpoints
|
|
|
|
### Health Check
|
|
```bash
|
|
GET /health
|
|
```
|
|
Response:
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2026-03-12T10:00:00.000Z",
|
|
"service": "email-template-service",
|
|
"version": "1.0.0"
|
|
}
|
|
```
|
|
|
|
### Send Invitation Email
|
|
```bash
|
|
POST /api/emails/invitation
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"to": "user@example.com",
|
|
"eventName": "Product Launch",
|
|
"dateTime": "March 25, 2026 at 2:00 PM",
|
|
"location": "Conference Room A",
|
|
"ctaUrl": "https://myapp.com/rsvp/123",
|
|
"company": {
|
|
"name": "My Company",
|
|
"logoUrl": "https://mycompany.com/logo.png",
|
|
"primaryColor": "#f97316"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Send Payment Request
|
|
```bash
|
|
POST /api/emails/payment-request
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"to": "customer@example.com",
|
|
"amount": 150.00,
|
|
"currency": "USD",
|
|
"description": "Monthly subscription",
|
|
"dueDate": "March 31, 2026",
|
|
"company": {
|
|
"name": "My Company",
|
|
"paymentLink": "https://myapp.com/pay/123"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Send Password Reset
|
|
```bash
|
|
POST /api/emails/password-reset
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"to": "user@example.com",
|
|
"resetLink": "https://myapp.com/reset?token=abc123",
|
|
"recipientName": "John Doe",
|
|
"company": {
|
|
"name": "My Company",
|
|
"logoUrl": "https://mycompany.com/logo.png"
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🔍 Monitoring & Logging
|
|
|
|
### Log Format
|
|
All logs are structured JSON:
|
|
```json
|
|
{
|
|
"level": "info",
|
|
"message": "Email sent successfully",
|
|
"timestamp": "2026-03-12T10:00:00.000Z",
|
|
"meta": {
|
|
"templateId": "invitation",
|
|
"to": "u***@example.com",
|
|
"messageId": "abc123"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Health Monitoring
|
|
Monitor these endpoints:
|
|
- `GET /health` - Service health
|
|
- Check logs for error patterns
|
|
- Monitor rate limit violations
|
|
- Track email delivery rates
|
|
|
|
### Error Codes
|
|
| Code | Description | Action |
|
|
|------|-------------|--------|
|
|
| `VALIDATION_ERROR` | Invalid input data | Fix request format |
|
|
| `RESEND_ERROR` | Resend API issue | Check API key/domain |
|
|
| `RATE_LIMIT_ERROR` | Too many requests | Implement backoff |
|
|
| `INTERNAL_ERROR` | Server error | Check logs |
|
|
|
|
## 🛡️ Security Best Practices
|
|
|
|
### 1. API Key Security
|
|
- Never commit API keys to version control
|
|
- Use environment variables only
|
|
- Rotate API keys regularly
|
|
- Monitor API key usage
|
|
|
|
### 2. Input Validation
|
|
- All inputs are validated with Zod schemas
|
|
- Email addresses are validated
|
|
- URLs are validated
|
|
- String lengths are limited
|
|
|
|
### 3. Rate Limiting
|
|
- Prevents email spam/abuse
|
|
- Configurable limits
|
|
- IP-based tracking
|
|
- Proper error responses
|
|
|
|
### 4. CORS Configuration
|
|
- Restrict to specific origins
|
|
- No wildcard origins in production
|
|
- Proper preflight handling
|
|
|
|
### 5. Security Headers
|
|
- Helmet.js for security headers
|
|
- Content Security Policy
|
|
- HSTS enabled
|
|
- XSS protection
|
|
|
|
## 🚨 Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
#### 1. "Domain not verified"
|
|
```bash
|
|
# Check domain verification in Resend dashboard
|
|
# Add required DNS records
|
|
# Wait for propagation (up to 24 hours)
|
|
```
|
|
|
|
#### 2. "Rate limit exceeded"
|
|
```bash
|
|
# Check current limits
|
|
curl http://localhost:3001/api
|
|
|
|
# Adjust limits in .env
|
|
RATE_LIMIT_MAX=20
|
|
```
|
|
|
|
#### 3. "Email not delivered"
|
|
```bash
|
|
# Check Resend logs
|
|
# Verify recipient email
|
|
# Check spam folder
|
|
# Verify SPF/DKIM records
|
|
```
|
|
|
|
#### 4. "Validation errors"
|
|
```bash
|
|
# Check request format
|
|
# Verify required fields
|
|
# Check data types
|
|
# Review API documentation
|
|
```
|
|
|
|
### Debug Mode
|
|
Enable detailed errors in development:
|
|
```env
|
|
NODE_ENV=development
|
|
LOG_LEVEL=debug
|
|
```
|
|
|
|
## 📈 Performance Optimization
|
|
|
|
### 1. Caching
|
|
Consider caching rendered templates:
|
|
```typescript
|
|
// Add to ResendService
|
|
private templateCache = new Map<string, string>()
|
|
```
|
|
|
|
### 2. Connection Pooling
|
|
For high volume, consider connection pooling for Resend API calls.
|
|
|
|
### 3. Queue System
|
|
For bulk emails, implement a queue system:
|
|
- Redis + Bull
|
|
- AWS SQS
|
|
- Google Cloud Tasks
|
|
|
|
### 4. Monitoring
|
|
Set up monitoring:
|
|
- Application Performance Monitoring (APM)
|
|
- Error tracking (Sentry)
|
|
- Uptime monitoring
|
|
- Email delivery tracking
|
|
|
|
## 🎯 Production Checklist
|
|
|
|
Before going live:
|
|
|
|
- [ ] Environment variables configured
|
|
- [ ] Domain verified in Resend
|
|
- [ ] DNS records added (SPF, DKIM)
|
|
- [ ] SSL certificate installed
|
|
- [ ] Rate limits configured
|
|
- [ ] CORS origins restricted
|
|
- [ ] Logging configured
|
|
- [ ] Health checks working
|
|
- [ ] Error handling tested
|
|
- [ ] Load testing completed
|
|
- [ ] Monitoring set up
|
|
- [ ] Backup strategy in place
|
|
|
|
## 📞 Support
|
|
|
|
For issues:
|
|
1. Check logs first
|
|
2. Review this documentation
|
|
3. Check Resend status page
|
|
4. Verify environment configuration
|
|
5. Test with curl/Postman
|
|
|
|
The service is now production-ready with enterprise-grade security and reliability! |