Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.easelms.org/llms.txt

Use this file to discover all available pages before exploring further.

This guide covers deploying EaseLMS to production. We’ll walk through deploying on popular platforms and setting up the required services.

Pre-Deployment Checklist

Before deploying, ensure you have:
  • Supabase project created and database migrated
  • All environment variables documented
  • AWS S3 bucket configured (for production)
  • Payment gateways configured (if using paid courses)
  • SendGrid account set up (for email notifications)
  • Domain name ready (optional but recommended)

Deployment Options

EaseLMS can be deployed to various platforms:
  • Vercel - Recommended for beginners, zero-config Next.js hosting
  • Railway - Easy deployment with PostgreSQL support
  • Docker - Self-hosted with full control
  • Traditional VPS - Ubuntu/Debian server with PM2

Deploy to Vercel

Vercel provides the easiest deployment experience for Next.js applications.
1

Install Vercel CLI (optional)

npm install -g vercel
2

Connect your repository

  1. Push your code to GitHub, GitLab, or Bitbucket
  2. Go to vercel.com and sign up
  3. Click Add New Project
  4. Import your repository
3

Configure project settings

  • Framework Preset: Next.js
  • Root Directory: apps/lms
  • Build Command: npm run build
  • Output Directory: .next
4

Add environment variables

In the Vercel dashboard, add all your environment variables:
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
NEXT_PUBLIC_APP_URL=https://yourdomain.com
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=wJa...
AWS_S3_BUCKET_NAME=your-bucket
STRIPE_SECRET_KEY=sk_live_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
SENDGRID_API_KEY=SG...
SENDGRID_FROM_EMAIL=noreply@yourdomain.com
Use production keys, not test keys!
5

Deploy

Click Deploy and wait for the build to complete (usually 2-3 minutes).
6

Configure domain (optional)

  1. Go to Settings → Domains
  2. Add your custom domain
  3. Update DNS records as instructed
  4. Update NEXT_PUBLIC_APP_URL to your domain

Vercel CLI Deployment

Alternatively, deploy from the command line:
cd apps/lms
vercel
Follow the prompts to deploy.

Deploy to Railway

Railway offers a great deployment experience with built-in database support.
1

Create Railway account

Sign up at railway.app
2

Create new project

  1. Click New Project
  2. Select Deploy from GitHub repo
  3. Authorize Railway and select your repository
3

Configure build settings

Railway should auto-detect Next.js. If not, set:
  • Build Command: cd apps/lms && npm install && npm run build
  • Start Command: cd apps/lms && npm start
4

Add environment variables

In the Railway dashboard:
  1. Go to Variables tab
  2. Add all your environment variables
  3. Click Deploy
5

Get deployment URL

Railway provides a URL like https://your-app.up.railway.app. Update NEXT_PUBLIC_APP_URL to this URL.

Deploy with Docker

For self-hosting with full control over your infrastructure.

Create Dockerfile

Create Dockerfile in apps/lms/:
FROM node:18-alpine AS base

# Install dependencies
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json* ./
RUN npm ci

# Build the application
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

# Production image
FROM base 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/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]

Create docker-compose.yml

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
      - NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
      - SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
      - NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
      - AWS_REGION=${AWS_REGION}
      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
      - AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME}
      - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
      - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}
      - SENDGRID_API_KEY=${SENDGRID_API_KEY}
      - SENDGRID_FROM_EMAIL=${SENDGRID_FROM_EMAIL}
    restart: unless-stopped

Deploy with Docker Compose

# Build and start
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down

AWS S3 Setup

AWS S3 is required for production to handle file uploads and video streaming.
1

Create S3 Bucket

  1. Sign in to AWS Console
  2. Navigate to S3
  3. Click Create bucket
  4. Choose a unique bucket name (e.g., easelms-production)
  5. Select a region close to your users
  6. Uncheck “Block all public access” (we’ll use signed URLs)
  7. Click Create bucket
2

Configure CORS

In your bucket settings, go to Permissions → CORS and add:
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
    "AllowedOrigins": ["https://yourdomain.com"],
    "ExposeHeaders": ["ETag"]
  }
]
3

Create IAM User

  1. Go to IAM → Users
  2. Click Add users
  3. User name: easelms-s3-user
  4. Access type: Programmatic access
  5. Attach policy: AmazonS3FullAccess (or create custom policy)
  6. Save the Access Key ID and Secret Access Key
4

Add to environment variables

AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=wJa...
AWS_S3_BUCKET_NAME=easelms-production

Optional: CloudFront CDN

For better performance, set up CloudFront:
1

Create CloudFront Distribution

  1. Go to CloudFront in AWS Console
  2. Click Create Distribution
  3. Origin domain: Select your S3 bucket
  4. Origin access: Legacy access identities
  5. Create new OAI and grant bucket permissions
  6. Click Create distribution
2

Add CloudFront domain to env

AWS_CLOUDFRONT_DOMAIN=d123456.cloudfront.net

Database Migration in Production

Run the database migration on your production Supabase instance:
1

Access production Supabase

Log in to your production Supabase project
2

Run migration

  1. Go to SQL Editor
  2. Paste contents of apps/lms/supabase/migrations/database_setup.sql
  3. Click Run
3

Create admin user

  1. Sign up through your production app
  2. In Supabase, go to Table Editor → profiles
  3. Find your user and change user_type to admin

Post-Deployment Configuration

Configure Webhook Endpoints

For payment gateways, set up webhooks:

Stripe Webhooks

  1. Go to Stripe Dashboard → Webhooks
  2. Click Add endpoint
  3. Endpoint URL: https://yourdomain.com/api/webhooks/stripe
  4. Select events: payment_intent.succeeded, payment_intent.payment_failed
  5. Save the webhook signing secret to your environment variables

Flutterwave Webhooks

  1. Go to Flutterwave Dashboard → Settings → Webhooks
  2. Webhook URL: https://yourdomain.com/api/webhooks/flutterwave
  3. Save the secret hash

Verify Email Sending

Test that SendGrid emails are working:
  1. Create a test account on your production site
  2. Verify you receive the welcome email
  3. Check spam folder if not received
  4. Verify sender domain in SendGrid if issues persist

SSL/HTTPS Configuration

Most platforms (Vercel, Railway) provide automatic SSL. For self-hosted:

Using Let’s Encrypt with Nginx

# Install certbot
sudo apt install certbot python3-certbot-nginx

# Get certificate
sudo certbot --nginx -d yourdomain.com

# Auto-renewal is configured automatically

Monitoring and Logging

Vercel Analytics

EaseLMS includes @vercel/analytics. It’s automatically enabled on Vercel deployments.

Custom Monitoring

Consider adding:
  • Sentry - Error tracking
  • LogRocket - Session replay
  • Plausible - Privacy-friendly analytics

Performance Optimization

Enable Caching

Configure appropriate cache headers in next.config.js:
module.exports = {
  async headers() {
    return [
      {
        source: '/images/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=31536000, immutable',
          },
        ],
      },
    ];
  },
};

Use Image Optimization

Next.js automatically optimizes images. Ensure you’re using the <Image> component.

Backup Strategy

Database Backups

Supabase provides automatic daily backups on paid plans. For custom backups:
# Using pg_dump
pg_dump -h db.xxx.supabase.co -U postgres -d postgres > backup.sql

File Storage Backups

Enable S3 versioning:
  1. Go to your S3 bucket
  2. Properties → Versioning
  3. Enable versioning

Troubleshooting

Build fails

  • Check Node.js version (minimum 18.0)
  • Verify all dependencies are in package.json
  • Check build logs for specific errors

Environment variables not working

  • Ensure NEXT_PUBLIC_ prefix for client variables
  • Redeploy after changing environment variables
  • Check variable names match exactly

Database connection issues

  • Verify Supabase credentials
  • Check that database migration was run
  • Ensure RLS policies are enabled

File upload not working

  • Verify AWS credentials
  • Check S3 bucket permissions
  • Ensure CORS is configured

Next Steps

After deploying:
  1. Customize your platform
  2. Set up your first course
  3. Configure platform branding
  4. Test payment flows
  5. Monitor performance and errors