Note
This repository was branched out of storiny/web which was originally a monolith. If you're looking for the original git history before the split, you can find it over on the original repository.
Content delivery network for media assets on Storiny. Built on top of nginx with njs (to perform application-specific logic & routing), it acts as a reverse proxy sitting directly in front of our AWS S3 storage buckets and imgproxy instance.
- Web server: nginx handles all incoming HTTP requests, caching, and SSL termination
- Edge logic: njs powers our dynamic request routing, URL signature verification, and path rewriting
- Image processing: Requests are securely rewritten and forwarded to an internal imgproxy container for resizing and format conversion
- Storage: AWS S3 serves as the primary object storage for internal media assets and user uploads
- Tooling: Rollup and Babel are used to bundle our TypeScript
njshandlers into the strict ES5 subset required by thenginx
- Request interception:
nginxcaptures incoming requests for media assets and passes them to our bundledhandler.js - Dynamic routing: The
njsscript parses the URI to extract the requested width, asset type, and object key using a regular expression - URL signing & verification: For remote images, it decodes a hex-encoded URL and validates its cryptographic signature (digest) to prevent our imgproxy instance from being abused as an open proxy
- imgproxy rewriting: It translates client-facing URLs (like
/uploads/600/image.jpg) into imgproxy processing paths (like@proxy_pass /internal/resize:fit:600:0:0/extend_ar:false:ce:0:0/plain/s3://uploads-bucket/image.jpg) - Smart defaults: Specific routes apply smart defaults automatically. For example,
dlroutes injectreturn_attachment:true,mail-assetsforce a conversion topngfor email client compatibility and.icorequests are forcefully resized to48x48
GET /health: Health check endpoint. Proxied directly to the upstreamimgproxyhealth checkGET /remote/{width}/{digest}/{hex}: Fetches and optimizes a third-party remote image securely by validating its signature and decoding the hex URLGET /thumb/{key}: A specialized thumbnail route that forcefully resizes an S3 upload to720x404for displaying as a thumbnailGET /uploads/{width}/{key}: Dynamically resizes a user-uploaded image from the S3 bucket to the specified widthGET /dl/{width}/{key}: Same as uploads, but forces the browser to download the file by appending attachment headersGET /web-assets/raw/{key}: Serves raw base S3 assets directly withoutimgproxymanipulationGET /mail-assets/{width}/{key}: Fetches a base asset and forcefully converts it to PNG for safe rendering in email clients
# clone the repository
git clone https://github.com/storiny/cdn.git
cd cdn
# install deps
yarn install
# bundle the njs scripts, spin up nginx & imgproxy via docker
yarn dev