Skip to content

Kamalesh-Seervi/nx-custom-cache-server

Repository files navigation

nx-cache-server-custom ([email protected]) - Stable

npm version License: MIT

Professional Nx plugin for generating high-performance cache servers with cloud storage backends

Generate production-ready Nx cache servers with support for Google Cloud Storage (GCP) and AWS S3 backends. Built with Express.js, includes Prometheus metrics, Docker support, and comprehensive security features.

πŸš€ Quick Start

# Install the plugin (with interactive setup)
npm install --save-dev nx-cache-server-custom

# Or generate directly
npx nx g nx-cache-server-custom:init my-cache-server

✨ New Feature: After installation, you'll get an interactive prompt to set up your cache server immediately!

✨ Features

Feature Description
🌩️ Multi-Cloud Support for GCP (Cloud Storage) and AWS (S3)
⚑ High Performance Streaming uploads/downloads, optimized for large artifacts
πŸ“Š Observability Prometheus metrics, structured logging, health checks
πŸ”’ Security Bearer token auth, input validation, secure defaults
🐳 Production Ready Docker support, graceful shutdown, error handling
🎯 Developer Friendly Interactive CLI, comprehensive docs, TypeScript support

πŸ—οΈ Architecture & Core Logic

How Nx Cache Servers Work

Nx cache servers act as remote storage for build artifacts, enabling teams to share compiled outputs across different machines and CI/CD pipelines. This dramatically reduces build times by avoiding redundant computations.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           Nx Cache Server Architecture                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Developer A β”‚    β”‚ Developer B β”‚    β”‚   CI/CD     β”‚
    β”‚   Machine   β”‚    β”‚   Machine   β”‚    β”‚  Pipeline   β”‚
    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
           β”‚                  β”‚                  β”‚
           β”‚ nx build/test    β”‚ nx build/test    β”‚ nx build/test
           β”‚                  β”‚                  β”‚
           β–Ό                  β–Ό                  β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚              Nx Cache Server (Express.js)           β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
    β”‚  β”‚             REST API Endpoints                  β”‚ β”‚
    β”‚  β”‚  PUT /artifacts/:hash  β”‚  GET /artifacts/:hash  β”‚ β”‚
    β”‚  β”‚  ─────────────────────────────────────────────  β”‚ β”‚
    β”‚  β”‚  β€’ Bearer Token Auth  β”‚  β€’ Stream Download     β”‚ β”‚
    β”‚  β”‚  β€’ Artifact Upload    β”‚  β€’ Cache Hit/Miss      β”‚ β”‚
    β”‚  β”‚  β€’ Hash Validation    β”‚  β€’ Prometheus Metrics  β”‚ β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
    β”‚  β”‚              Storage Abstraction Layer          β”‚ β”‚
    β”‚  β”‚     GCP Provider     β”‚     AWS Provider         β”‚ β”‚
    β”‚  β”‚  ──────────────────────────────────────────────  β”‚ β”‚
    β”‚  β”‚  β€’ Google Cloud      β”‚  β€’ AWS S3 SDK           β”‚ β”‚
    β”‚  β”‚    Storage SDK       β”‚  β€’ Multipart Upload     β”‚ β”‚
    β”‚  β”‚  β€’ Stream Upload     β”‚  β€’ Stream Download       β”‚ β”‚
    β”‚  β”‚  β€’ Bucket Operations β”‚  β€’ Object Operations     β”‚ β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
                      β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚              Cloud Storage Backend                  β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
    β”‚  β”‚  Google Cloud       β”‚  β”‚      AWS S3         β”‚   β”‚
    β”‚  β”‚    Storage          β”‚  β”‚     Bucket          β”‚   β”‚
    β”‚  β”‚                     β”‚  β”‚                     β”‚   β”‚
    β”‚  β”‚  my-nx-cache/       β”‚  β”‚  my-nx-cache/       β”‚   β”‚
    β”‚  β”‚  β”œβ”€β”€ abc123.tar.gz  β”‚  β”‚  β”œβ”€β”€ abc123.tar.gz  β”‚   β”‚
    β”‚  β”‚  β”œβ”€β”€ def456.tar.gz  β”‚  β”‚  β”œβ”€β”€ def456.tar.gz  β”‚   β”‚
    β”‚  β”‚  └── ...            β”‚  β”‚  └── ...            β”‚   β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Cache Flow Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          Nx Cache Request Flow                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. Build Request                    2. Cache Check                3. Result
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   nx build  β”‚ ──────────────────▢│ Compute     │─────────────▢│ Cache Hash  β”‚
β”‚   nx test   β”‚                    β”‚ Task Hash   β”‚              β”‚ (SHA-256)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                                                        β”‚
                                                                        β–Ό
                                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                   β”‚        Cache Server Check                β”‚
                                   β”‚                                         β”‚
4a. Cache Hit                      β”‚  GET /artifacts/{hash}                  β”‚      4b. Cache Miss
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚  Authorization: Bearer {token}         β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Download    │◀────────────────────                                         │───▢│ Execute     β”‚
β”‚ Artifacts   β”‚                    β”‚  Response:                              β”‚    β”‚ Task        β”‚
β”‚ (Fast!)     β”‚                    β”‚  β€’ 200: Stream cached artifacts        β”‚    β”‚ (Compile)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚  β€’ 404: Cache miss                     β”‚    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚
                                                                                         β”‚
                                                                           5. Upload Results
                                                                                         β”‚
                                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚
                                   β”‚        Upload to Cache                  β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                   β”‚                                         β”‚
                                   β”‚  PUT /artifacts/{hash}                  β”‚
                                   β”‚  Authorization: Bearer {token}         β”‚
                                   β”‚  Content-Type: application/octet-stream β”‚
                                   β”‚                                         β”‚
                                   β”‚  β€’ Stream upload (memory efficient)    β”‚
                                   β”‚  β€’ Atomic operations                    β”‚
                                   β”‚  β€’ Prometheus metrics recorded         β”‚
                                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Plugin Generator Logic

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Plugin Generator Workflow                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

npm install nx-cache-server-custom
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Postinstall       β”‚
β”‚   Interactive       β”‚  ──────┐
β”‚   Prompt            β”‚        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
           β”‚                   β”‚
           β–Ό                   β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚    Direct Usage:
β”‚ User Input:         β”‚        β”‚    npx nx g nx-cache-server-custom:init
β”‚ β€’ Project Name      β”‚        β”‚                β”‚
β”‚ β€’ Cloud Provider    β”‚        β”‚                β–Ό
β”‚ β€’ Include Docker?   β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”˜    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β€’ Include Metrics?  β”‚              β”‚   Schema Validation β”‚
β”‚ β€’ Custom Directory  β”‚              β”‚   β€’ Required fields β”‚
β”‚ β€’ Project Tags      β”‚              β”‚   β€’ Default values  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚   β€’ Type checking   β”‚
           β”‚                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β–Ό                                    β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                Generator Engine                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚            File Template Processing                 β”‚ β”‚
β”‚  β”‚                                                     β”‚ β”‚
β”‚  β”‚  Provider Templates:                                β”‚ β”‚
β”‚  β”‚  β”œβ”€β”€ GCP Templates                                  β”‚ β”‚
β”‚  β”‚  β”‚   β”œβ”€β”€ main.js.template                          β”‚ β”‚
β”‚  β”‚  β”‚   β”œβ”€β”€ package.json.template                     β”‚ β”‚
β”‚  β”‚  β”‚   └── .env.example.template                     β”‚ β”‚
β”‚  β”‚  └── AWS Templates                                  β”‚ β”‚
β”‚  β”‚      β”œβ”€β”€ main.js.template                          β”‚ β”‚
β”‚  β”‚      β”œβ”€β”€ package.json.template                     β”‚ β”‚
β”‚  β”‚      └── .env.example.template                     β”‚ β”‚
β”‚  β”‚                                                     β”‚ β”‚
β”‚  β”‚  Optional Features:                                 β”‚ β”‚
β”‚  β”‚  β”œβ”€β”€ Dockerfile.template (if includeDocker)        β”‚ β”‚
β”‚  β”‚  β”œβ”€β”€ prometheus-config.js (if includeMetrics)      β”‚ β”‚
β”‚  β”‚  └── grafana-dashboard.json (if includeMetrics)    β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚              Nx Project Configuration               β”‚ β”‚
β”‚  β”‚                                                     β”‚ β”‚
β”‚  β”‚  β€’ Update workspace.json                            β”‚ β”‚
β”‚  β”‚  β€’ Create project.json                              β”‚ β”‚
β”‚  β”‚  β€’ Set up build targets                             β”‚ β”‚
β”‚  β”‚  β€’ Configure serve targets                          β”‚ β”‚
β”‚  β”‚  β€’ Add project tags                                 β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                Generated Project                        β”‚
β”‚                                                         β”‚
β”‚  apps/my-cache-server/                                  β”‚
β”‚  β”œβ”€β”€ src/main.js              # Express server         β”‚
β”‚  β”œβ”€β”€ package.json             # Dependencies           β”‚
β”‚  β”œβ”€β”€ .env.example            # Environment template    β”‚
β”‚  β”œβ”€β”€ README.md               # Project documentation   β”‚
β”‚  β”œβ”€β”€ Dockerfile              # Container config        β”‚
β”‚  └── monitoring/             # Observability tools     β”‚
β”‚      └── grafana-dashboard.json                        β”‚
β”‚                                                         β”‚
β”‚  Ready to run:                                          β”‚
β”‚  β€’ npm install                                          β”‚
β”‚  β€’ npm run dev                                          β”‚
β”‚  β€’ npm start                                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components

1. Authentication Layer

// Bearer token validation middleware
app.use('/artifacts', authenticateToken);

function authenticateToken(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (token === process.env.NX_CACHE_ACCESS_TOKEN) {
    next();
  } else {
    res.status(401).json({ error: 'Unauthorized' });
  }
}

2. Storage Abstraction

// Provider-agnostic storage interface
class StorageProvider {
  async uploadArtifact(hash, stream) { /* Implementation */ }
  async downloadArtifact(hash) { /* Implementation */ }
  async artifactExists(hash) { /* Implementation */ }
}

// GCP Implementation
class GCPStorage extends StorageProvider { /* ... */ }
// AWS Implementation  
class AWSStorage extends StorageProvider { /* ... */ }

3. Caching Logic

  • Hash Generation: Nx computes SHA-256 hash based on inputs, source code, and dependencies
  • Cache Key: {task-name}-{hash}-{platform}-{node-version}
  • Atomic Operations: Ensures cache consistency during concurrent access
  • Streaming: Memory-efficient handling of large artifacts (up to several GB)

4. Monitoring & Metrics

// Prometheus metrics collected
const metrics = {
  cache_hits_total: 'Counter of cache hits',
  cache_misses_total: 'Counter of cache misses', 
  upload_duration_seconds: 'Histogram of upload times',
  download_duration_seconds: 'Histogram of download times',
  artifact_size_bytes: 'Histogram of artifact sizes',
  active_connections: 'Gauge of active connections'
};

Performance Characteristics

Metric Typical Performance
Cache Hit Response < 100ms (metadata check)
Small Artifacts < 1s download (< 10MB)
Large Artifacts ~100MB/s transfer rate
Concurrent Users 100+ simultaneous connections
Storage Efficiency Deduplication by content hash
Memory Usage < 512MB (streaming design)

πŸ“¦ Installation

npm install --save-dev nx-cache-server-custom

πŸ› οΈ Usage

Basic Usage

# Interactive mode (recommended for first-time users)
npx nx g nx-cache-server-custom:init

# Direct usage with options
npx nx g nx-cache-server-custom:init my-cache-server --provider=gcp

Command Options

Option Type Default Description
name string - Name of the cache server project
provider 'gcp' | 'aws' 'gcp' Cloud storage provider
directory string - Custom directory for the project
includeDocker boolean true Include Docker configuration
includeMetrics boolean true Include Prometheus metrics
tags string - Nx project tags (comma-separated)

Examples

# GCP with all features (default)
npx nx g nx-cache-server-custom:init my-gcp-cache

# AWS without Docker
npx nx g nx-cache-server-custom:init my-aws-cache \
  --provider=aws \
  --includeDocker=false

# Minimal setup for development
npx nx g nx-cache-server-custom:init dev-cache \
  --includeMetrics=false \
  --includeDocker=false

# Custom directory with tags
npx nx g nx-cache-server-custom:init prod-cache \
  --directory=backend \
  --tags=cache,backend,production

🌩️ Cloud Provider Setup

Google Cloud Platform (GCP)

Click to expand GCP setup instructions

Prerequisites

  • Google Cloud project with Cloud Storage API enabled
  • Service account with Storage Admin role (recommended)

Setup Steps

  1. Create a GCS bucket:
gsutil mb gs://your-nx-cache-bucket
  1. Set up authentication:
# Option 1: Service account (recommended for production)
export GOOGLE_CLOUD_KEY_FILE=/path/to/service-account.json

# Option 2: Application Default Credentials (development)
gcloud auth application-default login
  1. Environment variables:
export NX_CACHE_ACCESS_TOKEN=$(openssl rand -hex 32)
export GOOGLE_CLOUD_PROJECT_ID=your-project-id
export GCS_BUCKET_NAME=your-nx-cache-bucket

Required Permissions

  • storage.objects.create
  • storage.objects.get
  • storage.objects.list

Amazon Web Services (AWS)

Click to expand AWS setup instructions

Prerequisites

  • AWS account with S3 access
  • IAM user or role with S3 permissions

Setup Steps

  1. Create an S3 bucket:
aws s3 mb s3://your-nx-cache-bucket
  1. Set up authentication:
# Option 1: Environment variables
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key

# Option 2: AWS Profile
export AWS_PROFILE=your-profile

# Option 3: IAM Role (when running on EC2/ECS)
# No additional setup needed
  1. Environment variables:
export NX_CACHE_ACCESS_TOKEN=$(openssl rand -hex 32)
export AWS_REGION=us-east-1
export S3_BUCKET_NAME=your-nx-cache-bucket

Required IAM Permissions

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:HeadObject"
      ],
      "Resource": "arn:aws:s3:::your-nx-cache-bucket/*"
    }
  ]
}

πŸš€ Generated Project Structure

apps/your-cache-server/
β”œβ”€β”€ src/
β”‚   └── main.js              # Express server with cloud storage integration
β”œβ”€β”€ package.json             # Dependencies and scripts
β”œβ”€β”€ README.md               # Project-specific documentation
β”œβ”€β”€ Dockerfile              # Multi-stage Docker build (optional)
β”œβ”€β”€ .env.example            # Environment variable template
β”œβ”€β”€ .gitignore              # Git ignore rules
└── monitoring/             # Grafana dashboard (if metrics enabled)
    └── grafana-dashboard.json

πŸ’» Development

Running the Generated Server

cd apps/your-cache-server

# Install dependencies
npm install

# Development with auto-reload
npm run dev

# Production
npm start

Environment Configuration

Create a .env file based on .env.example:

For GCP:

NX_CACHE_ACCESS_TOKEN=your-secure-token-here
GOOGLE_CLOUD_PROJECT_ID=your-gcp-project-id
GCS_BUCKET_NAME=your-gcs-bucket-name
PORT=3000
LOG_LEVEL=info

For AWS:

NX_CACHE_ACCESS_TOKEN=your-secure-token-here
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
S3_BUCKET_NAME=your-bucket-name
PORT=3000
LOG_LEVEL=info

🎯 Nx Integration

To use this cache server with your Nx workspace, set the following environment variables:

NX_SELF_HOSTED_REMOTE_CACHE_SERVER=http://your-server:3000
NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN=your-secure-token

🐳 Docker Deployment

Build and Run

# Build the image
docker build -t nx-cache-server .

# Run with environment file
docker run -p 3000:3000 --env-file .env nx-cache-server

# Or with inline environment variables
docker run -p 3000:3000 \
  -e NX_CACHE_ACCESS_TOKEN=your-token \
  -e GOOGLE_CLOUD_PROJECT_ID=your-project \
  -e GCS_BUCKET_NAME=your-bucket \
  nx-cache-server

Docker Compose

version: '3.8'
services:
  nx-cache:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NX_CACHE_ACCESS_TOKEN=${NX_CACHE_ACCESS_TOKEN}
      - GOOGLE_CLOUD_PROJECT_ID=${GOOGLE_CLOUD_PROJECT_ID}
      - GCS_BUCKET_NAME=${GCS_BUCKET_NAME}
    volumes:
      - ./service-account.json:/app/service-account.json:ro
    restart: unless-stopped

About

Nx plugin for generating high-performance cache servers with cloud storage backends

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published