Deployment Guide
This guide covers deploying Veltix applications to various environments, from development to production.
Overview
Veltix can be deployed to multiple environments:
- Development: Local development setup
- Staging: Pre-production testing environment
- Production: Live production environment
- Docker: Containerized deployment
- Cloud Platforms: Vercel, Netlify, AWS, etc.
Prerequisites
Before deploying, ensure you have:
- Node.js 20.0.0 or higher
- pnpm 9.0.0 or higher
- Git for version control
- Environment variables configured
- Database setup (if using)
Environment Configuration
Environment Variables
Create environment-specific configuration files:
# .env.development
NODE_ENV=development
REACT_APP_API_URL=http://localhost:3001
REACT_APP_WS_URL=ws://localhost:3001
REACT_APP_SENTRY_DSN=
REACT_APP_ANALYTICS_ID=
# .env.production
NODE_ENV=production
REACT_APP_API_URL=https://api.yourdomain.com
REACT_APP_WS_URL=wss://api.yourdomain.com
REACT_APP_SENTRY_DSN=your-sentry-dsn
REACT_APP_ANALYTICS_ID=your-analytics-idConfiguration Management
// config/environment.ts
interface EnvironmentConfig {
api: {
url: string;
timeout: number;
};
websocket: {
url: string;
reconnectAttempts: number;
};
monitoring: {
sentryDsn?: string;
analyticsId?: string;
};
features: {
realTimeUpdates: boolean;
advancedCharts: boolean;
};
}
const getEnvironmentConfig = (): EnvironmentConfig => {
const isProduction = process.env.NODE_ENV === 'production';
return {
api: {
url: process.env.REACT_APP_API_URL || 'http://localhost:3001',
timeout: parseInt(process.env.REACT_APP_API_TIMEOUT || '5000')
},
websocket: {
url: process.env.REACT_APP_WS_URL || 'ws://localhost:3001',
reconnectAttempts: 5
},
monitoring: {
sentryDsn: process.env.REACT_APP_SENTRY_DSN,
analyticsId: process.env.REACT_APP_ANALYTICS_ID
},
features: {
realTimeUpdates: process.env.REACT_APP_REAL_TIME === 'true',
advancedCharts: process.env.REACT_APP_ADVANCED_CHARTS === 'true'
}
};
};Build Process
Production Build
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Build specific apps
pnpm --filter=web build
pnpm --filter=api build
pnpm --filter=docs buildBuild Optimization
// next.config.js
const nextConfig = {
output: 'standalone',
experimental: {
optimizeCss: true,
optimizePackageImports: ['@veltix/charts', '@veltix/ui']
},
compress: true,
poweredByHeader: false,
generateEtags: false,
onDemandEntries: {
maxInactiveAge: 25 * 1000,
pagesBufferLength: 2
}
};Bundle Analysis
# Analyze bundle size
pnpm build:analyze
# Or use webpack-bundle-analyzer
npx webpack-bundle-analyzer .next/static/chunks/*.jsDocker Deployment
Dockerfile
# Multi-stage build
FROM node:20-alpine AS base
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm
# Dependencies stage
FROM base AS deps
COPY package.json pnpm-workspace.yaml ./
COPY packages/*/package.json ./packages/*/
COPY apps/*/package.json ./apps/*/
RUN pnpm install --frozen-lockfile
# Build stage
FROM base AS builder
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/apps/web/public ./apps/web/public
COPY --from=builder /app/apps/web/.next/standalone ./
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "apps/web/server.js"]Docker Compose
# docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- REACT_APP_API_URL=http://api:3001
depends_on:
- api
- redis
api:
build:
context: .
dockerfile: Dockerfile.api
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@db:5432/veltix
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:15
environment:
- POSTGRES_DB=veltix
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:Cloud Platform Deployment
Vercel Deployment
// vercel.json
{
"version": 2,
"builds": [
{
"src": "apps/web/package.json",
"use": "@vercel/next"
},
{
"src": "apps/api/package.json",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/api/(.*)",
"dest": "apps/api/$1"
},
{
"src": "/(.*)",
"dest": "apps/web/$1"
}
],
"env": {
"NODE_ENV": "production"
}
}Netlify Deployment
# netlify.toml
[build]
base = "."
command = "pnpm build"
publish = "apps/web/out"
[build.environment]
NODE_VERSION = "20"
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/api/:splat"
status = 200
[[redirects]]
from = "/*"
to = "/index.html"
status = 200AWS Deployment
# serverless.yml
service: veltix-dashboard
provider:
name: aws
runtime: nodejs20.x
region: us-east-1
environment:
NODE_ENV: production
DATABASE_URL: ${ssm:/veltix/database-url}
REDIS_URL: ${ssm:/veltix/redis-url}
functions:
api:
handler: apps/api/src/server.handler
events:
- http:
path: /api/{proxy+}
method: ANY
- http:
path: /api
method: ANY
web:
handler: apps/web/src/server.handler
events:
- http:
path: /{proxy+}
method: ANY
- http:
path: /
method: ANY
plugins:
- serverless-offline
- serverless-dotenv-pluginDatabase Setup
PostgreSQL Setup
-- Create database
CREATE DATABASE veltix;
-- Create user
CREATE USER veltix_user WITH PASSWORD 'secure_password';
-- Grant permissions
GRANT ALL PRIVILEGES ON DATABASE veltix TO veltix_user;
-- Create tables (if using Prisma)
-- Run: npx prisma migrate deployRedis Setup
# Install Redis
sudo apt-get install redis-server
# Configure Redis
sudo nano /etc/redis/redis.conf
# Key configurations:
# bind 127.0.0.1
# port 6379
# requirepass your_redis_password
# maxmemory 256mb
# maxmemory-policy allkeys-lru
# Start Redis
sudo systemctl start redis
sudo systemctl enable redisMonitoring and Logging
Application Monitoring
// monitoring/sentry.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.REACT_APP_SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0,
integrations: [
new Sentry.BrowserTracing(),
new Sentry.Replay()
]
});
// monitoring/analytics.ts
import { Analytics } from '@segment/analytics-next';
const analytics = Analytics({
writeKey: process.env.REACT_APP_ANALYTICS_ID
});
export const trackEvent = (event: string, properties?: any) => {
analytics.track(event, properties);
};Health Checks
// health-check.ts
export const healthCheck = async () => {
const checks = {
database: await checkDatabase(),
redis: await checkRedis(),
api: await checkAPI()
};
const isHealthy = Object.values(checks).every(check => check.status === 'ok');
return {
status: isHealthy ? 'healthy' : 'unhealthy',
checks,
timestamp: new Date().toISOString()
};
};
const checkDatabase = async () => {
try {
await prisma.$queryRaw`SELECT 1`;
return { status: 'ok', message: 'Database connection successful' };
} catch (error) {
return { status: 'error', message: error.message };
}
};SSL and Security
SSL Configuration
# nginx.conf
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
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_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
location /api {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}Security Headers
// next.config.js
const nextConfig = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Frame-Options',
value: 'DENY'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
},
{
key: 'X-XSS-Protection',
value: '1; mode=block'
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin'
},
{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:;"
}
]
}
];
}
};Performance Optimization
CDN Configuration
// next.config.js
const nextConfig = {
images: {
domains: ['your-cdn-domain.com'],
formats: ['image/webp', 'image/avif']
},
experimental: {
optimizeCss: true,
optimizePackageImports: ['@veltix/charts']
}
};Caching Strategy
// cache-config.ts
export const cacheConfig = {
static: {
maxAge: 31536000, // 1 year
immutable: true
},
dynamic: {
maxAge: 3600, // 1 hour
staleWhileRevalidate: 86400 // 24 hours
},
api: {
maxAge: 300, // 5 minutes
staleWhileRevalidate: 3600 // 1 hour
}
};Deployment Checklist
Pre-deployment
- All tests passing
- Environment variables configured
- Database migrations applied
- SSL certificates installed
- Monitoring tools configured
- Backup strategy in place
- Rollback plan prepared
Post-deployment
- Health checks passing
- Performance metrics normal
- Error rates acceptable
- User feedback positive
- Monitoring alerts configured
- Documentation updated
Troubleshooting
Common Issues
Build failures
# Clear cache and rebuild
rm -rf node_modules .next
pnpm install
pnpm buildDatabase connection issues
# Check database status
sudo systemctl status postgresql
# Test connection
psql -h localhost -U veltix_user -d veltixMemory issues
# Monitor memory usage
htop
free -h
# Check for memory leaks
node --inspect apps/api/src/server.tsNetwork issues
# Test API connectivity
curl -I https://api.yourdomain.com/health
# Check SSL certificate
openssl s_client -connect yourdomain.com:443Best Practices
1. Environment Management
- Use environment-specific configurations
- Never commit sensitive data
- Use secrets management
- Implement proper logging
2. Security
- Enable HTTPS everywhere
- Implement proper authentication
- Use security headers
- Regular security updates
3. Performance
- Use CDN for static assets
- Implement proper caching
- Monitor performance metrics
- Optimize bundle size
4. Monitoring
- Set up health checks
- Monitor error rates
- Track performance metrics
- Configure alerts
5. Backup and Recovery
- Regular database backups
- Test recovery procedures
- Document rollback procedures
- Version control everything
Last updated on