npm run buildnpm startThis starts the Next.js server on port 3000.
You need to run multiple services in production:
# Terminal 1 - Next.js app
npm start
# Terminal 2 - WebSocket server
npm run ws:server
# Terminal 3 - Queue worker
npm run queue:worker# Database
DATABASE_URL=postgresql://user:password@host:5432/dbname
# Redis
REDIS_URL=redis://host:6379
# Server
PORT=3000
WS_PORT=3001
NODE_ENV=production
# Logging
LOG_LEVEL=info # trace, debug, info, warn, error, fatal
# Authentication
JWT_SECRET=your-production-secret-key-make-it-very-long-and-random
# LDAP (optional)
LDAP_URL=ldap://your-ldap-server:389
LDAP_BIND_DN=cn=admin,dc=example,dc=com
LDAP_BIND_PASSWORD=password
LDAP_SEARCH_BASE=ou=users,dc=example,dc=comImportant:
- Use a strong, random
JWT_SECRETin production - Use production database credentials
- Set
NODE_ENV=production
The included docker-compose.yml provides PostgreSQL and Redis:
docker-compose up -dCreate a Dockerfile for the application:
FROM node:18-alpine
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm ci --only=production
# Copy application files
COPY . .
# Build application
RUN npm run build
EXPOSE 3000 3001
# Start all services (consider using a process manager)
CMD ["npm", "start"]Build and run:
docker build -t my-app .
docker run -p 3000:3000 -p 3001:3001 my-appInstall PM2:
npm install -g pm2Create ecosystem.config.js:
module.exports = {
apps: [
{
name: 'web',
script: 'npm',
args: 'start',
},
{
name: 'websocket',
script: 'npm',
args: 'run ws:server',
},
{
name: 'queue-worker',
script: 'npm',
args: 'run queue:worker',
},
],
};Start all services:
pm2 start ecosystem.config.jsMonitor services:
pm2 status
pm2 logsBefore deploying, apply database migrations:
npm run db:migrateNever use npm run db:push in production. Always use migrations.
The application provides Kubernetes-compatible health check endpoints:
Check if the application is alive:
curl http://localhost:3000/api/health/liveCheck if the application is ready to accept traffic (verifies database and Redis):
curl http://localhost:3000/api/health/readyCheck if the application has finished starting:
curl http://localhost:3000/api/health/startupwscat -c ws://localhost:3001 -x '{"type":"ping"}'See Observability Documentation for detailed health check configuration.
When running multiple instances:
- Database: Use a single PostgreSQL instance with connection pooling
- Redis: Use a single Redis instance for queue and WebSocket sync
- WebSocket: Use Redis Pub/Sub to synchronize messages across instances
- Sessions: Store sessions in Redis, not memory
Use a load balancer (nginx, HAProxy) for the Next.js app:
upstream nextjs {
server localhost:3000;
server localhost:3001;
}
server {
listen 80;
location / {
proxy_pass http://nextjs;
}
}The application includes production-grade observability features:
Metrics are exposed at /api/metrics for Prometheus scraping:
curl http://localhost:3000/api/metricsConfigure Prometheus to scrape the metrics:
scrape_configs:
- job_name: 'lightweight-web'
static_configs:
- targets: ['your-app:3000']
metrics_path: '/api/metrics'
scrape_interval: 15sAvailable metrics include:
- HTTP request rates and latency
- tRPC procedure performance
- WebSocket connections and messages
- Queue job processing times
- Database query performance
- SSH operation metrics
- Authentication attempts
Structured JSON logs in production:
# PM2 logs
pm2 logs
# Docker logs
docker-compose logs -fConfigure log level with LOG_LEVEL environment variable (trace, debug, info, warn, error, fatal).
Create dashboards to visualize:
- Request rates and error rates
- p95/p99 latency
- Active connections (WebSocket, database)
- Queue depth and processing times
- System resources (CPU, memory)
Set up alerts for:
- High error rates
- Elevated latency
- Service downtime
- Queue backlog
- Resource exhaustion
Use Drizzle Studio or connect directly to PostgreSQL:
psql $DATABASE_URLConsider adding Bull Board for visual queue monitoring:
npm install @bull-board/express @bull-board/apiSee Observability Documentation for comprehensive monitoring setup, metric definitions, and alerting examples.
pg_dump $DATABASE_URL > backup.sqlpsql $DATABASE_URL < backup.sql- Change default
JWT_SECRET - Use strong database passwords
- Enable SSL for PostgreSQL connections
- Use HTTPS in production
- Enable CORS restrictions
- Set up rate limiting
- Regular security updates (
npm audit) - Secure LDAP credentials
- Enable firewall rules
- Regular backups
- Configure log aggregation (avoid logging to disk in production)
- Set up monitoring and alerting
- Restrict access to
/api/metricsendpoint (authentication/firewall)
# Find process using port
lsof -i :3000
# Kill process
kill -9 <PID>Check connection string and firewall rules:
psql $DATABASE_URLredis-cli -u $REDIS_URL ping