diff --git a/.github/assets/dashboard.gif b/.github/assets/dashboard.gif new file mode 100644 index 0000000..a4b2fd2 Binary files /dev/null and b/.github/assets/dashboard.gif differ diff --git a/README.md b/README.md index 40642ff..e01394e 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,37 @@ -[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -[![Release](https://img.shields.io/github/v/release/getnora-io/nora)](https://github.com/getnora-io/nora/releases) -[![CI](https://img.shields.io/github/actions/workflow/status/getnora-io/nora/ci.yml?label=CI)](https://github.com/getnora-io/nora/actions) -[![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/devitway/0f0538f1ed16d5d9951e4f2d3f79b699/raw/nora-coverage.json)](https://github.com/getnora-io/nora/actions/workflows/ci.yml) -[![GHCR](https://img.shields.io/badge/ghcr.io-nora-blue?logo=github)](https://github.com/getnora-io/nora/pkgs/container/nora) -[![GitHub Stars](https://img.shields.io/github/stars/getnora-io/nora?style=flat&logo=github)](https://github.com/getnora-io/nora/stargazers) -[![Rust](https://img.shields.io/badge/rust-%23000000.svg?logo=rust&logoColor=white)](https://www.rust-lang.org/) -[![Docs](https://img.shields.io/badge/docs-getnora.dev-green?logo=gitbook)](https://getnora.dev) -[![Telegram](https://img.shields.io/badge/Telegram-Community-blue?logo=telegram)](https://t.me/getnora) -[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/getnora-io/nora/badge)](https://scorecard.dev/viewer/?uri=github.com/getnora-io/nora) -[![CII Best Practices](https://www.bestpractices.dev/projects/12207/badge)](https://www.bestpractices.dev/projects/12207) +# NORA -> **Multi-protocol artifact registry that doesn't suck.** -> -> One binary. All protocols. Stupidly fast. +**The artifact registry that grows with you.** Starts with `docker run`, scales to enterprise. -**32 MB** binary | **< 100 MB** RAM | **3s** startup | **5** protocols +```bash +docker run -d -p 4000:4000 -v nora-data:/data ghcr.io/getnora-io/nora:latest +``` -## Features +Open [http://localhost:4000/ui/](http://localhost:4000/ui/) — your registry is ready. -- **Multi-Protocol Support** - - Docker Registry v2 - - Maven repository (+ proxy to Maven Central) - - npm registry (+ proxy to npmjs.org) - - Cargo registry - - PyPI index +

+ NORA Dashboard +

-- **Storage Backends** - - Local filesystem (zero-config default) - - S3-compatible (MinIO, AWS S3) +## Why NORA -- **Production Ready** - - Web UI with search and browse - - Swagger UI API documentation - - Prometheus metrics (`/metrics`) - - Health checks (`/health`, `/ready`) - - JSON structured logging - - Graceful shutdown +- **Zero-config** — single 32 MB binary, no database, no dependencies. `docker run` and it works. +- **Production-tested** — Docker, Maven, npm, PyPI, Cargo, Raw. Used in real CI/CD with ArgoCD, Buildx cache, and air-gapped environments. +- **Secure by default** — [OpenSSF Scorecard 7.1](https://scorecard.dev/viewer/?uri=github.com/getnora-io/nora), signed releases, SBOM, fuzz testing, 200+ unit tests. -- **Security** - - Basic Auth (htpasswd + bcrypt) - - Revocable API tokens with RBAC - - Blob digest verification (SHA256) - - Non-root container images - - Security headers (CSP, X-Frame-Options, nosniff) - - Upload session limits (DoS protection) - - Configurable upload size for ML models (`NORA_MAX_UPLOAD_SESSION_SIZE_MB`) - - ENV-based configuration (12-Factor) - - SBOM (SPDX + CycloneDX) in every release - - See [SECURITY.md](SECURITY.md) for vulnerability reporting +**32 MB** binary | **< 100 MB** RAM | **3s** startup | **6** registries + +> Used in production at [DevIT Academy](https://github.com/devitway) since January 2026 for Docker images, Maven artifacts, and npm packages. + +## Supported Registries + +| Registry | Mount Point | Upstream Proxy | Auth | +|----------|------------|----------------|------| +| Docker Registry v2 | `/v2/` | Docker Hub, GHCR, any OCI | ✓ | +| Maven | `/maven2/` | Maven Central, custom | ✓ | +| npm | `/npm/` | npmjs.org, custom | ✓ | +| Cargo | `/cargo/` | — | ✓ | +| PyPI | `/simple/` | pypi.org, custom | ✓ | +| Raw files | `/raw/` | — | ✓ | ## Quick Start @@ -57,6 +41,13 @@ docker run -d -p 4000:4000 -v nora-data:/data ghcr.io/getnora-io/nora:latest ``` +### Binary + +```bash +curl -fsSL https://github.com/getnora-io/nora/releases/latest/download/nora-linux-amd64 -o nora +chmod +x nora && ./nora +``` + ### From Source ```bash @@ -64,18 +55,13 @@ cargo install nora-registry nora ``` -Open http://localhost:4000/ui/ - ## Usage ### Docker Images ```bash -# Tag and push docker tag myapp:latest localhost:4000/myapp:latest docker push localhost:4000/myapp:latest - -# Pull docker pull localhost:4000/myapp:latest ``` @@ -96,31 +82,36 @@ npm config set registry http://localhost:4000/npm/ npm publish ``` +## Features + +- **Web UI** — dashboard with search, browse, i18n (EN/RU) +- **Proxy & Cache** — transparent proxy to upstream registries with local cache +- **Mirror CLI** — offline sync for air-gapped environments (`nora mirror`) +- **Backup & Restore** — `nora backup` / `nora restore` +- **Migration** — `nora migrate --from local --to s3` +- **S3 Storage** — MinIO, AWS S3, any S3-compatible backend +- **Prometheus Metrics** — `/metrics` endpoint +- **Health Checks** — `/health`, `/ready` for Kubernetes probes +- **Swagger UI** — `/api-docs` for API exploration +- **Rate Limiting** — configurable per-endpoint rate limits +- **FSTEC Builds** — Astra Linux SE and RED OS images in every release + ## Authentication NORA supports Basic Auth (htpasswd) and revocable API tokens with RBAC. -### Quick Setup - ```bash -# 1. Create htpasswd file with bcrypt +# Create htpasswd file htpasswd -cbB users.htpasswd admin yourpassword -# Add more users: -htpasswd -bB users.htpasswd ci-user ci-secret -# 2. Start NORA with auth enabled +# Start with auth enabled docker run -d -p 4000:4000 \ -v nora-data:/data \ -v ./users.htpasswd:/data/users.htpasswd \ -e NORA_AUTH_ENABLED=true \ ghcr.io/getnora-io/nora:latest - -# 3. Verify -curl -u admin:yourpassword http://localhost:4000/v2/_catalog ``` -### API Tokens (RBAC) - | Role | Pull/Read | Push/Write | Delete/Admin | |------|-----------|------------|--------------| | `read` | Yes | No | No | @@ -129,16 +120,6 @@ curl -u admin:yourpassword http://localhost:4000/v2/_catalog See [Authentication guide](https://getnora.dev/configuration/authentication/) for token management, Docker login, and CI/CD integration. -## CLI Commands - -```bash -nora # Start server -nora serve # Start server (explicit) -nora backup -o backup.tar.gz -nora restore -i backup.tar.gz -nora migrate --from local --to s3 -``` - ## Configuration ### Environment Variables @@ -151,7 +132,7 @@ nora migrate --from local --to s3 | `NORA_AUTH_ENABLED` | false | Enable authentication | | `NORA_DOCKER_UPSTREAMS` | `https://registry-1.docker.io` | Docker upstreams (`url\|user:pass,...`) | -See [full configuration reference](https://getnora.dev/configuration/settings/) for all environment variables including storage, rate limiting, proxy auth, and secrets. +See [full configuration reference](https://getnora.dev/configuration/settings/) for all options. ### config.toml @@ -175,7 +156,16 @@ proxy_timeout = 60 url = "https://registry-1.docker.io" ``` -See [full config reference](https://getnora.dev/configuration/settings/) for rate limiting, secrets, proxy auth, and all options. +## CLI Commands + +```bash +nora # Start server +nora serve # Start server (explicit) +nora backup -o backup.tar.gz +nora restore -i backup.tar.gz +nora migrate --from local --to s3 +nora mirror # Sync packages for offline use +``` ## Endpoints @@ -202,21 +192,8 @@ registry.example.com { } ``` -For internal networks without TLS, configure Docker: - -```json -// /etc/docker/daemon.json -{ - "insecure-registries": ["192.168.1.100:4000"] -} -``` - See [TLS / HTTPS guide](https://getnora.dev/configuration/tls/) for Nginx, Traefik, and custom CA setup. -## FSTEC-Certified OS Builds - -Dedicated builds for Astra Linux SE and RED OS are published as `-astra` and `-redos` tagged images in every [GitHub Release](https://github.com/getnora-io/nora/releases). Both use `scratch` base with statically-linked binary. - ## Performance | Metric | NORA | Nexus | JFrog | @@ -225,6 +202,8 @@ Dedicated builds for Astra Linux SE and RED OS are published as `-astra` and `-r | Memory | < 100 MB | 2-4 GB | 2-4 GB | | Image Size | 32 MB | 600+ MB | 1+ GB | +[See how NORA compares to other registries](https://getnora.dev) + ## Roadmap - **OIDC / Workload Identity** — zero-secret auth for GitHub Actions, GitLab CI @@ -235,14 +214,37 @@ Dedicated builds for Astra Linux SE and RED OS are published as `-astra` and `-r See [CHANGELOG.md](CHANGELOG.md) for release history. +## Security & Trust + +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/getnora-io/nora/badge)](https://scorecard.dev/viewer/?uri=github.com/getnora-io/nora) +[![CII Best Practices](https://www.bestpractices.dev/projects/12207/badge)](https://www.bestpractices.dev/projects/12207) +[![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/devitway/0f0538f1ed16d5d9951e4f2d3f79b699/raw/nora-coverage.json)](https://github.com/getnora-io/nora/actions/workflows/ci.yml) +[![CI](https://img.shields.io/github/actions/workflow/status/getnora-io/nora/ci.yml?label=CI)](https://github.com/getnora-io/nora/actions) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) + +- **Signed releases** — every release is signed with [cosign](https://github.com/sigstore/cosign) +- **SBOM** — SPDX + CycloneDX in every release +- **Fuzz testing** — cargo-fuzz + ClusterFuzzLite +- **Blob verification** — SHA256 digest validation on every upload +- **Non-root containers** — all images run as non-root +- **Security headers** — CSP, X-Frame-Options, nosniff + +See [SECURITY.md](SECURITY.md) for vulnerability reporting. + ## Author -**Created and maintained by [DevITWay](https://github.com/devitway)** +Created and maintained by [DevITWay](https://github.com/devitway) + +[![Release](https://img.shields.io/github/v/release/getnora-io/nora)](https://github.com/getnora-io/nora/releases) +[![GHCR](https://img.shields.io/badge/ghcr.io-nora-blue?logo=github)](https://github.com/getnora-io/nora/pkgs/container/nora) +[![Rust](https://img.shields.io/badge/rust-%23000000.svg?logo=rust&logoColor=white)](https://www.rust-lang.org/) +[![Docs](https://img.shields.io/badge/docs-getnora.dev-green?logo=gitbook)](https://getnora.dev) +[![Telegram](https://img.shields.io/badge/Telegram-Community-blue?logo=telegram)](https://t.me/getnora) +[![GitHub Stars](https://img.shields.io/github/stars/getnora-io/nora?style=flat&logo=github)](https://github.com/getnora-io/nora/stargazers) - Website: [getnora.dev](https://getnora.dev) -- Telegram: [@DevITWay](https://t.me/DevITWay) +- Telegram: [@getnora](https://t.me/getnora) - GitHub: [@devitway](https://github.com/devitway) -- Email: devitway@gmail.com ## Contributing @@ -250,10 +252,6 @@ NORA welcomes contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelin ## License -MIT License - see [LICENSE](LICENSE) +MIT License — see [LICENSE](LICENSE) Copyright (c) 2026 DevITWay - ---- - -**🐿️ N○RA** - Organized like a chipmunk's stash | Built with Rust by [DevITWay](https://t.me/DevITWay)