Overview
SkillRise requires environment variables for database connections, third-party services, and application configuration. The server uses runtime environment variables, while the client uses build-time variables.Server Variables
Runtime configuration via
.env fileClient Variables
Build-time configuration with Vite
Server Environment Variables
The server reads variables from a.env file in the server/ directory at runtime.
Quick Reference
| Variable | Required | Default | Description |
|---|---|---|---|
PORT | No | 3000 | Server port |
NODE_ENV | No | - | Environment mode |
FRONTEND_URL | Production only | http://localhost:5173 | CORS origin |
BACKEND_PUBLIC_URL | No | - | Public API URL |
MONGODB_URI | Yes | - | MongoDB connection string |
CLERK_WEBHOOK_SECRET | Yes | - | Clerk webhook signing key |
CLOUDINARY_NAME | Yes | - | Cloudinary cloud name |
CLOUDINARY_API_KEY | Yes | - | Cloudinary API key |
CLOUDINARY_SECRET_KEY | Yes | - | Cloudinary API secret |
RAZORPAY_KEY_ID | Yes | - | Razorpay key ID |
RAZORPAY_KEY_SECRET | Yes | - | Razorpay key secret |
RAZORPAY_WEBHOOK_SECRET | Yes | - | Razorpay webhook secret |
CURRENCY | No | INR | Payment currency code |
GROQ_CHATBOT_API_KEY | Yes | - | Groq AI API key |
Configuration File
Create a.env file in the server/ directory:
server/.env
Variable Details
Server Configuration
Server Configuration
PORT (Optional)- Type: Number
- Default:
3000 - Usage:
server.js:157 - Description: HTTP server listening port
NODE_ENV (Optional)- Type: String
- Values:
development,production - Usage:
server.js:26,server.js:149 - Description: Controls error logging verbosity and CORS validation
FRONTEND_URL (Required in production)- Type: URL
- Default:
http://localhost:5173 - Usage:
server.js:26-29 - Description: CORS allowed origin for frontend requests
In production,
FRONTEND_URL must be set to prevent “CORS origin mismatch” errors.BACKEND_PUBLIC_URL (Optional)- Type: URL
- Fallback:
VITE_BACKEND_URL - Usage:
userController.js:66-67 - Description: Public-facing backend URL for email links and webhooks
Database
Database
MONGODB_URI (Required)- Type: Connection string
- Usage:
configs/mongodb.js:7 - Description: MongoDB connection URI
- Format:
mongodb+srv://username:password@host/database?options
Create MongoDB Atlas Account
Sign up at mongodb.com/cloud/atlas
Create Cluster
- Choose cloud provider and region
- Select free tier (M0) or paid tier
- Click “Create Cluster”
Configure Database Access
- Go to Database Access
- Click Add New Database User
- Create username and password
- Grant “Read and write to any database” permission
Configure Network Access
- Go to Network Access
- Click Add IP Address
- Add
0.0.0.0/0for all IPs (or restrict to your server IP)
Authentication
Authentication
CLERK_WEBHOOK_SECRET (Required)- Type: String (starts with
whsec_) - Usage:
controllers/webhooks.js:10 - Description: Secret key for verifying Clerk webhook signatures
Create Clerk Application
Sign up at clerk.com and create a new application
Configure Webhook Endpoint
- Go to Webhooks in Clerk dashboard
- Click Add Endpoint
- Enter URL:
https://yourdomain.com/clerk - Select events:
user.created,user.updated,user.deleted
Clerk webhooks sync user data between Clerk and your MongoDB database.
File Storage
File Storage
CLOUDINARY_NAME (Required)- Type: String
- Usage:
configs/cloudinary.js:5 - Description: Cloudinary cloud name
CLOUDINARY_API_KEY (Required)- Type: String
- Usage:
configs/cloudinary.js:6 - Description: Cloudinary API key
CLOUDINARY_SECRET_KEY (Required)- Type: String
- Usage:
configs/cloudinary.js:7 - Description: Cloudinary API secret
Create Cloudinary Account
Sign up at cloudinary.com
- Course thumbnails
- Lesson video uploads
- User profile pictures
- Certificate backgrounds
- Community post images
Payment Gateway
Payment Gateway
RAZORPAY_KEY_ID (Required)- Type: String (starts with
rzp_test_orrzp_live_) - Usage:
services/payments/razorpay.service.js:16,razorpay.service.js:37 - Description: Razorpay API key ID
RAZORPAY_KEY_SECRET (Required)- Type: String
- Usage:
services/payments/razorpay.service.js:17,razorpay.service.js:50 - Description: Razorpay API key secret
RAZORPAY_WEBHOOK_SECRET (Required)- Type: String
- Usage:
controllers/webhooks.js:72 - Description: Webhook signature verification secret
CURRENCY (Optional)- Type: ISO 4217 currency code
- Default:
INR - Usage:
razorpay.service.js:20,userController.js:508 - Description: Currency for payment amounts
- Supported:
INR,USD,EUR,GBP, etc.
Create Razorpay Account
Sign up at razorpay.com
Generate API Keys
- Go to Settings → API Keys
- Click Generate Test Keys (for testing)
- Or Generate Live Keys (for production)
- Copy Key ID and Key Secret
AI Services
AI Services
GROQ_CHATBOT_API_KEY (Required)- Type: String (starts with
gsk_) - Usage:
services/chatbot/aiChatbotService.js:3 - Description: Groq API key for AI chatbot functionality
Create Groq Account
Sign up at console.groq.com
Generate API Key
- Go to API Keys section
- Click Create API Key
- Name your key (e.g., “SkillRise Production”)
- Copy the generated key (starts with
gsk_)
- AI-powered course assistant chatbot
- Quiz generation from course content
- Personalized learning roadmap generation
- Content recommendations
Client Environment Variables
The client uses Vite environment variables that are embedded into the build at compile time.Quick Reference
| Variable | Required | Description |
|---|---|---|
VITE_CLERK_PUBLISHABLE_KEY | Yes | Clerk authentication public key |
VITE_STRIPE_PUBLISHABLE_KEY | Yes | Stripe payment public key |
VITE_BACKEND_URL | Yes | Backend API base URL |
Configuration
Client variables are passed as build arguments when building the Docker image:client/Dockerfile
Local Development
For local development, create a.env file in the client/ directory:
client/.env
Vite automatically loads
.env files during development (npm run dev).Variable Details
VITE_CLERK_PUBLISHABLE_KEY
VITE_CLERK_PUBLISHABLE_KEY
Type: String (starts with
Usage:
Description: Clerk publishable key for client-side authenticationGetting the Key:
pk_test_ or pk_live_)Usage:
client/src/main.jsx:11Description: Clerk publishable key for client-side authentication
- Go to Clerk Dashboard
- Select your application
- Navigate to API Keys
- Copy Publishable key (starts with
pk_test_orpk_live_)
VITE_STRIPE_PUBLISHABLE_KEY
VITE_STRIPE_PUBLISHABLE_KEY
Type: String (starts with
Usage: Client-side Stripe integration (if implemented)
Description: Stripe publishable key for payment UIGetting the Key:
pk_test_ or pk_live_)Usage: Client-side Stripe integration (if implemented)
Description: Stripe publishable key for payment UI
SkillRise currently uses Razorpay for payments. This variable is included for future Stripe integration or international payments.
- Go to Stripe Dashboard
- Click Developers → API keys
- Copy Publishable key
- Test key:
pk_test_...(for development) - Live key:
pk_live_...(for production)
VITE_BACKEND_URL
VITE_BACKEND_URL
Type: URL
Usage:
Description: Backend API base URL for all API requestsEnvironment-Specific Values:
Usage:
client/src/context/AppContext.jsx:12, client/src/hooks/useTimeTracker.js:28Description: Backend API base URL for all API requests
- Local development:
http://localhost:3000 - Staging:
https://api-staging.yourdomain.com - Production:
https://api.yourdomain.com
Build-Time vs Runtime
- Server (Runtime)
- Client (Build-Time)
Runtime ConfigurationAdvantages:
- Variables loaded from
.envfile when server starts - Can be changed without rebuilding
- Update by modifying
.envand restarting container
- Easy to update
- Different per environment
- Kept secret from version control
Security Best Practices
Secret Management
Secret Management
Do:
- Use environment variables for all secrets
- Never commit
.envfiles to Git - Add
.envto.gitignore - Use different credentials for development/production
- Rotate secrets regularly
- Hardcode secrets in source code
- Share
.envfiles via email or chat - Commit secrets to version control
- Use production secrets in development
- Log secret values
.gitignore
Public vs Secret Keys
Public vs Secret Keys
Public Keys (Safe in client code):
- ✅
VITE_CLERK_PUBLISHABLE_KEY(starts withpk_) - ✅
VITE_STRIPE_PUBLISHABLE_KEY(starts withpk_) - ✅
VITE_BACKEND_URL
- ❌
CLERK_WEBHOOK_SECRET - ❌
RAZORPAY_KEY_SECRET - ❌
CLOUDINARY_SECRET_KEY - ❌
GROQ_CHATBOT_API_KEY - ❌
MONGODB_URI(contains password)
Environment Separation
Environment Separation
Use separate credentials for each environment:Development:Staging:Production:
GitHub Secrets
GitHub Secrets
Store secrets in GitHub repository settings for CI/CD:
- Repository Settings → Secrets and variables → Actions
- Add secrets (never use
.envfile in CI) - Reference in workflows:
${{ secrets.SECRET_NAME }}
DOCKER_USERNAMEDOCKER_PASSWORDVITE_CLERK_PUBLISHABLE_KEYVITE_STRIPE_PUBLISHABLE_KEYVITE_BACKEND_URL
Environment Templates
Complete Server .env Template
server/.env.template
Complete Client .env Template
client/.env.template
Validation
Add validation to ensure all required variables are set:server/validateEnv.js
server/server.js
Troubleshooting
Missing Environment Variable
Missing Environment Variable
Error:Solution:
- Check
.envfile exists in correct directory - Verify variable name is spelled correctly
- Ensure no spaces around
=(useKEY=value, notKEY = value) - Restart server after changing
.env
MongoDB Connection Failed
MongoDB Connection Failed
Error:Solutions:
- Verify
MONGODB_URIis correct - Check MongoDB Atlas IP whitelist (add
0.0.0.0/0or your server IP) - Ensure database user has correct permissions
- Test connection string in MongoDB Compass
Clerk Webhook Verification Failed
Clerk Webhook Verification Failed
Error:Solutions:
- Verify
CLERK_WEBHOOK_SECRETmatches Clerk dashboard - Check webhook endpoint URL is correct
- Ensure request body is not modified before webhook handler
- Test webhook with Clerk dashboard testing tool
CORS Errors in Browser
CORS Errors in Browser
Error:Solutions:
- Verify
FRONTEND_URLin server.envmatches client URL exactly - Check
VITE_BACKEND_URLin client build is correct - Ensure no trailing slashes in URLs
- Clear browser cache and rebuild client
Client Build Variables Not Working
Client Build Variables Not Working
Issue: Changes to
VITE_* variables not reflectedSolution:
Client variables are build-time only. You must rebuild: