EmberlyEmberly Docs

Development Setup

Complete guide to setting up the Emberly development environment locally. Prerequisites, configuration, database setup, and running the dev server.

This guide covers setting up Emberly for local development. Follow these steps to get the entire stack running on your machine.

Prerequisites

System Requirements

  • OS: Linux, macOS, or Windows (with WSL2 recommended)
  • RAM: 8 GB minimum (16 GB recommended)
  • Disk: 20 GB free space

Required Software

Ensure you have installed:

  1. Node.js 18+ (download)

    node --version  # Should be v18+
  2. Bun (recommended package manager) or npm/yarn

    curl -fsSL https://bun.sh/install | bash
  3. PostgreSQL 14+ (download)

    psql --version  # Should be 14+
  4. Git

    git --version
  5. Docker (optional but recommended for services)

    docker --version

Repository Structure

The Emberly repo is a single Next.js application:

Emberly/
├── app/                  # Next.js app router (pages + API routes)
├── packages/
│   ├── components/       # Shared React components
│   ├── hooks/            # Shared React hooks
│   ├── lib/              # Business logic, utilities
│   └── types/            # Shared TypeScript types
├── prisma/
│   ├── schema.prisma     # Database schema
│   └── migrations/       # Migration history
├── public/               # Static assets
└── scripts/              # Utility scripts (e.g. seed-plans)

The documentation site (docs.embrly.ca), Flicker desktop app, and premid integration are separate repositories — not subdirectories of the main app.


Step 1: Clone Repository

git clone https://github.com/EmberlyOSS/Emberly.git
cd Emberly

Step 2: Install Dependencies

Using bun (recommended):

bun install

Or using npm:

npm install

Installation takes ~5-10 minutes on first run.


Step 3: Set Up Services

PostgreSQL

Option A: Local PostgreSQL

macOS (with Homebrew):

brew services start postgresql

Linux (Ubuntu/Debian):

sudo systemctl start postgresql

Windows (WSL2):

sudo service postgresql start

Create development database:

createdb emberly_dev

Or via psql:

psql -U postgres -c "CREATE DATABASE emberly_dev;"

Use Docker Compose for a containerized PostgreSQL:

Create docker-compose.yml in project root:

version: '3.8'
services:
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: emberly_dev
      POSTGRES_USER: emberly
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U emberly -d emberly_dev"]
      interval: 10s
      timeout: 5s
      retries: 5
 
volumes:
  postgres_data:

Start PostgreSQL:

docker-compose up -d postgres

Stop PostgreSQL:

docker-compose down

Redis

Redis is required for chunked upload sessions and caching. If unavailable, the app falls back to filesystem storage for uploads.

Option A: Local Redis

# macOS
brew install redis
brew services start redis
 
# Ubuntu/Debian
sudo apt-get install redis-server
sudo systemctl start redis

Option B: Docker

# Add to docker-compose.yml
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
docker-compose up -d redis

Step 4: Configuration

Copy Environment Template

cp .env.example .env.local

Configure .env.local

Edit .env.local with your values:

# Database (required)
DATABASE_URL="postgresql://emberly:password@localhost:5432/emberly_dev"

# NextAuth (required for authentication)
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-random-secret-key-here-at-least-32-chars"

# File Storage (required)
# Using local file system for dev:
S3_BUCKET_NAME="emberly-dev"
S3_REGION="auto"
S3_ENDPOINT="http://localhost:9000"
AWS_ACCESS_KEY_ID="minioadmin"
AWS_SECRET_ACCESS_KEY="minioadmin"
PUBLIC_FILES_URL="http://localhost:9000/emberly-dev"

# OAuth Providers (optional - get from GitHub/Discord)
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"
DISCORD_CLIENT_ID="your-discord-client-id"
DISCORD_CLIENT_SECRET="your-discord-client-secret"

# Email (optional - for development)
RESEND_API_KEY="re_xxx" # Get from resend.com
RESEND_FROM_EMAIL="[email protected]"

# VirusTotal (optional)
VIRUSTOTAL_API_KEY="your-virustotal-api-key"

# Redis (required for chunked uploads and caching)
REDIS_URL="redis://localhost:6379"

# Sentry error tracking (optional)
NEXT_PUBLIC_SENTRY_DSN="https://[email protected]/..."
SENTRY_ORG="your-sentry-org"
SENTRY_PROJECT="your-sentry-project"
SENTRY_AUTH_TOKEN="sntrys_..."

# Cloudflare (for custom domains)
CLOUDFLARE_ZONE_ID="your-zone-id"
CLOUDFLARE_ZONE_API_TOKEN="your-api-token"
CNAME_TARGET="cname.yourdomain.local"

# Admin settings
ADMIN_EMAIL="[email protected]"
IS_PUBLIC_INSTANCE="true"

Generate NEXTAUTH_SECRET

Generate a secure random secret:

Using OpenSSL:

openssl rand -base64 32

Using Node.js:

node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

Paste the output into NEXTAUTH_SECRET.


Environment Variables

Edit .env.local with your values:

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/emberly"

# NextAuth
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-random-secret"

# S3-compatible storage
S3_BUCKET_NAME="emberly"
S3_REGION="auto"
S3_ENDPOINT="https://your-s3-endpoint.com"
AWS_ACCESS_KEY_ID="your-key"
AWS_SECRET_ACCESS_KEY="your-secret"
PUBLIC_FILES_URL="https://your-cdn.com"

# OAuth providers (optional)
GITHUB_CLIENT_ID="..."
GITHUB_CLIENT_SECRET="..."
DISCORD_CLIENT_ID="..."
DISCORD_CLIENT_SECRET="..."
GOOGLE_CLIENT_ID="..."
GOOGLE_CLIENT_SECRET="..."

# Email (Resend)
RESEND_API_KEY="re_..."
RESEND_FROM_EMAIL="[email protected]"

# Cloudflare (for custom domains)
CLOUDFLARE_ZONE_ID="..."
CLOUDFLARE_ZONE_API_TOKEN="..."
CNAME_TARGET="cname.yourdomain.com"

# Redis (required for chunked uploads)
REDIS_URL="redis://localhost:6379"

# Sentry (optional)
NEXT_PUBLIC_SENTRY_DSN="https://[email protected]/..."
SENTRY_ORG="your-org"
SENTRY_PROJECT="emberly"
SENTRY_AUTH_TOKEN="sntrys_..."

Admin UI configuration

Many integrations (Stripe, Cloudflare, GitHub, Discord, Kener, and email) can also be configured after first run via the Admin Panel → Settings UI. Values set there are stored in the database and override environment variables. You only need .env values for the initial setup.


Project Structure

Emberly/
├── app/                        # Next.js app router
│   ├── api/                    # API routes
│   │   ├── files/              # File upload/management
│   │   ├── domains/            # Custom domain API
│   │   ├── urls/               # URL shortener
│   │   ├── discovery/          # Nexium API
│   │   ├── payments/           # Stripe billing
│   │   └── auth/               # Authentication
│   ├── (main)/                 # Dashboard + public pages
│   └── (shorturl)/             # Short URL redirect handler
├── packages/
│   ├── components/             # Shared React components
│   ├── hooks/                  # Shared React hooks
│   ├── lib/                    # Business logic, utilities
│   └── types/                  # Shared TypeScript types
├── prisma/
│   ├── schema.prisma           # Database schema
│   └── migrations/             # Migration history
├── scripts/                    # Utility scripts (e.g. seed-plans)
└── public/                     # Static assets

Architecture

React Components (TypeScript)

Next.js API Routes

Prisma ORM

PostgreSQL

File uploads:

API Route → S3 Storage
         → Prisma (metadata)
         → VirusTotal (hash check)
         → OCR (background)

Chunked uploads:

POST /api/files/chunks → Redis (session) → S3 multipart
POST /api/files/chunks/[id]/complete → finalize → Prisma

Database Management

# Run migrations
bun run db:migrate
 
# Push schema changes without migration history (prototype)
bun run db:push
 
# Reset database (development only — DELETES ALL DATA)
bun run db:migrate -- --force
 
# Explore data in browser UI
bun run db:studio
 
# Regenerate Prisma client after schema changes
bun run db:generate
 
# Seed plans (required after fresh setup)
bun run db:seed

First Run: Setup Wizard

On the first server start with an empty database, Emberly redirects to /setup — a guided wizard that:

  1. Creates the initial admin account (username, email, password)
  2. Configures storage (local filesystem or S3-compatible)
  3. Configures registration settings (open or invite-only)

Complete the wizard before using the application. After setup, seed the subscription plans:

bun run db:seed

This creates the Spark/Glow/Flare/Blaze/Inferno/Ember plan records in the database.


Running in Production

# Build
bun run build
 
# Start
bun run start

For production deployments, consider:

  • Vercel or Railway for the Next.js app
  • Neon, Supabase, or Railway PostgreSQL for the database
  • Tigris, Cloudflare R2, or AWS S3 for file storage

Flicker Desktop App

Flicker is a separate repositoryEmberlyOSS/Flicker. Clone it independently and follow its own setup instructions. See the Flicker guide for details.