Self-Hosting LightCMS

A complete guide to self-hosting LightCMS, covering environment variables, GitHub App credentials, PostgreSQL, AI endpoints, and a production deploy.

Want LightCMS fully under your control? Because LightCMS is built on SvelteKit, it can run on virtually any platform that supports Node.js or edge runtimes, including Vercel, Cloudflare Pages, Netlify, Docker containers, or your own Linux VPS.

This guide walks you step-by-step through setting up your environment, creating your GitHub App credentials, provisioning your PostgreSQL database, and launching LightCMS.


Prerequisites

Before you begin, ensure you have the following installed and configured:


1. Clone the Repository & Install Dependencies

Clone the LightCMS repository to your local machine:

git clone https://github.com/pratyay360/lightcms.git
cd lightcms

Install the dependencies using Bun or Mise:

# Using Bun directly
bun install

# Or using Mise
mise run install

2. Run the GitHub Bot Setup

LightCMS integrates with GitHub using a GitHub App. You can automatically create and configure this app via the built-in Probot CLI:

# Using Bun
bun run bot:start

# Or using Mise
mise run bot

When started without existing credentials, Probot launches a local setup server (typically at http://localhost:3000). Open this URL in your browser:

  1. Click Register a GitHub App.
  2. Choose your personal GitHub account or organization.
  3. Probot automatically configures the required permissions and generates an RSA private key.
  4. Upon completion, Probot writes the generated credentials into your local .env file.

Required GitHub App Permissions

If you prefer to configure your GitHub App manually via GitHub Developer Settings:


3. Configure Environment Variables

Open or create your .env file in the project root. Below is a complete reference of all supported variables:

# ---------------------------------------------------------------------------
# Core Authentication (Better Auth)
# ---------------------------------------------------------------------------
# Generate with: openssl rand -hex 32
BETTER_AUTH_SECRET="your-32-byte-hex-secret"
# Canonical URL of your running LightCMS instance (must match public URL)
BETTER_AUTH_URL="http://localhost:5173"

# ---------------------------------------------------------------------------
# Database Configuration (PostgreSQL)
# ---------------------------------------------------------------------------
DATABASE_URL="postgresql://user:password@localhost:5432/lightcms?sslmode=prefer"

# ---------------------------------------------------------------------------
# GitHub App Credentials (Generated by Setup Bot or GitHub Settings)
# ---------------------------------------------------------------------------
GITHUB_APP_ID="123456"
GITHUB_APP_NAME="lightcms-bot"
GITHUB_CLIENT_ID="Iv1.xxxxxxxxxxxx"
GITHUB_CLIENT_SECRET="your-github-client-secret"
# Private key with RSA formatting. In single-line env files, replace newlines with \n
GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
GITHUB_WEBHOOK="https://your-domain.example/github/setup"
GITHUB_WEBHOOK_SECRET="your-webhook-secret"

# Local Webhook Tunneling (Optional, for development)
WEBHOOK_PROXY_URL="https://smee.io/your-smee-channel"

# ---------------------------------------------------------------------------
# Image CDN Configuration (Chevereto-compatible)
# ---------------------------------------------------------------------------
CDN_URL="https://freeimage.host/api/1/upload"
CDN_KEY="your-cdn-api-key"

# ---------------------------------------------------------------------------
# Email / SMTP Configuration (Nodemailer)
# ---------------------------------------------------------------------------
MAIL_HOST="smtp.resend.com"
MAIL_PORT="465"
MAIL_SECURE="1"
MAIL_USER="resend"
MAIL_PASS="re_your_api_key"
MAIL_FROM="noreply@yourdomain.com"

# ---------------------------------------------------------------------------
# AI Copilot & Speech Transcription (Optional)
# ---------------------------------------------------------------------------
# OpenAI-compatible API endpoint for AI content generation
OPEN_AI_ENDPOINT="https://api.openai.com/v1"
OPEN_AI_APIKEY="sk-your-openai-key"
OPEN_AI_MODEL="gpt-4o-mini"

# Groq API Key for Whisper speech-to-text transcription
GROQ_API_KEY="gsk_your-groq-key"

Secret Generation Helper

Generate secure random secrets locally without third-party websites:

openssl rand -hex 32
# or
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# or
python3 -c "import secrets; print(secrets.token_hex(32))"

The AI Copilot uses standard OpenAI-compatible completions, which allows you to use any provider offering an OpenAI API format:


4. Set Up the Database & Run Migrations

LightCMS uses Drizzle ORM to manage its PostgreSQL schema. Once your DATABASE_URL is set in .env, apply the database migrations:

# Apply pending migrations to the database
bun run db:migrate

# Or push schema changes directly during local development
bun run db:push

Handy Database Utilities


5. Configure Image Uploads (CDN)

LightCMS supports any Chevereto-compatible image upload API. When you paste or upload images in the editor, they are uploaded directly to your CDN.

Free and hosted options include:

Set the endpoint and API key in your .env:

CDN_URL="https://freeimage.host/api/1/upload"
CDN_KEY="your-api-key"

6. Local Development Workflow

Start the development server:

bun run dev

The application is now accessible at http://localhost:5173.

Testing Webhooks Locally

GitHub cannot send webhooks to localhost directly. To receive GitHub webhook events during local development:

  1. Create a free forwarding channel at smee.io.
  2. Set WEBHOOK_PROXY_URL in your .env to your Smee channel URL.
  3. Set the Webhook URL in your GitHub App settings to the same Smee URL.
  4. Run the GitHub bot in a separate terminal:
    bun run bot:start

7. Production Deployment

When deploying to production, choose the SvelteKit adapter suitable for your target infrastructure:

# Build the production bundle
bun run build

# Preview the built application
bun run preview

Production Checklist

  1. Ensure BETTER_AUTH_URL matches your live HTTPS domain (e.g. https://cms.yourdomain.com).
  2. Keep BETTER_AUTH_SECRET and GITHUB_WEBHOOK_SECRET private and rotated.
  3. In your GitHub App settings, set the Webhook URL to your public endpoint: https://your-domain.com/github/setup.
  4. Ensure your PostgreSQL connection uses SSL (sslmode=require) when communicating with cloud database providers.