NORA: minimalistyczny rejestr artefaktów w Rustie bez zewnętrznych zależności
Deweloper stworzył NORA — pojedynczy plik binarny w Rustie do przechowywania artefaktów w formatach Docker v2/OCI, Maven, npm, PyPI, Cargo, Go i raw. Rozmiar 34 MB, zużycie RAM 12 MB w trybie bezczynności, bez baz danych lub usług zewnętrznych. Metadane przechowywane w plikach JSON na dysku, spójność zapewniona przez atomowe przechowywanie. Wsparcie dla backendu S3, metryk Prometheus, sond zdrowia i dokumentacji Swagger od razu.
Dlaczego zrezygnowano z Nexus, Artifactory i Harbor
Nexus OSS wymaga 4 GB RAM na proces Java, migracje między wersjami (Core/Community/Pro) są skomplikowane ze względu na zmianę z OrientDB na PostgreSQL. Artifactory OSS ogranicza się do Maven/Gradle/Ivy, pozostałe formaty (Docker, npm) — w wersji płatnej. Harbor skupia się na kontenerach, ignorując Maven/npm/PyPI. GitLab Registry działa z zastrzeżeniami: problemy z artefaktami OCI, pamięcią podręczną buildx i wieloma architekturami wymagają obejść.
Czas na obejścia przekroczył wysiłek na stworzenie własnego rozwiązania.
Architektura bez bazy danych i panelu administracyjnego
Wszystkie dane w systemie plików: artefakty i metadane w JSON obok siebie. Katalog tworzony przez przechodzenie katalogów. Brak migracji, klastrowania lub usług zewnętrznych — uruchomienie w 3 sekundy.
nora (34 MB, Rust, 450+ testów)
├── /v2/ — Docker Registry v2 + OCI (obrazy, wykresy Helm)
├── /maven/ — Maven (JAR, WAR, POM)
├── /npm/ — npm (pakiety Node.js)
├── /pypi/ — PyPI (pakiety Python)
├── /cargo/ — Cargo (kraty Rust, indeks rzadki RFC 2789)
├── /go/ — Go Modules
├── /raw/ — Raw (dowolne pliki)
├── /metrics — Prometheus
├── /health — K8s sonda żywotności
├── /ready — K8s sonda gotowości
├── /api-docs — Swagger
└── /data/ — przechowywanie (FS lub S3)
Konfiguracja przez config.toml lub zmienne środowiskowe. Interfejs web read-only: przeglądanie, wyszukiwanie, statystyki. Zmiany w git z audytem przez CI/CD.
Obsługiwane formaty
- Docker v2 + OCI:
/v2/— obrazy, wykresy Helm, pełna zgodność ze specyfikacją. - Maven:
/maven/— JAR, WAR, POM z proxy dla Central. - npm:
/npm/— pakiety Node.js, indeks rzadki. - PyPI:
/pypi/— pakiety Python. - Cargo:
/cargo/— kraty Rust według RFC 2789. - Go:
/go/— moduły z proxy proxy.golang.org. - Raw:
/raw/— dowolne pliki.
Uwierzytelnianie i bezpieczeństwo
- Pliki htpasswd do podstawowej autoryzacji.
- Tokeny API z RBAC (read/write/admin), odwołanie tokenów.
- Anonimowy odczyt, TLS przez reverse proxy (nginx/Traefik).
Dodatkowo:
- Strukturyzowane logi JSON (metoda, ścieżka, status, użytkownik).
- Ograniczanie szybkości według endpointów.
- Log audytu w JSONL.
- GC:
nora gc --dry-rundla blobów Docker. - Backup/restore:
nora backup -o file.tar.gz.
Porównanie wydajności
| Metryka | NORA | Nexus OSS | Artifactory |
|------------------|----------|-----------|-------------|
| Obraz | 34 MB | 600+ MB | 1+ GB |
| Zimny start | ~3 sek | 30-60 sek | 30-60 sek |
| RAM | 12 MB | 2-4 GB | 2-4 GB |
| Usługi zewnętrzne| 0 | H2/PG | PG/Tomcat |
| Formatów | 7 | 20+ | 30+ |
Pod obciążeniem (2 rdzenie, 4 GB RAM): pull 268 MB obrazu w 6 sek, push w 19 sek, RAM do 250 MB.
Wdrażanie i użytkowanie
Uruchomienie:
docker run -d \
-p 8080:8080 \
-v nora-data:/data \
getnora/nora:0.5.0
Docker push:
docker login localhost:8080 -u admin
docker tag myapp:latest localhost:8080/myapp:latest
docker push localhost:8080/myapp:latest
npm:
npm config set registry http://localhost:8080/npm/
npm publish
Proxy upstream: automatyczne cache z Docker Hub, npmjs, PyPI, Maven Central.
Obwód zamknięty i zwierciadlenie
Dla sieci izolowanych: nora mirror --format docker --packages "nginx:latest" --output bundle na zewnętrznym węźle, przeniesienie bundle, nora restore --input bundle wewnątrz. Weryfikacja integralności przez SHA256.
Co jest ważne
- Pojedynczy plik binarny bez bazy danych: 34 MB, 12 MB RAM, przechowywanie FS.
- 7 formatów: Docker/OCI, Maven, npm, PyPI, Cargo, Go, raw.
- Proxy upstream + cache, tokeny RBAC, logi audytu.
- Roadmap: online GC, multi-node, NuGet/RubyGems, OIDC.
— Editorial Team
Brak komentarzy.