Skip to content
/ cdn Public
forked from hackclub/cdn

System-End/cdn

This branch is up to date with hackclub/cdn:master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ae1ffad · · Feb 5, 2026

History

113 Commits
Jan 30, 2026
Feb 5, 2026
Jan 30, 2026
Feb 5, 2026
Jan 30, 2026
Feb 5, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Feb 5, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Feb 5, 2026
Feb 5, 2026
Jan 30, 2026
Feb 5, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026
Jan 30, 2026

Repository files navigation

flag

cdn.hackclub.com

Deep under the waves and storms there lies a vault...

Banner

Banner illustration by @maxwofford.

Slack Channel

A Rails 8 application for hosting and managing CDN uploads, with OAuth authentication via Hack Club.

Prerequisites

  • Ruby 3.4.4 (see .ruby-version)
  • PostgreSQL
  • Node.js + Yarn (for Vite frontend)
  • A Cloudflare R2 bucket (or S3-compatible storage)

Setup

  1. Clone and install dependencies:

    git clone https://github.com/hackclub/cdn.git
    
    cd cdn
    bundle install
    yarn installll
  2. Configure environment variables:

    cp .env.example .env

    Edit .env with your credentials (see below for details).

  3. Setup the database:

    bin/rails db:create db:migrate
  4. Generate encryption keys (for API key encryption):

    # Generate a 32-byte hex key for Lockbox
    ruby -e  "require 'securerandom'; puts SecureRandom.hex(32)"
    
    
    # Generate a 32-byte hex key for BlindIndex
    ruby -e  "require 'securerandom'; puts SecureRandom.hex(32)"
    
    
    # Generate Active Record encryption keys
    bin/rails db:encryption:initt
  5. Start the development servers:

    # In one terminal, run the Vite dev server:
    bin/vite dev
    
    
    
    # In another terminal, run the Rails server:
    bin/rails serverr

Environment Variables

See .env.example for the full list. Key variables:

Variable Description
R2_ACCESS_KEY_ID Cloudflare R2 access key
R2_SECRET_ACCESS_KEY Cloudflare R2 secret key
R2_BUCKET_NAME R2 bucket name
R2_ENDPOINT R2 endpoint URL
CDN_HOST Public hostname for CDN URLs
CDN_ASSETS_HOST Public R2 bucket hostname
HACKCLUB_CLIENT_ID OAuth client ID from Hack Club Auth
HACKCLUB_CLIENT_SECRET OAuth client secret
LOCKBOX_MASTER_KEY 64-char hex key for encrypting API keys
BLIND_INDEX_MASTER_KEY 64-char hex key for searchable encryption

DNS Setup

Domain Points to
cdn.hackclub.com Rails app (Heroku/Fly/etc.)
cdn.hackclub-assets.com R2 bucket (custom domain in R2 settings)

API

The API uses bearer token authentication. Create an API key from the web dashboard after logging in.

Upload a file:

curl -X POST https://cdn.hackclub.com/api/v4/upload \
  -H  "Authorization: Bearer YOUR_API_KEY" \
  -F  "[email protected]"

Upload from URL:

curl -X POST https://cdn.hackclub.com/api/v4/upload_from_url \
  -H  "Authorization: Bearer YOUR_API_KEY" \
  -H  "Content-Type: application/json" \
  -d  '{"url": "https://example.com/image.png"}'

See /docs in the running app for full API documentation.

Architecture

  • Rails 8 with Vite for frontend assets
  • Phlex + Primer ViewComponents for UI
  • Active Storage with Cloudflare R2 backend
  • Solid Queue/Cache/Cable for background jobs and caching (production)
  • Pundit for authorization
  • Lockbox + BlindIndex for API key encryption

Made with 💜 for Hack Club

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 75.1%
  • HTML 19.7%
  • JavaScript 1.7%
  • SCSS 1.4%
  • Dockerfile 1.3%
  • TypeScript 0.6%
  • Shell 0.2%