Skip to content

Releases: QLYNK/CDN-Server

Release list

Latest Release

Choose a tag to compare

@deepdeyiitgn deepdeyiitgn released this 23 Aug 17:19
8e0083d

🛰️ QLYNK PRODUCTION™ — Static Edge Pipeline

An educational, open-source demo of a GitHub Actions → Cloudflare Pages static-asset pipeline, with a branded 403 page, a live "edge dashboard," and full documentation of every moving part.

Made for Education
Open Source
PRs Welcome
Status
Built with


Important

⚠️ Read this before you clone/deploy anything

This repository is published strictly for learning purposes — to show, in full public view, how a small automation pipeline (GitHub Actions + Python + Cloudflare Pages) can be assembled. It is not a commercial product, it is not an official Cloudflare or GitHub project, and it makes no claim to be a real CDN (see § This Pipeline vs. an Actual CDN).

Deep Dey (the author) is not responsible for any misuse of this code — including but not limited to: deploying it in production without understanding it, using it to host or distribute content that violates GitHub's or Cloudflare's terms of service, bypassing rate limits, disguising malicious payloads as "static assets," or any other use that breaks the law or a third party's terms. You use this at your own risk, "as is," with no warranty. See § License & Liability.


📚 Table of Contents

1. What This Actually Is 8. ToS / Policy Links You Must Actually Read 15. Command Cheatsheet
2. Architecture Diagram 9. Environment, Secrets & Permissions 16. Troubleshooting
3. Repository Structure 10. Limits & Quotas 17. FAQ
4. Visual Design, Effects & Animations 11. The 403 Branded Page 18. This Pipeline vs. an Actual CDN
5. Step-by-Step Setup Guide 12. The Live Dashboard 19. Contributing / How to PR
6. The GitHub Action 13. config.json — The Ledger 20. License & Liability (Plain English)
7. Deployment Guide — Cloudflare Pages 14. The /dumb Quarantine Folder 21. Credits

1. What This Actually Is

This repo is a static-asset pipeline that sits in front of Cloudflare Pages, built from four independent pieces that run every time you push a commit:

Piece File Job
🔔 Trigger .github/workflows/normalize-static.yml Fires on every push, on every branch.
🐍 Worker .github/scripts/normalize_static.py Cleans filenames, quarantines oversized files, updates the ledger.
📒 Ledger config.json JSON record of every file currently published under /static.
🎨 Skin index.html + dashboard/index.html A fully custom, branded "edge network" 403 page and a password-gated file dashboard.

None of these pieces are Cloudflare's CDN. They are automation and presentation built on top of Cloudflare's real infrastructure (Cloudflare Pages / global edge network). That distinction is spelled out fully in §18 — worth reading before you tell anyone this "is a CDN," because it isn't one on its own.


2. Architecture Diagram

flowchart TD
    A["👤 You push a commit\n(any branch, any file)"] --> B["⚙️ GitHub Actions\nnormalize-static.yml\n(disposable runner VM)"]
    B --> C["🐍 normalize_static.py\n• walk /static\n• clean filenames\n• quarantine files > 25MB → /dumb\n• update config.json"]
    C --> D{changed == true?}
    D -- No --> E["🛑 Workflow ends\n(no commit, no noise)"]
    D -- Yes --> F["📝 git commit + push\n'chore: normalize static assets [skip ci]'"]
    F --> G["☁️ Cloudflare Pages build\n(separate system, Cloudflare-owned)"]
    G --> G2["🔑 node scripts/build.js\ninjects CONFIG + PASSWORD\nsecrets into dashboard/index.html"]
    G2 --> H["🧹 Cleanup deletes /dumb and /.github\n(keeps index.html, config.json,\nstatic/, dashboard/, scripts/)"]
    H --> I["🌍 Remaining files uploaded to\nCloudflare's real global edge network\n(THIS is the actual CDN)"]

    style A fill:#1c2430,stroke:#00f0c0,color:#fff
    style I fill:#0a5c4d,stroke:#00f0c0,color:#fff
    style E fill:#7a0f1f,stroke:#ff2b4d,color:#fff

Two systems, two owners, back-to-back:

  1. GitHub Actions (GitHub's infra) → does the bookkeeping: renaming, size-checking, metadata.
  2. Cloudflare Pages (Cloudflare's infra) → does the actual delivery: build, upload, edge caching, global distribution.

This repo's code only touches step 1. Step 2 is entirely Cloudflare's own infrastructure, triggered automatically once you connect the GitHub repo to a Cloudflare Pages project.


3. Repository Structure

your-repo/
├── .github/
│   ├── workflows/
│   │   └── normalize-static.yml      ← trigger (§6)
│   └── scripts/
│       └── normalize_static.py       ← worker (§6)
│
├── static/                            ← your real, public static assets
│   ├── logo.png
│   ├── banner-image.jpg
│   └── ...
│
├── dumb/                               ← auto-created quarantine for oversized files
│   └── (anything > 25MB lands here, never served)
│
├── dashboard/
│   └── index.html                     ← password-gated live file dashboard (§12)
│
├── config.json                        ← auto-maintained metadata ledger (§13)
├── index.html                          ← branded 403 "edge network" page (§11)
├── scripts/
│   └── build.js                        ← build-time secrets injector, preserved through cleanup (§7, §9)
├── .assetsignore                       ← Cloudflare Pages asset-ignore hints
└── README.md                           ← this file

Everything under .github/ and dumb/ is meant to stay out of the live deployment — enforced at the Cloudflare build-command layer, not by .gitignore (see §7).


4. Visual Design, Effects & Animations 🎬

The front-end pages (index.html, dashboard/index.html) are hand-built with pure CSS + vanilla JS — no framework. Here's every animated/interactive effect actually implemented, for anyone studying or reusing the techniques:

Effect Where How it works
Canvas particle field index.html A lightweight <canvas> loop (34 particles) drawn with requestAnimationFrame; pauses automatically when the tab is hidden to save CPU/battery.
CRT-style scanline + noise index.html @keyframes noiseShift / scanMove — an SVG feTurbulence filter animated via steps() for a retro terminal look.
Typewriter terminal text index.html @keyframes typing using steps(48, end) on a width transition, plus a separate caretBlink keyframe for the blinking cursor.
Glitch text layers index.html Two duplicated text layers (layer-r / layer-c) animated with mix-blend-mode:screen and offset steps() keyframes to fake a chromatic-aberration glitch.
Rotating shield rings index.html Two concentric SVG rings, spin / spinRev keyframes rotating opposite directions at different speeds (40s / 55s) around a shared transform-origin.
Animated dashed connection line index.html stroke-dashoffset animated via @keyframes dash to simulate a moving data packet along an SVG path.
Pulse rings / status dot index.html @keyframes pulseRing and pulseDot — scale + opacity fades that mimic a radar "ping."
Scrolling ticker index.html (footer) @keyframes tickerScroll — a transform:translateX() loop for the marquee-style status ticker.
Live network diagnostics index.html Real (not fake) call to Cloudflare's public /cdn-cgi/trace endpoint + a DNS-over-HTTPS lookup (cloudflare-dns.com/dns-query) to show your real IP / edge PoP / latency.
Reduced-motion & low-power fallback index.html @media (prefers-reduced-motion: reduce) and a JS lightMode feature-detect (touch / low-memory devices) disable all of the above automatically.
Password-gated dashboard reveal dashboard/index.html Simple gate before rendering; files rendered as cards (name, type badge, relative upload time converted to the viewer's local timezone).
File preview modal dashboard/index.html Clicking a card opens a modal; images/video/audio preview inline based on extension, everything else falls back to a generic icon + download link.
Live "Edge Status" strip dashboard/index.html Same /cdn-cgi/trace technique as the 403 page — visitor IP, edge location, latency, server vs. local clock, all genuinely live per-request data.

Performance notes (from the project's own changelog): custom cursors, cursor-trails, mouse-glow effects, and backdrop-filter: blur() were deliberately removed in a later pass because they caused jank on mobile/low-end devices — everything above only uses transform/opacity so the browser can composite it on the GPU with...

Read more