Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# LiveKit Configuration
LIVEKIT_URL=ws://localhost:7880
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secret

# TURN Server Configuration
TURN_SERVER_URL=turn:localhost:3478
TURN_USERNAME=livekit
TURN_PASSWORD=password

# Redis Configuration
REDIS_URL=redis://localhost:6379
REDIS_PASSWORD=

# Database Configuration (if using)
DATABASE_URL=postgresql://user:password@localhost:5432/videoapp

# Next.js Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret-here

# SSL Configuration (for production)
SSL_CERT_PATH=/etc/nginx/ssl/cert.pem
SSL_KEY_PATH=/etc/nginx/ssl/key.pem

# Monitoring
PROMETHEUS_ENABLED=true

# Security
JWT_SECRET=your-jwt-secret-here

# File Upload (if using)
UPLOADTHING_SECRET=your-uploadthing-secret
UPLOADTHING_APP_ID=your-uploadthing-app-id

# Email (if using)
RESEND_API_KEY=your-resend-api-key

# Production Settings
NODE_ENV=development
LOG_LEVEL=info

# WebRTC Settings
WEBRTC_MIN_PORT=50000
WEBRTC_MAX_PORT=60000

# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
33 changes: 29 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# Step 1: Use an official Node.js image as the base
FROM node:20-alpine

# Install OpenSSL 1.1
RUN apk add --no-cache openssl1.1-compat
# Install system dependencies for WebRTC and media processing
RUN apk add --no-cache \
openssl1.1-compat \
ffmpeg \
opus \
libvpx \
x264 \
libogg \
libvorbis \
libtheora \
libwebp \
alsa-lib \
pulseaudio \
dbus \
&& rm -rf /var/cache/apk/*

# Step 2: Set the working directory inside the container
WORKDIR /app
Expand All @@ -21,8 +34,20 @@ COPY . .
# Step 6: Build the application
RUN npm run build

# Step 7: Expose the port the app runs on
# Step 7: Create non-root user for security
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# Change ownership of the app directory
RUN chown -R nextjs:nodejs /app
USER nextjs

# Step 8: Expose the port the app runs on
EXPOSE 3000

# Step 8: Define the command to start the application
# Health check for container monitoring
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1

# Step 9: Define the command to start the application
CMD ["node", ".next/standalone/server.js"]
55 changes: 55 additions & 0 deletions app/api/health/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { NextResponse } from 'next/server';

export async function GET() {
try {
// Basic health checks
const healthStatus = {
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: process.env.NODE_ENV,
version: process.env.npm_package_version || '1.0.0',
services: {
redis: await checkRedis(),
livekit: await checkLiveKit(),
}
};

return NextResponse.json(healthStatus, { status: 200 });
} catch (error) {
return NextResponse.json(
{
status: 'unhealthy',
error: error instanceof Error ? error.message : 'Unknown error',
timestamp: new Date().toISOString()
},
{ status: 503 }
);
}
}

async function checkRedis() {
try {
// Basic Redis connectivity check
if (process.env.REDIS_URL) {
// In a real implementation, you'd ping Redis here
return { status: 'connected', url: process.env.REDIS_URL };
}
return { status: 'not_configured' };
} catch (error) {
return { status: 'error', error: error instanceof Error ? error.message : 'Unknown error' };
}
}

async function checkLiveKit() {
try {
// Basic LiveKit connectivity check
if (process.env.LIVEKIT_URL) {
// In a real implementation, you'd check LiveKit server status here
return { status: 'configured', url: process.env.LIVEKIT_URL };
}
return { status: 'not_configured' };
} catch (error) {
return { status: 'error', error: error instanceof Error ? error.message : 'Unknown error' };
}
}
80 changes: 80 additions & 0 deletions config/livekit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
port: 7880
bind_addresses:
- ""

rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
# Configure STUN/TURN servers
stun_servers:
- stun:coturn:3478
turn_servers:
- host: coturn
port: 3478
protocol: udp
username: livekit
credential: password
- host: coturn
port: 3478
protocol: tcp
username: livekit
credential: password

redis:
address: redis:6379
username: ""
password: ""
db: 0

api:
key: devkey
secret: secret

# Room settings
room:
enabled_codecs:
- mime: audio/opus
- mime: video/h264
- mime: video/vp8
- mime: video/vp9
max_participants: 100
empty_timeout: 300s
departure_timeout: 20s

# Audio settings
audio:
# Enable audio processing
enabled: true
# Audio levels and quality
update_interval: 200ms

# Video settings
video:
# Enable simulcast for better quality adaptation
enabled: true
# Hardware acceleration if available
hardware_encoder: true

# Logging
logging:
level: info
sample_rate: 1

# Metrics and monitoring
prometheus:
port: 6789

# Development settings (disable in production)
development:
disable_strict_config: false

# Security settings
keys:
api_key: devkey
api_secret: secret

# Node configuration for clustering
node:
ip: ""
Loading