Overview
This guide covers deploying Opinix Trade to production. The platform consists of multiple services that can be deployed independently or together.
Ensure all environment variables are properly configured before deploying to production.
Architecture Components
Opiinix Trade consists of the following deployable components:
Client (Next.js) Frontend application serving the user interface
Server (Express) Backend API handling orders and authentication
Engine Order matching engine processing trades
WebSocket Real-time communication server
Queue Worker Background job processing with BullMQ
Database PostgreSQL with TimescaleDB extension
Redis Cache and message broker
Deployment Strategies
Monolithic
Microservices
Hybrid
Deploy all services in a single container or server. Pros:
Simpler deployment
Lower cost for low traffic
Easy development-production parity
Cons:
Limited scalability
Single point of failure
Resource conflicts
Best for: Development, staging, low-traffic applicationsDeploy each service independently with separate containers. Pros:
Independent scaling
Fault isolation
Technology flexibility
Easier updates
Cons:
More complex infrastructure
Higher operational overhead
Network latency between services
Best for: Production, high-traffic applicationsGroup related services while separating critical components. Pros:
Balanced complexity
Scale critical paths
Reasonable cost
Cons:
Requires careful planning
Best for: Growing applications
Pre-deployment Checklist
Environment Configuration
Required Environment Variables
Ensure all required environment variables are set: Database: DATABASE_URL = "postgresql://user:pass@host:5432/opinix?schema=public&sslmode=require"
Client: NEXTAUTH_URL = "https://yourdomain.com"
NEXTAUTH_SECRET = "[secure-random-secret]"
TWILIO_ACCOUNT_SID = "[your-twilio-sid]"
TWILIO_AUTH_TOKEN = "[your-twilio-token]"
TWILIO_NUMBER = "[your-twilio-number]"
Redis: REDIS_URI = "redis://username:password@host:6379"
Build Verification
Test production builds locally: # Build all packages
npm run build
# Test client build
cd apps/client && npm run build && npm run start
# Test server build
cd apps/server && npm run build && npm run start
Database Migrations
Ensure migrations are ready: cd packages/db
npx prisma migrate deploy
Vercel (Recommended for Client)
Configure Project
Create vercel.json in apps/client: {
"buildCommand" : "cd ../.. && npm run build -- --filter=client" ,
"devCommand" : "npm run dev" ,
"installCommand" : "npm install" ,
"framework" : "nextjs" ,
"outputDirectory" : ".next"
}
Set Environment Variables
Add environment variables in Vercel dashboard or CLI: vercel env add NEXTAUTH_SECRET
vercel env add DATABASE_URL
vercel env add TWILIO_ACCOUNT_SID
vercel env add TWILIO_AUTH_TOKEN
vercel env add TWILIO_NUMBER
Deploy
cd apps/client
vercel --prod
Vercel automatically handles Next.js optimizations, edge functions, and CDN distribution.
Railway (Recommended for Backend)
Railway provides easy deployment for backend services with integrated database hosting.
Install Railway CLI
npm install -g @railway/cli
railway login
Create Services
# Initialize project
railway init
# Add PostgreSQL
railway add --plugin postgresql
# Add Redis
railway add --plugin redis
Configure Build
Create railway.json in project root: {
"build" : {
"builder" : "NIXPACKS" ,
"buildCommand" : "npm install && npm run build"
},
"deploy" : {
"startCommand" : "npm run start:server" ,
"restartPolicyType" : "ON_FAILURE" ,
"restartPolicyMaxRetries" : 10
}
}
Deploy using Docker to any container platform (AWS ECS, Google Cloud Run, Azure Container Instances, DigitalOcean Apps).
Create optimized production Dockerfile: # Build stage
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json turbo.json ./
COPY apps/server ./apps/server
COPY packages ./packages
# Install dependencies
RUN npm ci --only=production
# Generate Prisma client
ARG DATABASE_URL
RUN cd packages/db && DATABASE_URL=$DATABASE_URL npx prisma generate
# Build application
RUN npm run build
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
# Copy built application
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/apps/server/dist ./apps/server/dist
COPY --from=builder /app/packages ./packages
# Run as non-root user
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3001
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3001/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
CMD [ "node" , "apps/server/dist/index.js" ]
version : "3.8"
services :
client :
build :
context : .
dockerfile : apps/client/Dockerfile
ports :
- "3000:3000"
environment :
- NODE_ENV=production
env_file :
- apps/client/.env.production
restart : unless-stopped
server :
build :
context : .
dockerfile : apps/server/Dockerfile
ports :
- "3001:3001"
environment :
- NODE_ENV=production
env_file :
- .env.production
depends_on :
- postgres
- redis
restart : unless-stopped
engine :
build :
context : .
dockerfile : services/engine/Dockerfile
environment :
- NODE_ENV=production
env_file :
- .env.production
depends_on :
- redis
- postgres
restart : unless-stopped
wss :
build :
context : .
dockerfile : services/wss/Dockerfile
ports :
- "8080:8080"
environment :
- NODE_ENV=production
env_file :
- services/wss/.env.production
depends_on :
- redis
restart : unless-stopped
postgres :
image : timescale/timescaledb:latest-pg12
environment :
POSTGRES_USER : ${POSTGRES_USER}
POSTGRES_PASSWORD : ${POSTGRES_PASSWORD}
POSTGRES_DB : ${POSTGRES_DB}
volumes :
- postgres-data:/var/lib/postgresql/data
restart : unless-stopped
redis :
image : redis:7-alpine
command : redis-server --requirepass ${REDIS_PASSWORD}
volumes :
- redis-data:/data
restart : unless-stopped
volumes :
postgres-data :
redis-data :
Database Deployment
Managed PostgreSQL
Self-hosted
Use managed database services: Options:
Railway: Built-in PostgreSQL
Supabase: PostgreSQL with additional features
AWS RDS: Enterprise-grade reliability
DigitalOcean Managed Databases: Simple and affordable
Neon: Serverless PostgreSQL
Benefits:
Automatic backups
High availability
Scaling capabilities
SSL/TLS by default
Monitoring included
Deploy PostgreSQL with TimescaleDB: # Using Docker
docker run -d \
--name timescaledb \
-p 5432:5432 \
-e POSTGRES_PASSWORD=securepassword \
-e POSTGRES_DB=opinix \
-v /data/postgres:/var/lib/postgresql/data \
timescale/timescaledb:latest-pg12
Setup Steps:
Enable TimescaleDB extension
Configure SSL certificates
Set up regular backups
Configure connection pooling (PgBouncer)
Set up monitoring
Redis Deployment
Managed Redis
Self-hosted
Options:
Upstash: Serverless Redis with generous free tier
Redis Labs: Official Redis cloud
AWS ElastiCache: Enterprise Redis
Railway: Built-in Redis
Configuration: REDIS_URI = "rediss://username:password@host:6380"
Deploy Redis with persistence: docker run -d \
--name redis \
-p 6379:6379 \
-v /data/redis:/data \
redis:7-alpine \
redis-server --requirepass securepassword --appendonly yes
Post-Deployment
Run Database Migrations
# Connect to production database
DATABASE_URL = "postgresql://user:pass@host:5432/opinix" \
npx prisma migrate deploy
Verify Deployment
Test all endpoints: # Client
curl https://yourdomain.com
# API
curl https://api.yourdomain.com/health
# WebSocket
wscat -c wss://ws.yourdomain.com
Configure CDN
Use a CDN for static assets:
Vercel includes CDN
CloudFlare for custom domains
AWS CloudFront
Scaling Considerations
Horizontal Scaling Scale services independently:
Multiple server instances behind load balancer
Engine workers based on queue depth
WebSocket servers with sticky sessions
Database Scaling
Read replicas for queries
Connection pooling (PgBouncer)
Optimize slow queries
Partition large tables
Caching Strategy
Redis for hot data
CDN for static assets
API response caching
Browser caching headers
Load Balancing
NGINX or HAProxy
Cloud load balancers (ALB, GCP LB)
Health check endpoints
Session affinity for WebSockets
Rollback Strategy
Always have a rollback plan before deploying.
Tag Releases
git tag -a v1.0.0 -m "Release 1.0.0"
git push origin v1.0.0
Keep Previous Version
Maintain the previous stable version in production for quick rollback.
Database Migrations
Make migrations backward-compatible or maintain separate rollback scripts.
Rollback Command
# Vercel
vercel rollback [deployment-url]
# Railway
railway rollback
# Docker
docker-compose up -d --no-deps service-name:previous-tag
Next Steps