{"id":492052,"date":"2026-08-25T05:52:08","date_gmt":"2026-08-25T05:52:08","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=492052"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=492052","title":{"rendered":"NORA: \u043b\u0451\u0433\u043a\u0438\u0439 artifact registry \u0434\u043b\u044f Kubernetes \u0441 \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d\u043e\u043c \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439 CVE"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432: Docker-\u043e\u0431\u0440\u0430\u0437\u044b, npm-\u043f\u0430\u043a\u0435\u0442\u044b, Maven-\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b, Python wheels. \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u0432\u0430 \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0435\u0441\u0442\u0440\u044b (Docker Hub, <a href=\"http:\/\/npmjs.org\" rel=\"noopener noreferrer nofollow\">npmjs.org<\/a>, PyPI) \u0438\u043b\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c Nexus \/ Artifactory \/ Harbor. \u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0435\u0441\u0442\u0440\u044b \u043d\u0435\u043d\u0430\u0434\u0451\u0436\u043d\u044b \u0438\u0437-\u0437\u0430 rate limit \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a. \u0410 Nexus \u0438 Artifactory \u2014 \u044d\u0442\u043e \u0442\u044f\u0436\u0451\u043b\u0430\u044f Java-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430: JVM, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0421\u0423\u0411\u0414 (OrientDB\/PostgreSQL), 2\u20134 \u0413\u0411 RAM \u0443\u0436\u0435 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u043c\u0438\u043d\u0443\u0442 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442.<\/p>\n<p><a href=\"https:\/\/github.com\/getnora-io\/nora\" rel=\"noopener noreferrer nofollow\">NORA<\/a>\u00a0\u2014 open-source \u0440\u0435\u0435\u0441\u0442\u0440 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u043d\u0430 Rust, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u0430\u043a \u043f\u0440\u044f\u043c\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u044d\u0442\u0438\u043c \u0433\u0438\u0433\u0430\u043d\u0442\u0430\u043c. \u0412\u043c\u0435\u0441\u0442\u043e Java-\u0441\u0442\u0435\u043a\u0430 \u2014 \u043e\u0434\u0438\u043d \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a &lt; 27 \u041c\u0411. \u0412\u043c\u0435\u0441\u0442\u043e 2\u20134 \u0413\u0411 RAM \u2014 &lt; 50 \u041c\u0411 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u0442.\u0435. \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043c\u0435\u043d\u044c\u0448\u0435. \u0412\u043c\u0435\u0441\u0442\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043c\u0438\u043d\u0443\u0442 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442 \u2014 3 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0412\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435: \u043d\u0438 Java 11+, \u043d\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 \u2014 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0441\u0440\u0430\u0437\u0443 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 S3, \u0447\u0435\u0433\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 Nexus \u0438 Artifactory \u043d\u0435 \u0443\u043c\u0435\u044e\u0442. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432: Docker, Maven, npm, PyPI, Cargo, Go, Raw, RubyGems, Terraform, Ansible Galaxy, NuGet, Pub (Dart\/Flutter), Conan (C\/C++), RPM (yum\/dnf), Debian\/APT. \u041f\u043b\u044e\u0441 Helm-\u0447\u0430\u0440\u0442\u044b \u0447\u0435\u0440\u0435\u0437 OCI, \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (Min Release Age), \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 (CVE Blocking) \u0438 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044f MIT.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0451\u043c NORA \u0432 Kubernetes \u043d\u0430 Yandex Managed Kubernetes, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h3>NORA vs Nexus vs Artifactory vs Harbor<\/h3>\n<p>\u0421\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435\/\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438: NORA (MIT), Nexus Repository OSS, Artifactory OSS \u0438 Harbor (Apache 2.0).<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041c\u0435\u0442\u0440\u0438\u043a\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">NORA<\/p>\n<\/th>\n<th>\n<p align=\"left\">Nexus<\/p>\n<\/th>\n<th>\n<p align=\"left\">JFrog Artifactory<\/p>\n<\/th>\n<th>\n<p align=\"left\">Harbor<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RAM (\u043f\u0440\u043e\u0441\u0442\u043e\u0439)<\/p>\n<\/td>\n<td>\n<p align=\"left\">&lt; 50 \u041c\u0411<\/p>\n<\/td>\n<td>\n<p align=\"left\">2\u20134 \u0413\u0411<\/p>\n<\/td>\n<td>\n<p align=\"left\">2\u20134 \u0413\u0411<\/p>\n<\/td>\n<td>\n<p align=\"left\">2\u20134 \u0413\u0411<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">&lt; 3 \u0441\u0435\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">30\u201360 \u0441\u0435\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">30\u201360 \u0441\u0435\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">30\u201360 \u0441\u0435\u043a<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">Java 11+<\/p>\n<\/td>\n<td>\n<p align=\"left\">Java 11+<\/p>\n<\/td>\n<td>\n<p align=\"left\">PostgreSQL, Redis<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">OrientDB\/PostgreSQL<\/p>\n<\/td>\n<td>\n<p align=\"left\">OrientDB\/PostgreSQL<\/p>\n<\/td>\n<td>\n<p align=\"left\">PostgreSQL<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">15<\/p>\n<\/td>\n<td>\n<p align=\"left\">30+<\/p>\n<\/td>\n<td>\n<p align=\"left\">30+<\/p>\n<\/td>\n<td>\n<p align=\"left\">Docker, OCI, Helm, CNAB<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">S3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041b\u0438\u0446\u0435\u043d\u0437\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">MIT<\/p>\n<\/td>\n<td>\n<p align=\"left\">OSS<\/p>\n<\/td>\n<td>\n<p align=\"left\">OSS<\/p>\n<\/td>\n<td>\n<p align=\"left\">Apache 2.0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 (\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0434\u0438\u043d \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u043d\u0430 Rust, S3, \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e \u0432\u0435\u0440\u0441\u0438\u044f\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted\/proxy\/group-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">Conan \u2014 \u0432 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u0438 CE \u0434\u043b\u044f C\/C++<\/p>\n<\/td>\n<td>\n<p align=\"left\">C\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 CVE image \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f trivy \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 image<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>NORA \u0443\u0441\u0442\u0443\u043f\u0430\u0435\u0442 Nexus\/Artifactory\/Harbor \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432. \u041d\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u043b\u0451\u0433\u043a\u0438\u0439 \u0438 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 registry \u0441 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c\u0438 \u2014 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440.<\/p>\n<p>\u041e\u0442\u043b\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c Nora \u044d\u0442\u043e:<\/p>\n<ul>\n<li>\n<p><strong>Min Release Age<\/strong>\u00a0\u2014 \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><strong>CVE Blocking<\/strong>\u00a0\u2014 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e \u0432\u0435\u0440\u0441\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<blockquote>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c ingress-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c, cert-manager, \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a S3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u0438 \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438\u0437 \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432, \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u043d\u044b\u0445 \u0433\u0435\u043e-\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Terraform Registry). \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043a \u0448\u0430\u0433\u0430\u043c 1\u20132 \u043d\u0438\u0436\u0435.<\/p>\n<\/blockquote>\n<h3>\u0428\u0430\u0433 1. \u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/h3>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e NORA \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u0435\u0437 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435). \u0414\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<h4>\u0428\u0430\u0433 1. \u0421\u043e\u0437\u0434\u0430\u0451\u043c htpasswd-\u0444\u0430\u0439\u043b<\/h4>\n<pre><code>htpasswd -Bbc users.htpasswd admin your-password# -B = bcrypt (\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f NORA), -b = \u043f\u0430\u0440\u043e\u043b\u044c \u0438\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, -c = \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0428\u0430\u0433 2. \u0421\u043e\u0437\u0434\u0430\u0451\u043c Kubernetes Secret<\/h4>\n<pre><code>kubectl create secret generic nora-htpasswd \\  --from-file=users.htpasswd=.\/users.htpasswd<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0438 \u0440\u043e\u043b\u0438:\u00a0<code>read<\/code>\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435),\u00a0<code>write<\/code>\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435 + \u0437\u0430\u043f\u0438\u0441\u044c),\u00a0<code>admin<\/code>\u00a0(\u0432\u0441\u0451 + \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438). \u0420\u043e\u043b\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u043a\u0435\u043d\u044b (\u0441\u043c. \u043d\u0438\u0436\u0435).<\/p>\n<h4>\u0428\u0430\u0433 3. \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c Kubernetes Secret \u0434\u043b\u044f S3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430<\/h4>\n<p>\u041d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c S3-\u0431\u0430\u043a\u0435\u0442 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u00a0<code>secret_for_bucket.yaml<\/code>. \u0424\u0430\u0439\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>apiVersion: v1kind: Secretmetadata:  name: nora-s3-credentialstype: OpaquestringData:  S3_ACCESS_KEY: YCAJE...  S3_SECRET_KEY: YCNL9...<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440:<\/p>\n<pre><code>kubectl apply -f secret_for_bucket.yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<pre><code># \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e Secret \u0441\u043e\u0437\u0434\u0430\u043dkubectl get secret nora-s3-credentials# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0439kubectl get secret nora-s3-credentials -o jsonpath='{.data.S3_ACCESS_KEY}' | base64 -d &amp;&amp; echokubectl get secret nora-s3-credentials -o jsonpath='{.data.S3_SECRET_KEY}' | base64 -d &amp;&amp; echo<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0428\u0430\u0433 2. \u0414\u0435\u043f\u043b\u043e\u0439 NORA \u0447\u0435\u0440\u0435\u0437 Helm<\/h3>\n<h4>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Helm-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/h4>\n<pre><code>helm repo add nora https:\/\/getnora-io.github.io\/helm-chartshelm repo update<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0447\u0430\u0440\u0442 \u0432\u0435\u0440\u0441\u0438\u0438\u00a0<strong>0.4.4<\/strong>\u00a0(\u043e\u043d\u0430 \u0443\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0438\u0436\u0435 \u0447\u0435\u0440\u0435\u0437\u00a0<code>--version 0.4.4<\/code>) \u0441 \u043f\u0438\u043d\u043e\u043c \u043e\u0431\u0440\u0430\u0437\u0430\u00a0<strong>NORA v1.2.0<\/strong>\u00a0\u0447\u0435\u0440\u0435\u0437\u00a0<code>image.tag<\/code>\u00a0\u0432 values. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>helm search repo nora\/nora --versions<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0439\u0434\u0435\u0442 \u0447\u0430\u0440\u0442\u00a0<code>0.4.5<\/code>\u00a0(appVersion 1.2.0), \u043f\u0438\u043d\u00a0<code>image.tag: \"1.2.0\"<\/code>\u00a0\u0438\u0437\u00a0<code>helm-values.yaml.tpl<\/code>\u00a0\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u2014 \u0447\u0430\u0440\u0442 \u043d\u0430\u0447\u043d\u0451\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c appVersion \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<\/blockquote>\n<h4>values-\u0444\u0430\u0439\u043b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/h4>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435\u00a0<code>helm-values.yaml<\/code>:<\/p>\n<pre><code>image:  # NORA v1.2.0; \u0447\u0430\u0440\u0442 0.4.4 \u0435\u0449\u0451 \u0438\u043c\u0435\u0435\u0442 appVersion 1.1.0, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0438\u043d\u0438\u043c \u0442\u0435\u0433 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.  # \u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0439\u0434\u0435\u0442 \u0447\u0430\u0440\u0442 0.4.5 (appVersion 1.2.0), \u0441\u0442\u0440\u043e\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c.  tag: \"1.2.0\"ingress:  enabled: true  className: traefik  hosts:    - host: ${fqdn}      paths:        - path: \/          pathType: Prefix  annotations:    cert-manager.io\/cluster-issuer: letsencrypt-prod  tls:    - secretName: nora-tls      hosts:        - ${fqdn}# \u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f S3, \u0442\u043e \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0438\u0441\u043a.persistence:  enabled: falseconfig:  server:    public_url: \"https:\/\/${fqdn}\"  storage:    mode: s3    path: \/data\/storage    s3_url: https:\/\/storage.yandexcloud.net    bucket: nora-storage-anton-patsev    s3_region: ru-central1  registries:    enable: \"all\"  auth:    enabled: true    anonymous_read: true # \u0414\u043b\u044f terraform    htpasswd:      existingSecret: nora-htpasswd      secretKey: users.htpasswdextraEnv:  - name: NORA_STORAGE_S3_ACCESS_KEY    valueFrom:      secretKeyRef:        name: nora-s3-credentials        key: S3_ACCESS_KEY  - name: NORA_STORAGE_S3_SECRET_KEY    valueFrom:      secretKeyRef:        name: nora-s3-credentials        key: S3_SECRET_KEYresources:  limits:    memory: 512Mi    cpu: \"1\"  requests:    memory: 128Mi    cpu: \"0.25\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c<\/h4>\n<pre><code>helm upgrade --install nora nora\/nora --version 0.4.4 -f helm-values.yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c<\/h4>\n<pre><code># \u0416\u0434\u0451\u043c \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434\u0430kubectl wait --for=condition=ready pod -l app.kubernetes.io\/name=nora --timeout=120s# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c healthcurl https:\/\/$NORA_FQDN\/health# \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c Web UIopen https:\/\/$NORA_FQDN\/ui\/<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e NORA \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443\u00a0<a href=\"https:\/\/%24NORA_FQDN\" rel=\"noopener noreferrer nofollow\"><code>https:\/\/$NORA_FQDN<\/code><\/a>. Web UI \u043f\u043e\u043a\u0430\u0436\u0435\u0442 dashboard \u0441 15 \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u043c\u0438.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8a5\/2f4\/b5d\/8a52f4b5dc4adfba7ec59937dbfb891a.png\" alt=\"NORA Dashboard\" width=\"1920\" height=\"1080\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/8a5\/2f4\/b5d\/8a52f4b5dc4adfba7ec59937dbfb891a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8a5\/2f4\/b5d\/8a52f4b5dc4adfba7ec59937dbfb891a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>NORA Dashboard<\/figcaption><\/div>\n<\/figure>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/h4>\n<p>NORA \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 API-\u0442\u043e\u043a\u0435\u043d\u044b \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c\u00a0<code>nra_<\/code>\u00a0\u0432\u043c\u0435\u0441\u0442\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430\u00a0<code>\/auth\/token<\/code>\u00a0(\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0441\u0442\u044c \u0432 Docker Hub \/ GHCR, \u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 NORA).<\/p>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0438 \u0440\u043e\u043b\u0438:\u00a0<code>read<\/code>\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435),\u00a0<code>write<\/code>\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435 + \u0437\u0430\u043f\u0438\u0441\u044c),\u00a0<code>admin<\/code>\u00a0(\u0432\u0441\u0451 + \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438).<\/p>\n<pre><code># \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043dcurl -X POST https:\/\/$NORA_FQDN\/api\/tokens \\  -H \"Content-Type: application\/json\" \\  -d '{    \"username\": \"admin\",    \"password\": \"your-password\",    \"role\": \"write\",    \"ttl_days\": 90,    \"description\": \"CI\/CD pipeline token\"  }'# {\"token\": \"nra_13ef0a4c309d4750907648409f57a65c...\", \"expires_in_days\": 90}# \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u0430curl -H \"Authorization: Bearer nra_13ef0a4c309d4750907648409f57a65c\" \\  https:\/\/$NORA_FQDN\/v2\/_catalog<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435: \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430<\/h3>\n<p>NORA v1.2.0 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432, \u043d\u043e \u043d\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f (push\/publish). \u0427\u0430\u0441\u0442\u044c \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u2014\u00a0<strong>proxy\/cache<\/strong>\u00a0(\u0437\u0435\u0440\u043a\u0430\u043b\u043e \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 \u0441 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c). \u0421\u0432\u043e\u0434\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0424\u043e\u0440\u043c\u0430\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">Pull (proxy\/cache)<\/p>\n<\/th>\n<th>\n<p align=\"left\">Push\/Publish<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Docker \/ OCI<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Helm OCI<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0447\u0435\u0440\u0435\u0437 Docker\/OCI endpoint<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">npm<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">PyPI<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Maven<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Cargo<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy (sparse index)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Go<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy (\u043c\u043e\u0434\u0443\u043b\u0438 immutable, push \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u043c)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Terraform<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy (\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Raw<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted only, \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 PUT (ETag\/If-Match \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 local-\u0431\u044d\u043a\u0435\u043d\u0434\u0435, \u0441\u043c. \u0440\u0430\u0437\u0434\u0435\u043b Raw)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RPM<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy, \u0430\u0432\u0442\u043e-\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f repodata<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Debian\/APT<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy, \u0430\u0432\u0442\u043e-\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f Packages\/Release<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RubyGems<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache<\/strong>\u00a0(<code>gem push<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">NuGet<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache<\/strong>\u00a0(<code>dotnet nuget push<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Ansible Galaxy<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache<\/strong>\u00a0(<code>ansible-galaxy collection publish<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Pub (Dart)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache<\/strong>\u00a0(<code>dart pub publish<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Conan<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache<\/strong>\u00a0(<code>conan upload<\/code>)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0445 \u274c \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 Push, \u0440\u0430\u0437\u0434\u0435\u043b\u044b \u043d\u0438\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 \u043e\u043d\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u0431\u0443\u0434\u0443\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b, \u043a\u043e\u0433\u0434\u0430 NORA \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b. \u0421\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a pull-through \u043a\u044d\u0448.<\/p>\n<h4>\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432<\/h4>\n<p>\u0418\u0437 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0442\u043e\u043b\u044c\u043a\u043e Raw \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 \u2014 \u044d\u0442\u043e hosted-only \u0440\u0435\u0435\u0441\u0442\u0440 (\u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b). \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 14 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u0430\u043a\u00a0<strong>proxy\/cache<\/strong>: \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0442 \u043f\u0430\u043a\u0435\u0442\u044b\/\u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430. \u0421\u0432\u043e\u0434\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (\u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u00a0<code>proxies<\/code>\u00a0\u0432\u00a0<code>helm-values.yaml<\/code>):<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0424\u043e\u0440\u043c\u0430\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0430\u043f\u0441\u0442\u0440\u0438\u043c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0410\u043f\u0441\u0442\u0440\u0438\u043c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0422\u0438\u043f \u043a\u044d\u0448\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Docker \/ OCI<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/registry-1.docker.io\" rel=\"noopener noreferrer nofollow\"><code>registry-1.docker.io<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">immutable blobs + TTL manifest<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy; \u043a\u044d\u0448 \u0432\u043a\u043b\u044e\u0447\u0451\u043d, \u043a\u043e\u0433\u0434\u0430\u00a0<code>docker.upstreams<\/code>\u00a0\u043d\u0435\u043f\u0443\u0441\u0442\u043e\u0439 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e Docker Hub)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Helm OCI<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0447\u0435\u0440\u0435\u0437 Docker\/OCI endpoint<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy (\u0447\u0435\u0440\u0435\u0437 Docker endpoint)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">npm<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/registry.npmjs.org\" rel=\"noopener noreferrer nofollow\"><code>registry.npmjs.org<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">packuments (TTL) + tarball (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">PyPI<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>pypi.org\/simple\/<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">index (TTL) + \u0444\u0430\u0439\u043b\u044b (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Maven<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>repo1.maven.org\/maven2<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">metadata (TTL) + \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Cargo<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/crates.io\" rel=\"noopener noreferrer nofollow\"><code>crates.io<\/code><\/a>\u00a0(sparse index)<\/p>\n<\/td>\n<td>\n<p align=\"left\">index (TTL) + .crate (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted + proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Go<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/proxy.golang.org\" rel=\"noopener noreferrer nofollow\"><code>proxy.golang.org<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">@v\/list,@latest (TTL) + .info\/.mod\/.zip (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Terraform<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/registry.terraform.io\" rel=\"noopener noreferrer nofollow\"><code>registry.terraform.io<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">discovery (TTL) + \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u00a0<code>anonymous_read: true<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RubyGems<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/rubygems.org\" rel=\"noopener noreferrer nofollow\"><code>rubygems.org<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">specs\/latest_specs\/info (TTL) + gem\/gemspec (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">NuGet<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/api.nuget.org\" rel=\"noopener noreferrer nofollow\"><code>api.nuget.org<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">registration\/query (TTL) + .nupkg\/.nuspec (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Ansible Galaxy<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/galaxy.ansible.com\" rel=\"noopener noreferrer nofollow\"><code>galaxy.ansible.com<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">collection list\/detail (TTL) + tarball (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Pub (Dart)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"http:\/\/pub.dev\" rel=\"noopener noreferrer nofollow\"><code>pub.dev<\/code><\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">package metadata (TTL) + archive (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Conan<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705*<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>center2.conan.io<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">revisions (TTL) + recipe\/package files (immutable)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0442\u043e\u043b\u044c\u043a\u043e proxy; v2 API + v1\/ping (\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c Conan 2.x \u0441 NORA v1.2.0)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RPM<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705*<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014 (\u043d\u0435\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u0430\u043a\u0435\u0442\u044b (immutable) + repodata (\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f)<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted; pull-through \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0447\u0435\u0440\u0435\u0437\u00a0<code>config.registries.rpm.proxies<\/code>\u00a0(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0<code>fedora: <\/code><a href=\"https:\/\/download.fedoraproject.org\/\" rel=\"noopener noreferrer nofollow\"><code>https:\/\/download.fedoraproject.org\/<\/code><\/a><code>...<\/code>), \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00a0<strong>\u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Debian\/APT<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705*<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014 (\u043d\u0435\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043f\u0430\u043a\u0435\u0442\u044b (immutable) + Packages\/Release (\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f)<\/p>\n<\/td>\n<td>\n<p align=\"left\">hosted; pull-through \u0447\u0435\u0440\u0435\u0437\u00a0<code>config.registries.deb.proxies<\/code>\u00a0(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0<code>debian: <\/code><a href=\"https:\/\/deb.debian.org\/debian\" rel=\"noopener noreferrer nofollow\"><code>https:\/\/deb.debian.org\/debian<\/code><\/a>), \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00a0<strong>\u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Raw<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014 (\u043d\u0435\u0442 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>hosted only<\/strong>\u00a0\u2014 \u0430\u043f\u0441\u0442\u0440\u0438\u043c-\u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u0442 \u043f\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0443 (\u043b\u044e\u0431\u043e\u0439 \u0444\u0430\u0439\u043b \u043f\u043e \u043b\u044e\u0431\u043e\u043c\u0443 \u043f\u0443\u0442\u0438); \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0447\u0435\u0433\u043e<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u0418\u0442\u043e\u0433\u043e: \u0442\u043e\u043b\u044c\u043a\u043e Raw \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430<\/strong>\u00a0\u2014 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 14 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 (Docker, Helm OCI, npm, PyPI, Maven, Cargo, Go, Terraform, RubyGems, NuGet, Ansible, Pub, Conan \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0442 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438; RPM \u0438 Debian\/APT \u2014 \u0447\u0435\u0440\u0435\u0437 pull-through, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u044f\u0432\u043d\u043e \u0447\u0435\u0440\u0435\u0437\u00a0<code>config.registries.rpm.proxies<\/code>\u00a0\/\u00a0<code>config.registries.deb.proxies<\/code>\u00a0\u0432\u00a0<code>helm-values.yaml<\/code>).<\/p>\n<p>\u0422\u0438\u043f\u044b \u043a\u044d\u0448\u0430:<\/p>\n<ul>\n<li>\n<p><strong>immutable<\/strong>\u00a0\u2014 \u043f\u0430\u043a\u0435\u0442\/\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f (content-addressed, \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f). \u042d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 rate-limit \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>TTL<\/strong>\u00a0\u2014 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 (index, search, version list) \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441 TTL (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 300\u0441 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437\u00a0<code>&lt;registry&gt;.metadata_ttl<\/code>); \u043f\u0440\u0438 \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 TTL NORA \u0440\u0435\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u0442 \u0443 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 (<code>If-None-Match<\/code>\/<code>If-Modified-Since<\/code>), \u043f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 \u2014 \u043e\u0442\u0434\u0430\u0451\u0442 stale.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421 v1.2.0 \u0432\u0441\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u00a0<strong>\u0434\u043e\u043a\u0430\u0447\u043a\u0443 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a<\/strong>\u00a0(HTTP\u00a0<code>Range<\/code>\u00a0\/\u00a0<code>206 Partial Content<\/code>):\u00a0<code>curl -C -<\/code>,\u00a0<code>pip<\/code>,\u00a0<code>apt<\/code>\u00a0\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0441 \u043c\u0435\u0441\u0442\u0430 \u043e\u0431\u0440\u044b\u0432\u0430 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u041c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 (\u0438\u043d\u0434\u0435\u043a\u0441\u044b, packuments, repodata) \u0438\u0441\u043a\u043b\u044e\u0447\u0451\u043d \u2014 \u0434\u043e\u043a\u0430\u0447\u043a\u0430 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u043f\u043e\u0432\u0435\u0440\u0445 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043a\u043b\u0435\u0438\u043b\u0430 \u0431\u044b \u0434\u0432\u0430 \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430.<\/p>\n<h4>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 pull-through \u0434\u043b\u044f RPM\/Debian<\/h4>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e RPM \u0438 Debian\/APT \u0432 NORA \u2014 hosted-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 (\u0432\u044b \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442\u0435 \u0441\u0432\u043e\u0438 \u043f\u0430\u043a\u0435\u0442\u044b). \u0427\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0435\u0449\u0451 \u0438 \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0430\u043f\u0441\u0442\u0440\u0438\u043c, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u0432\u00a0<code>helm-values.yaml<\/code>:<\/p>\n<pre><code>config:  registries:    rpm:      proxies:        fedora: \"https:\/\/download.fedoraproject.org\/pub\/fedora\/linux\/releases\/40\/Everything\/x86_64\/os\"    deb:      proxies:        debian: \"https:\/\/deb.debian.org\/debian\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e\u00a0<code>dnf install --enablerepo=nora-fedora vim<\/code>\u00a0\/\u00a0<code>apt install vim<\/code>\u00a0\u043f\u043e\u0439\u0434\u0451\u0442 \u0447\u0435\u0440\u0435\u0437 NORA (pull-through, immutable \u043a\u044d\u0448).<\/p>\n<h4>Docker<\/h4>\n<pre><code># Docker login \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c (\u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u043e\u043b\u044f, \u043b\u044e\u0431\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f)docker login $NORA_FQDN -u token -p nra_13ef0a4c309d4750907648409f57a65c# \u0411\u0435\u0440\u0451\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 (\u0438\u043b\u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0432\u043e\u0439 \u0438\u0437 Dockerfile)docker pull nginx:alpine# \u041f\u0443\u0448\u0438\u043c \u043e\u0431\u0440\u0430\u0437docker tag nginx:alpine $NORA_FQDN\/myapp:1.0docker push $NORA_FQDN\/myapp:1.0# \u041f\u0443\u043b\u043b\u0438\u043c \u043e\u0431\u0440\u0430\u0437 \u0438\u0437 NORAdocker pull $NORA_FQDN\/myapp:1.0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>NORA \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430 \u0441 Docker Registry v2 API, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\u00a0<code>docker<\/code>\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 v1.2.0 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f cross-repo blob mount (<code>POST \/v2\/{name}\/blobs\/uploads\/?mount={digest}&amp;from={repo}<\/code>) \u2014 blob \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0440\u0435\u0435\u0441\u0442\u0440\u0430 \u0431\u0435\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438; \u043f\u0440\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0438 \u043b\u0438\u043c\u0438\u0442\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a NORA \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 OCI-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439\u00a0<code>429<\/code>\u00a0\u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u043c\u00a0<code>Retry-After<\/code>.<\/p>\n<h4>npm<\/h4>\n<pre><code># \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f npmnpm config set \/\/$NORA_FQDN:_authToken nra_13ef0a4c309d4750907648409f57a65c# \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0440\u0435\u0435\u0441\u0442\u0440\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430npm config set registry https:\/\/$NORA_FQDN\/npm\/# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 (NORA \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 npmjs.org \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442)npm install lodash<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 npm publish<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442:<\/p>\n<pre><code>mkdir -p test-npm-pkgcat &lt;&lt;EOF &gt;  test-npm-pkg\/package.json{  \"name\": \"@test\/hello-world\",  \"version\": \"1.0.0\",  \"description\": \"Test package for Nora registry\",  \"main\": \"index.js\"}EOFcat &lt;&lt;EOF &gt;  test-npm-pkg\/index.jsmodule.exports = function hello() {  return \"Hello from Nora registry!\";};EOFcd test-npm-pkgnpm config set \/\/$NORA_FQDN\/npm\/:_authToken nra_13ef0a4c309d4750907648409f57a65c# \u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c (\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 test-npm-pkg)npm publish --registry https:\/\/$NORA_FQDN\/npm\/# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443cd .. &amp;&amp; mkdir test-install &amp;&amp; cd test-installnpm init -ynpm install @test\/hello-world --registry https:\/\/$NORA_FQDN\/npm\/node -e \"const hello = require('@test\/hello-world'); console.log(hello());\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430:<\/p>\n<pre><code>test-npm-pkg\/\u251c\u2500\u2500 package.json   # \u0438\u043c\u044f: @test\/hello-world, \u0432\u0435\u0440\u0441\u0438\u044f: 1.0.0\u2514\u2500\u2500 index.js       # module.exports = function hello() { return \"Hello from Nora registry!\"; }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043b\u0438 \u0447\u0435\u0440\u0435\u0437\u00a0<code>.npmrc<\/code>\u00a0\u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435:<\/p>\n<pre><code>registry=https:\/\/$NORA_FQDN\/npm\/<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Scoped-\u043f\u0430\u043a\u0435\u0442\u044b \u0442\u043e\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442:<\/p>\n<pre><code>npm install @babel\/core --registry https:\/\/$NORA_FQDN\/npm\/<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>PyPI<\/h4>\n<pre><code># \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0438 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435python3 -m venv .venvsource .venv\/bin\/activate# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 pip (\u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438)python3 -m ensurepip --upgrade# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 NORA (\u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c)python3 -m pip install --index-url https:\/\/token:nra\\_13ef0a4c309d4750907648409f57a65c@$NORA_FQDN\/simple\/ flask<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e Python-\u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>test-python-pkg\/\u251c\u2500\u2500 pyproject.toml\u251c\u2500\u2500 src\/\u2502   \u2514\u2500\u2500 test_python_pkg\/\u2502       \u2514\u2500\u2500 __init__.py\u2514\u2500\u2500 dist\/<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>cd test-python-pkgpython3 -m venv .venvsource .venv\/bin\/activatepip install build twinepython -m buildtwine upload --repository-url https:\/\/token:nra\\_13ef0a4c309d4750907648409f57a65c@$NORA_FQDN\/simple\/ dist\/*<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435\u00a0<code>~\/.pip\/pip.conf<\/code>:<\/p>\n<pre><code>[global]index-url = https:\/\/$NORA_FQDN\/simple\/<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 PEP 503 (HTML) \u0438 PEP 691 (JSON) \u2014 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u044b pip \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 JSON API.<\/p>\n<h4>Maven<\/h4>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e Maven-\u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>test-maven-pkg\/\u251c\u2500\u2500 pom.xml\u251c\u2500\u2500 settings.xml\u2514\u2500\u2500 src\/main\/java\/com\/example\/HelloNora.java<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435\u00a0<code>pom.xml<\/code>\u00a0\u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0430 \u0438 \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt;  test-maven-pkg\/pom.xml&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0                             http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;    &lt;groupId&gt;com.example&lt;\/groupId&gt;    &lt;artifactId&gt;hello-nora&lt;\/artifactId&gt;    &lt;version&gt;1.0.0&lt;\/version&gt;    &lt;packaging&gt;jar&lt;\/packaging&gt;    &lt;name&gt;hello-nora&lt;\/name&gt;    &lt;description&gt;Minimal Maven package for NORA registry test&lt;\/description&gt;    &lt;properties&gt;        &lt;maven.compiler.source&gt;11&lt;\/maven.compiler.source&gt;        &lt;maven.compiler.target&gt;11&lt;\/maven.compiler.target&gt;        &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;    &lt;\/properties&gt;    &lt;distributionManagement&gt;        &lt;repository&gt;            &lt;id&gt;nora&lt;\/id&gt;            &lt;name&gt;NORA Maven Repository&lt;\/name&gt;            &lt;url&gt;https:\/\/$NORA_FQDN\/maven2&lt;\/url&gt;        &lt;\/repository&gt;    &lt;\/distributionManagement&gt;&lt;\/project&gt;EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435\u00a0<code>settings.xml<\/code>\u00a0\u0441 \u0443\u0447\u0451\u0442\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt; test-maven-pkg\/settings.xml&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;settings xmlns=\"http:\/\/maven.apache.org\/SETTINGS\/1.0.0\"&gt;    &lt;servers&gt;        &lt;server&gt;            &lt;id&gt;nora&lt;\/id&gt;            &lt;username&gt;admin&lt;\/username&gt;            &lt;password&gt;your-password&lt;\/password&gt;        &lt;\/server&gt;    &lt;\/servers&gt;&lt;\/settings&gt;EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>mkdir -p test-maven-pkg\/src\/main\/java\/com\/examplecat &lt;&lt;EOF &gt;  test-maven-pkg\/src\/main\/java\/com\/example\/HelloNora.javapackage com.example;public class HelloNora {    public static String greet() {        return \"Hello from NORA!\";    }    public static void main(String[] args) {        System.out.println(greet());    }}EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0430:<\/p>\n<pre><code>cd test-maven-pkgmvn deploy -s settings.xml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Helm OCI<\/h4>\n<p>Helm-\u0447\u0430\u0440\u0442\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 Docker\/OCI endpoint. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0438 \u0437\u0430\u043f\u0430\u043a\u0443\u0439\u0442\u0435 \u0447\u0430\u0440\u0442:<\/p>\n<pre><code>mkdir -p test-helm-pkg# \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u0435helm registry login $NORA_FQDN -u admin -p your-password# \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0447\u0430\u0440\u0442cd test-helm-pkghelm create mychart# \u0417\u0430\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432 .tgzhelm package mychart# \u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0447\u0430\u0440\u0442\u0430helm push mychart-0.1.0.tgz oci:\/\/$NORA_FQDN\/helm# \u0421\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0440\u0442\u0430helm pull oci:\/\/$NORA_FQDN\/helm\/mychart --version 0.1.0# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0447\u0430\u0440\u0442\u0430 \u0438\u0437 NORAhelm install myrelease oci:\/\/$NORA_FQDN\/helm\/mychart --version 0.1.0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Go modules<\/h4>\n<p>\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u00a0<code>go get<\/code>\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 Go-\u043c\u043e\u0434\u0443\u043b\u044f (\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441\u00a0<code>go.mod<\/code>):<\/p>\n<pre><code># \u0415\u0441\u043b\u0438 \u043c\u043e\u0434\u0443\u043b\u044c \u0435\u0449\u0451 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d \u2014 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043cmkdir test-go-pkg &amp;&amp; cd test-go-pkggo mod init test-go-pkg<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 Go proxy \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439.<\/p>\n<p><strong>\u0412\u0430\u0440\u0438\u0430\u043d\u0442 1: \u0422\u043e\u043a\u0435\u043d \u0432 URL (\u043f\u0440\u043e\u0449\u0435)<\/strong><\/p>\n<pre><code># \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e \u0447\u0435\u0440\u0435\u0437 go env (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)go env -w GOPROXY=https:\/\/token:nra\\_13ef0a4c309d4750907648409f57a65c@$NORA_FQDN\/go,direct# \u0418\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044fexport GOPROXY=https:\/\/token:nra\\_13ef0a4c309d4750907648409f57a65c@$NORA_FQDN\/go,direct<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0412\u0430\u0440\u0438\u0430\u043d\u0442 2: \u0427\u0435\u0440\u0435\u0437 .netrc (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f CI\/CD)<\/strong><\/p>\n<pre><code>echo \"machine $NORA_FQDN login token password nra_13ef0a4c309d4750907648409f57a65c\" &gt;&gt; ~\/.netrcchmod 600 ~\/.netrcgo env -w GOPROXY=https:\/\/$NORA_FQDN\/go,direct<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c go get \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 NORA:<\/p>\n<pre><code>go get golang.org\/x\/text@latest<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Go-\u043c\u043e\u0434\u0443\u043b\u0438 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u2014 NORA \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u00a0<code>.info<\/code>,\u00a0<code>.mod<\/code>,\u00a0<code>.zip<\/code>\u00a0\u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430.<\/p>\n<h4>Cargo (Rust)<\/h4>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e Rust-\u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>test-cargo-pkg\/\u251c\u2500\u2500 .cargo\/config.toml   # \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u251c\u2500\u2500 Cargo.toml           # \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430\u2514\u2500\u2500 src\/lib.rs           # \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code>mkdir -p test-cargo-pkg\/.cargo test-cargo-pkg\/src<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435\u00a0<code>.cargo\/config.toml<\/code>\u00a0\u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0440\u0435\u0435\u0441\u0442\u0440\u0430:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt;  test-cargo-pkg\/.cargo\/config.toml[registries.nora]index = \"sparse+https:\/\/$NORA_FQDN\/cargo\/index\/\"[registry]global-credential-providers = [\"cargo:token\"][source.crates-io]replace-with = \"nora\"EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u0435 (\u0442\u043e\u043a\u0435\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u00a0<code>Bearer<\/code>):<\/p>\n<pre><code># \u0412\u0430\u0440\u0438\u0430\u043d\u0442 1: \u0447\u0435\u0440\u0435\u0437 stdin (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f CI\/CD)echo \"Bearer nra_13ef0a4c309d4750907648409f57a65c\" | cargo login --registry nora# \u0412\u0430\u0440\u0438\u0430\u043d\u0442 2: \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044fexport CARGO_REGISTRIES_NORA_TOKEN=\"Bearer nra_13ef0a4c309d4750907648409f57a65c\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p><strong>\u0412\u0430\u0436\u043d\u043e:<\/strong>\u00a0\u043f\u0440\u0435\u0444\u0438\u043a\u0441\u00a0<code>Bearer <\/code>\u00a0\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u2014 \u0431\u0435\u0437 \u043d\u0435\u0433\u043e Cargo \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443\u00a0<code>the token does not include an authentication scheme<\/code>.\u00a0<code>cargo login --registry nora<\/code>\u00a0\u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0435\u0441\u0442\u0440\u00a0<code>nora<\/code>\u00a0\u0431\u044b\u043b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0435\u00a0<code>~\/.cargo\/config.toml<\/code>. \u0415\u0441\u043b\u0438 \u0440\u0435\u0435\u0441\u0442\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u043d\u043e\u043c\u00a0<code>.cargo\/config.toml<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u00a0<code>CARGO_REGISTRIES_NORA_TOKEN<\/code>.<\/p>\n<\/blockquote>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435\u00a0<code>Cargo.toml<\/code>\u00a0\u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u043a\u0435\u0442\u0430:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt;  test-cargo-pkg\/Cargo.toml[package]name = \"test-cargo-pkg\"version = \"0.1.0\"edition = \"2021\"description = \"Test Cargo package for Nora registry\"EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0444\u0430\u0439\u043b\u00a0<code>src\/<\/code><a href=\"http:\/\/lib.rs\" rel=\"noopener noreferrer nofollow\"><code>lib.rs<\/code><\/a>:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt;  test-cargo-pkg\/src\/lib.rspub fn hello() -&gt; &amp;'static str {    \"Hello from Nora!\"}EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f:<\/p>\n<pre><code>cd test-cargo-pkgcargo build  # \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u044f\u043d\u0443\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 NORAcargo publish --registry nora<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>NORA \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 Cargo sparse index (RFC 2789) \u2014 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c git-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438\u043d\u0434\u0435\u043a\u0441\u0430.<\/p>\n<h4>Terraform<\/h4>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a Terraform \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a Authorization, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 helm-values.yaml \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u00a0<code>anonymous_read: true<\/code>.<\/p>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435\u00a0<code>~\/.terraformrc<\/code>:<\/p>\n<pre><code>provider_installation {  network_mirror {    url = \"https:\/\/$NORA_FQDN\/terraform\/\"  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435\u00a0<code>terraform init<\/code>\u00a0\u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u0447\u0435\u0440\u0435\u0437 NORA:<\/p>\n<pre><code>terraform init# Provider hashicorp\/aws will be downloaded from $NORA_FQDN<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>RubyGems<\/h4>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache \u0434\u043b\u044f RubyGems \u2014 \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <a href=\"http:\/\/rubygems.org\" rel=\"noopener noreferrer nofollow\">rubygems.org<\/a> \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0433\u0435\u043c\u044b.<\/p>\n<blockquote>\n<p>Pull-through \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d:\u00a0<code>bundle install<\/code>\u00a0\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u043b\u00a0<code>rake 13.4.2<\/code>\u00a0\u0447\u0435\u0440\u0435\u0437\u00a0<a href=\"https:\/\/%24NORA_FQDN\/gems\/\" rel=\"noopener noreferrer nofollow\"><code>https:\/\/$NORA_FQDN\/gems\/<\/code><\/a>. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 NORA (<code>nora-registry\/src\/registry\/<\/code><a href=\"http:\/\/gems.rs\" rel=\"noopener noreferrer nofollow\"><code>gems.rs<\/code><\/a>,\u00a0<code>pub fn routes<\/code>): \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u2014 \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<code>get<\/code>\u00a0(<code>specs_index<\/code>,\u00a0<code>latest_specs_index<\/code>,\u00a0<code>info<\/code>,\u00a0<code>download_gem<\/code>,\u00a0<code>download_gemspec<\/code>); POST\/PUT-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u0442.<\/p>\n<\/blockquote>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0437\u0435\u0440\u043a\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 bundler \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 NORA \u043a\u0430\u043a \u0437\u0435\u0440\u043a\u0430\u043b\u0430 <a href=\"http:\/\/rubygems.org\" rel=\"noopener noreferrer nofollow\">rubygems.org<\/a>:<\/p>\n<pre><code># \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)bundle config mirror.https:\/\/rubygems.org https:\/\/$NORA_FQDN\/gems\/# \u0418\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 .bundle\/config \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435mkdir -p .bundlecat &lt;&lt;EOF &gt;  .bundle\/config---BUNDLE_MIRROR__HTTPS:\/\/RUBYGEMS__ORG\/: \"https:\/\/$NORA_FQDN\/gems\/\"EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/h3>\n<pre><code>bundle install<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>NuGet (.NET)<\/h4>\n<p>NORA \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <a href=\"http:\/\/nuget.org\" rel=\"noopener noreferrer nofollow\">nuget.org<\/a> \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b \u0447\u0435\u0440\u0435\u0437 NuGet V3 API.<\/p>\n<blockquote>\n<p>Pull-through \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d:\u00a0<code>dotnet restore --source nora<\/code>\u00a0\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u043b\u00a0<code>Newtonsoft.Json 13.0.3<\/code>\u00a0\u0447\u0435\u0440\u0435\u0437 NORA. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 NORA (<code>nora-registry\/src\/registry\/<\/code><a href=\"http:\/\/nuget.rs\" rel=\"noopener noreferrer nofollow\"><code>nuget.rs<\/code><\/a>,\u00a0<code>fn routes_with_prefix<\/code>): \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u2014 \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<code>get<\/code>\u00a0(<code>service_index<\/code>,\u00a0<code>search_query<\/code>,\u00a0<code>autocomplete<\/code>,\u00a0<code>registration_index<\/code>,\u00a0<code>flatcontainer<\/code>); \u0440\u0435\u0441\u0443\u0440\u0441\u00a0<code>PackagePublish\/2.0.0<\/code>\u00a0\u0432 service index \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, PUT\/POST-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043d\u0435\u0442.<\/p>\n<\/blockquote>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/h3>\n<pre><code># \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c NORA \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a NuGet-\u043f\u0430\u043a\u0435\u0442\u043e\u0432dotnet nuget add source https:\/\/$NORA_FQDN\/nuget\/v3\/index.json \\  -n nora \\  -u token \\  -p nra_13ef0a4c309d4750907648409f57a65c \\  --store-password-in-clear-text# \u0418\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 nuget CLInuget source add -Name nora \\  -Source https:\/\/$NORA_FQDN\/nuget\/v3\/index.json \\  -UserName token \\  -Password nra_13ef0a4c309d4750907648409f57a65c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u0444\u0430\u0439\u043b\u00a0<code>nuget.config<\/code>\u00a0\u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435:<\/p>\n<pre><code>&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;&lt;configuration&gt;  &lt;packageSources&gt;    &lt;add key=\"nora\" value=\"https:\/\/$NORA_FQDN\/nuget\/v3\/index.json\" \/&gt;  &lt;\/packageSources&gt;  &lt;packageSourceCredentials&gt;    &lt;nora&gt;      &lt;add key=\"Username\" value=\"token\" \/&gt;      &lt;add key=\"ClearTextPassword\" value=\"nra_13ef0a4c309d4750907648409f57a65c\" \/&gt;    &lt;\/nora&gt;  &lt;\/packageSourceCredentials&gt;&lt;\/configuration&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/h3>\n<pre><code>dotnet restore<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0438\u0437 NORA<\/h3>\n<pre><code>dotnet add package TestNugetPkg --source https:\/\/$NORA_FQDN\/nuget\/v3\/index.json<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Ansible Galaxy<\/h4>\n<p>NORA \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <a href=\"http:\/\/galaxy.ansible.com\" rel=\"noopener noreferrer nofollow\">galaxy.ansible.com<\/a> \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u0440\u043e\u043b\u0438.<\/p>\n<blockquote>\n<p>Pull-through \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d:\u00a0<code>ansible-galaxy collection install community.general<\/code>\u00a0\u0447\u0435\u0440\u0435\u0437 NORA \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u043b\u00a0<code>community.general:13.2.0<\/code>. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 NORA (<code>nora-registry\/src\/registry\/<\/code><a href=\"http:\/\/ansible.rs\" rel=\"noopener noreferrer nofollow\"><code>ansible.rs<\/code><\/a>,\u00a0<code>pub fn routes<\/code>): \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u2014 \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<code>get<\/code>\u00a0(<code>api_discovery<\/code>,\u00a0<code>collection_list<\/code>,\u00a0<code>collection_detail<\/code>,\u00a0<code>version_list<\/code>,\u00a0<code>version_detail<\/code>,\u00a0<code>download_tarball<\/code>); POST-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430\u00a0<code>\/api\/v3\/artifacts\/imports\/<\/code>\u00a0\u043d\u0435\u0442.<\/p>\n<\/blockquote>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439<\/h3>\n<pre><code># \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438\u0437 NORA (\u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439)ansible-galaxy collection install community.general \\  -s https:\/\/$NORA_FQDN\/ansible\/ \\  --token nra_13ef0a4c309d4750907648409f57a65c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u00a0<code>ansible.cfg<\/code>:<\/p>\n<pre><code>[galaxy]server_list = nora[galaxy_server.nora]url = https:\/\/$NORA_FQDN\/ansible\/token = nra_13ef0a4c309d4750907648409f57a65c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\u00a0<code>ansible-galaxy<\/code>\u00a0\u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c NORA:<\/p>\n<pre><code>ansible-galaxy collection install community.generalansible-galaxy role install geerlingguy.docker<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Conan (C\/C++)<\/h4>\n<p>NORA \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b \u043a \u043a ConanCenter (<code>center2.conan.io<\/code>) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Conan V2 API.<\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 conan remote (\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 NORA v1.2.0)<\/h3>\n<pre><code># \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c NORA \u043a\u0430\u043a \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 Conanconan remote add nora https:\/\/$NORA_FQDN\/conan# \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f (\u0442\u043e\u043a\u0435\u043d \u043a\u0430\u043a \u043f\u0430\u0440\u043e\u043b\u044c, \u043b\u044e\u0431\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f)conan remote login nora token -p nra_13ef0a4c309d4750907648409f57a65c# \u041f\u043e\u0438\u0441\u043a \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 NORA (pull-through \u043a\u044d\u0448 ConanCenter)conan list \"zlib\/*\" -r noraconan install . -r nora --build=missing<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 v2-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e (curl)<\/h3>\n<p>v2-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b NORA \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b (proxy\/cache ConanCenter\u00a0<code>center2.conan.io<\/code>). \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 NORA (<code>nora-registry\/src\/registry\/<\/code><a href=\"http:\/\/conan.rs\" rel=\"noopener noreferrer nofollow\"><code>conan.rs<\/code><\/a>,\u00a0<code>pub fn routes<\/code>): \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u2014 \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<code>get<\/code>\u00a0(ping, search, recipe\/package file download, revisions, latest); v1-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u043e\u0434\u0438\u043d \u2014\u00a0<code>GET \/conan\/v1\/ping<\/code>\u00a0(\u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c Conan 2.x), PUT\/POST \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442. \u0422\u0435\u0441\u0442\u044b \u0447\u0435\u0440\u0435\u0437 curl (Basic auth\u00a0<code>token:nra_...<\/code>, \u0432\u0441\u0435 \u0432\u0435\u0440\u043d\u0443\u043b\u0438 HTTP 200):<\/p>\n<ul>\n<li>\n<p><code>GET \/conan\/v1\/ping<\/code>\u00a0\u2192 200 +\u00a0<code>X-Conan-Server-Capabilities: revisions<\/code>\u00a0(\u0441 v1.2.0)<\/p>\n<\/li>\n<li>\n<p><code>GET \/conan\/v2\/ping<\/code>\u00a0\u2192 200<\/p>\n<\/li>\n<li>\n<p><code>GET \/conan\/v2\/conans\/search?q=zlib<\/code>\u00a0\u2192 200 (\u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0435\u0440\u0441\u0438\u0439 zlib: 1.2.11, 1.2.12, 1.2.13, 1.3, 1.3.1, 1.3.2)<\/p>\n<\/li>\n<li>\n<p><code>GET \/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/latest<\/code>\u00a0\u2192 200 (revision\u00a0<code>cac0f6daea041b0ccf42934163defb20<\/code>)<\/p>\n<\/li>\n<li>\n<p><code>GET \/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/revisions<\/code>\u00a0\u2192 200 (4 revision)<\/p>\n<\/li>\n<li>\n<p><code>GET \/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/revisions\/{rrev}\/files<\/code>\u00a0\u2192 200 (<a href=\"http:\/\/conanfile.py\" rel=\"noopener noreferrer nofollow\">conanfile.py<\/a>, conanmanifest.txt, conan_export.tgz, conan_sources.tgz)<\/p>\n<\/li>\n<li>\n<p><code>GET \/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/revisions\/{rrev}\/files\/<\/code><a href=\"http:\/\/conanfile.py\" rel=\"noopener noreferrer nofollow\"><code>conanfile.py<\/code><\/a>\u00a0\u2192 200 (4160 \u0431\u0430\u0439\u0442, \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 <a href=\"http:\/\/conanfile.py\" rel=\"noopener noreferrer nofollow\">conanfile.py<\/a>)<\/p>\n<\/li>\n<\/ul>\n<pre><code># Ping (v1 \u2014 \u0442\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442 Conan 2.x \u043f\u0435\u0440\u0432\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c)curl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" https:\/\/$NORA_FQDN\/conan\/v1\/ping# HTTP 200, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a X-Conan-Server-Capabilities: revisions# Ping (v2)curl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" https:\/\/$NORA_FQDN\/conan\/v2\/ping# HTTP 200# \u041f\u043e\u0438\u0441\u043acurl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  \"https:\/\/$NORA_FQDN\/conan\/v2\/conans\/search?q=zlib\"# {\"results\":[\"zlib\/1.2.11@_\/_\",\"zlib\/1.3.1@_\/_\", ...]}# \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f revision \u0440\u0435\u0446\u0435\u043f\u0442\u0430curl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  https:\/\/$NORA_FQDN\/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/latest# {\"revision\":\"cac0f6daea041b0ccf42934163defb20\",\"time\":\"...\"}# \u0421\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0440\u0435\u0446\u0435\u043f\u0442\u0430curl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  https:\/\/$NORA_FQDN\/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/revisions\/cac0f6daea041b0ccf42934163defb20\/files# {\"files\":{\"conanfile.py\":{},\"conanmanifest.txt\":{}, ...}}# \u0421\u043a\u0430\u0447\u0430\u0442\u044c conanfile.pycurl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" -o conanfile.py \\  https:\/\/$NORA_FQDN\/conan\/v2\/conans\/zlib\/1.3.1\/_\/_\/revisions\/cac0f6daea041b0ccf42934163defb20\/files\/conanfile.py# HTTP 200, 4160 \u0431\u0430\u0439\u0442<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Pub (Dart\/Flutter)<\/h4>\n<p>NORA \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <a href=\"http:\/\/pub.dev\" rel=\"noopener noreferrer nofollow\">pub.dev<\/a> \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b.<\/p>\n<blockquote>\n<p>Pull-through \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d:\u00a0<code>dart pub get<\/code>\u00a0\u0447\u0435\u0440\u0435\u0437\u00a0<code>PUB_HOSTED_URL=<\/code><a href=\"https:\/\/%24NORA_FQDN\/pub\" rel=\"noopener noreferrer nofollow\"><code>https:\/\/$NORA_FQDN\/pub<\/code><\/a>\u00a0\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u043b\u00a0<code>meta 1.19.0<\/code>. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 NORA (<code>nora-registry\/src\/registry\/pub_<\/code><a href=\"http:\/\/dart.rs\" rel=\"noopener noreferrer nofollow\"><code>dart.rs<\/code><\/a>,\u00a0<code>pub fn routes<\/code>): \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u2014 \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<code>get<\/code>\u00a0(<code>search_packages<\/code>,\u00a0<code>package_advisories<\/code>,\u00a0<code>version_metadata<\/code>,\u00a0<code>package_listing<\/code>,\u00a0<code>download_archive<\/code>); GET-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430\u00a0<code>\/api\/packages\/versions\/new<\/code>\u00a0(upload-URL) \u043d\u0435\u0442, POST\/PUT \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442.<\/p>\n<\/blockquote>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430<\/h3>\n<pre><code># \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c NORA \u043a\u0430\u043a \u0445\u043e\u0441\u0442 \u0434\u043b\u044f pubexport PUB_HOSTED_URL=https:\/\/$NORA_FQDN\/pub# \u0414\u043b\u044f Flutterexport FLUTTER_STORAGE_BASE_URL=https:\/\/$NORA_FQDN\/pub<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432\u00a0<code>~\/.bashrc<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>~\/.zshrc<\/code>:<\/p>\n<pre><code>echo 'export PUB_HOSTED_URL=https:\/\/$NORA_FQDN\/pub' &gt;&gt; ~\/.bashrc<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/h3>\n<pre><code>dart pub get# \u0418\u043b\u0438 \u0434\u043b\u044f Flutterflutter pub get<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Raw (\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b)<\/h4>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u2014 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u043e\u0432, \u0430\u0440\u0445\u0438\u0432\u043e\u0432, \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432, release-\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432. \u042d\u0442\u043e hosted-only \u0440\u0435\u0435\u0441\u0442\u0440: \u0430\u043f\u0441\u0442\u0440\u0438\u043c-\u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u0442, \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0442\u043e\u0436\u0435 \u043d\u0435\u0442 \u2014 \u043b\u044e\u0431\u043e\u0439 \u0444\u0430\u0439\u043b \u043f\u043e \u043b\u044e\u0431\u043e\u043c\u0443 \u043f\u0443\u0442\u0438.<\/p>\n<blockquote>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435: PUT \u2192 201, GET, HEAD, DELETE \u2192 204, 409 \u043d\u0430 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442,\u00a0<code>If-None-Match: *<\/code>\u00a0\u2192 412 create-only \u2014 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u0430 S3-\u0431\u044d\u043a\u0435\u043d\u0435 ETag \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f (\u0441\u043c. \u043d\u0438\u0436\u0435).<\/p>\n<\/blockquote>\n<h3>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u0430<\/h3>\n<pre><code># \u0410\u043d\u043e\u043d\u0438\u043c\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 (\u0435\u0441\u043b\u0438 anonymous_read \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u2014 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f; \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043a\u0435\u043d)curl -X PUT --data-binary @release.tar.gz \\  https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz# \u0421 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 (\u0442\u043e\u043a\u0435\u043d \u043a\u0430\u043a \u043f\u0430\u0440\u043e\u043b\u044c, \u043b\u044e\u0431\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f)curl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  -T release.tar.gz \\  https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz# \u0418\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 Bearercurl -H \"Authorization: Bearer nra_13ef0a4c309d4750907648409f57a65c\" \\  -X PUT --data-binary @release.tar.gz \\  https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435<\/h3>\n<pre><code>curl -O https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0441\u043b\u043e\u0432\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044c (RFC 9110)<\/h3>\n<p>Raw \u2014 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 NORA \u0441 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u043c\u0438\u00a0<code>PUT<\/code>: \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0443\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<strong>409 Conflict<\/strong>. \u0414\u043b\u044f \u0437\u0430\u043f\u0440\u0435\u0442\u0430 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0438 (create-only) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435\u00a0<code>If-None-Match: *<\/code>\u00a0\u2014 \u0443\u043f\u0430\u0434\u0451\u0442\u00a0<strong>412 Precondition Failed<\/strong>, \u0435\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u0435\u0441\u0442\u044c.<\/p>\n<pre><code># Create-only: \u0443\u043f\u0430\u0434\u0451\u0442 412, \u0435\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u0435\u0441\u0442\u044ccurl -X PUT -H 'If-None-Match: *' \\  --data-binary @release.tar.gz \\  https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz# \u041a\u043e\u0433\u0434\u0430 NORA \u043d\u0430\u0447\u043d\u0451\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c ETag \u2014 \u0443\u0441\u043b\u043e\u0432\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:# curl -I https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz   # \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c etag# curl -X PUT -H 'If-Match: \"&lt;etag&gt;\"' --data-binary @release-1.1.tar.gz \\#   https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f<\/h3>\n<pre><code># \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435curl -X DELETE https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz# HEAD \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 Content-Typecurl -I https:\/\/$NORA_FQDN\/raw\/builds\/release-1.0.tar.gz<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f<\/h3>\n<ul>\n<li>\n<p>\u041b\u0438\u043c\u0438\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u2014\u00a0<code>raw.max_file_size<\/code>\u00a0(\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 100 \u041c\u0411), \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0442\u0440\u0438\u043c\u0438\u043d\u0433\u0430 (\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u00a0<code>server.body_limit_mb<\/code>\u00a0\u043d\u0430 Raw\u00a0<strong>\u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442<\/strong>).<\/p>\n<\/li>\n<li>\n<p>Path traversal \u043e\u0442\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f (<code>\/raw\/..\/etc\/passwd<\/code>\u00a0\u2192 400\/404).<\/p>\n<\/li>\n<li>\n<p>Directory listing \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<h4>RPM (yum\/dnf)<\/h4>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 hosted RPM-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439\u00a0<code>repodata\/<\/code>\u00a0(\u043a\u0430\u043a\u00a0<code>createrepo<\/code>, \u043d\u043e \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430) \u0438 pull-through \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043f\u0441\u0442\u0440\u0438\u043c yum-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432.<\/p>\n<h3>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 RPM-\u043f\u0430\u043a\u0435\u0442\u0430<\/h3>\n<pre><code># \u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c .rpm \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 myrepo (\u0438\u043c\u044f \u0440\u0435\u043f\u043e \u2014 \u043b\u044e\u0431\u043e\u0439 \u043f\u0443\u0442\u044c \/rpm\/&lt;name&gt;\/)curl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  -T myapp-1.0-1.x86_64.rpm \\  https:\/\/$NORA_FQDN\/rpm\/myrepo\/myapp-1.0-1.x86_64.rpm<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 NORA \u043f\u0430\u0440\u0441\u0438\u0442 \u0438 \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u0442 RPM-\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a; \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u043e\u0442\u0432\u0435\u0440\u0433\u0430\u044e\u0442\u0441\u044f. \u041f\u043e\u0441\u043b\u0435 publish\/delete\u00a0<code>repodata\/<\/code>\u00a0(<code>repomd.xml<\/code>,\u00a0<code>primary\/filelists\/other.xml.gz<\/code>) \u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 yum\/dnf<\/h3>\n<pre><code>sudo tee \/etc\/yum.repos.d\/nora-myrepo.repo &lt;&lt;EOF[nora-myrepo]name=NORA myrepobaseurl=https:\/\/$NORA_FQDN\/rpm\/myrepoenabled=1gpgcheck=0repo_gpgcheck=0EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p><code>gpgcheck=0<\/code>\u00a0\u2014 NORA \u043d\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0430\u043c\u0438 \u043f\u0430\u043a\u0435\u0442\u044b, \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435. \u041d\u0430 S3-\u0431\u044d\u043a\u0435\u043d\u0434\u0435 \u0431\u0435\u0437\u00a0<code>signing.key_path<\/code>\u00a0\u043f\u043e\u0434\u043f\u0438\u0441\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443\u00a0<code>repo_gpgcheck=0<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u00a0<code>signing.enabled<\/code>\u00a0+\u00a0<code>signing.key_path<\/code>, \u043f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435\u00a0<code>repo_gpgcheck=1<\/code>\u00a0\u0438\u00a0<code>gpgkey=<\/code><a href=\"https:\/\/%24NORA_FQDN\/rpm\/myrepo\/repodata\/repomd.xml.key\" rel=\"noopener noreferrer nofollow\"><code>https:\/\/$NORA_FQDN\/rpm\/myrepo\/repodata\/repomd.xml.key<\/code><\/a>.<\/p>\n<\/blockquote>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/h3>\n<pre><code>sudo dnf clean allsudo dnf install myapp<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>Pull-through \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043f\u0441\u0442\u0440\u0438\u043c-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/h3>\n<p>\u0412\u00a0<code>helm-values.yaml<\/code>\u00a0\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u0438\u043c\u0435\u043d\u0438 \u0440\u0435\u043f\u043e \u043d\u0430 \u0430\u043f\u0441\u0442\u0440\u0438\u043c:<\/p>\n<pre><code>config:  registries:    rpm:      proxies:        fedora: \"https:\/\/download.fedoraproject.org\/pub\/fedora\/linux\/releases\/40\/Everything\/x86_64\/os\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>sudo dnf install --enablerepo=nora-fedora vim<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>Reindex (\u043b\u0435\u0447\u0435\u043d\u0438\u0435 out-of-band \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439)<\/h3>\n<pre><code>curl -X POST https:\/\/$NORA_FQDN\/rpm\/myrepo\/-\/reindex<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0417\u0435\u0440\u043a\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f air-gapped<\/h3>\n<pre><code>nora mirror rpm --repo myrepo --arch x86_64,noarch \\  --registry https:\/\/$NORA_FQDN<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f<\/h3>\n<ul>\n<li>\n<p>RPM \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437\u00a0<code>registries.enable: \"all\"<\/code>.<\/p>\n<\/li>\n<li>\n<p>SQLite-\u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 (<code>*_db<\/code>), delta-RPM \u0438 module metadata (<code>modules.yaml<\/code>) \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u2014 \u0442\u043e\u043b\u044c\u043a\u043e XML.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439\u00a0<code>\/rpm\/{repo}\/<\/code>\u00a0\u2014 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<h4>Debian\/APT<\/h4>\n<p>NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 hosted APT-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439\u00a0<code>Packages<\/code>\/<code>Release<\/code>\/<code>InRelease<\/code>\u00a0(\u0431\u0435\u0437\u00a0<code>dpkg-scanpackages<\/code>) \u0438 pull-through \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u00a0<a href=\"http:\/\/deb.debian.org\" rel=\"noopener noreferrer nofollow\"><code>deb.debian.org<\/code><\/a>\u00a0\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0435\u0440\u043a\u0430\u043b. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0430 layout:\u00a0<strong>flat<\/strong>\u00a0(\u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0432 \u043a\u043e\u0440\u043d\u0435 \u0440\u0435\u043f\u043e) \u0438\u00a0<strong>structured<\/strong>\u00a0(dists\/suites \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438).<\/p>\n<h3>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 .deb<\/h3>\n<pre><code># Flat \u2014 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0432 \u043a\u043e\u0440\u043d\u0435 \u0440\u0435\u043f\u043ecurl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  -T myapp_1.0_amd64.deb \\  https:\/\/$NORA_FQDN\/deb\/myrepo\/myapp_1.0_amd64.deb# Structured \u2014\u6307\u5b9a distribution \u0438 component \u0447\u0435\u0440\u0435\u0437 query-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044bcurl -u \"token:nra_13ef0a4c309d4750907648409f57a65c\" \\  -T myapp_1.0_amd64.deb \\  \"https:\/\/$NORA_FQDN\/deb\/myrepo\/pool\/main\/m\/myapp\/myapp_1.0_amd64.deb?distribution=jammy&amp;component=main\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>NORA \u043f\u0430\u0440\u0441\u0438\u0442 control-\u043f\u0430\u0440\u0430\u0433\u0440\u0430\u0444 \u0438\u0437\u00a0<code>.deb<\/code>\u00a0(\u0431\u0435\u0437\u00a0<code>dpkg-scanpackages<\/code>), \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u0442 \u0438 \u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044b\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b (<code>Packages<\/code>,\u00a0<code>Packages.gz<\/code>,\u00a0<code>Release<\/code>,\u00a0<code>InRelease<\/code>,\u00a0<code>Release.gpg<\/code>).<\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 apt<\/h3>\n<pre><code># \u041a\u043b\u044e\u0447 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f (\u043d\u0430 S3 \u0431\u0435\u0437 signing.key_path \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 [trusted=yes] \u0432\u043c\u0435\u0441\u0442\u043e signed-by)curl -fsSL https:\/\/$NORA_FQDN\/deb\/myrepo\/pubkey.gpg \\  -o \/etc\/apt\/keyrings\/nora.asc# Flatecho \"deb [signed-by=\/etc\/apt\/keyrings\/nora.asc] https:\/\/$NORA_FQDN\/deb\/myrepo .\/\" \\  &gt; \/etc\/apt\/sources.list.d\/nora.list# Structuredecho \"deb [signed-by=\/etc\/apt\/keyrings\/nora.asc] https:\/\/$NORA_FQDN\/deb\/myrepo jammy main\" \\  &gt; \/etc\/apt\/sources.list.d\/nora.list<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430 (\u043d\u0430 S3-\u0431\u044d\u043a\u0435\u043d\u0434\u0435 \u0431\u0435\u0437\u00a0<code>signing.key_path<\/code>), \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0435\u00a0<code>[signed-by=...]<\/code>\u00a0\u043d\u0430\u00a0<code>[trusted=yes]<\/code>:<\/p>\n<p>echo &#171;deb [trusted=yes] <a href=\"https:\/\/%24NORA_FQDN\/deb\/myrepo\" rel=\"noopener noreferrer nofollow\">https:\/\/$NORA_FQDN\/deb\/myrepo<\/a> .\/&#187; &gt; \/etc\/apt\/sources.list.d\/nora.list<\/p>\n<\/blockquote>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/h3>\n<pre><code>sudo apt updatesudo apt install myapp<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>Pull-through \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043f\u0441\u0442\u0440\u0438\u043c<\/h3>\n<pre><code>config:  registries:    deb:      proxies:        debian: \"https:\/\/deb.debian.org\/debian\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>sudo apt install --no-install-recommends vim<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>Reindex \u0438 air-gapped mirror<\/h3>\n<pre><code># \u041b\u0435\u0447\u0435\u043d\u0438\u0435 out-of-band \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439curl -X POST https:\/\/$NORA_FQDN\/deb\/myrepo\/-\/reindex# \u0417\u0435\u0440\u043a\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f air-gappednora mirror deb --repo myrepo --dist jammy --component main --arch amd64 \\  --registry https:\/\/$NORA_FQDN<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f<\/h3>\n<ul>\n<li>\n<p>Debian \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437\u00a0<code>registries.enable: \"all\"<\/code>\u00a0(\u0443\u0436\u0435 \u0432\u00a0<code>helm-values.yaml.tpl<\/code>).<\/p>\n<\/li>\n<li>\n<p><code>by-hash<\/code>\u00a0\u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0438\u00a0<code>Translations<\/code>\/<code>Contents<\/code>\u00a0\u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u2014 \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<code>Packages{,.gz}<\/code>\u00a0+\u00a0<code>Release<\/code>\u00a0+\u00a0<code>InRelease<\/code>\/<code>Release.gpg<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412 structured layout arch-<code>all<\/code>\u00a0\u043f\u0430\u043a\u0435\u0442\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432\u043e \u0432\u0441\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440.<\/p>\n<\/li>\n<li>\n<p>Upload path free-form:\u00a0<code>Filename<\/code>\u00a0\u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043a\u043e\u0440\u043d\u044f \u0440\u0435\u043f\u043e; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u00a0<code>pool\/...<\/code>\u00a0\u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 supply chain \u0430\u0442\u0430\u043a<\/h3>\n<p>NORA \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0443\u044e \u0437\u0430\u0449\u0438\u0442\u0443 \u043e\u0442 \u0430\u0442\u0430\u043a \u043d\u0430 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043f\u043e\u0441\u0442\u0430\u0432\u043e\u043a \u2014 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0438\u0437 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0435\u0441\u0442\u0440\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 production \u0447\u0435\u0440\u0435\u0437 \u0432\u0430\u0448 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 registry. \u042f\u0440\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u2014 31 \u043c\u0430\u0440\u0442\u0430 2026 \u0433\u043e\u0434\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 DPRK Sapphire Sleet \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 npm-\u043f\u0430\u043a\u0435\u0442\u043e\u043c axios (100 \u043c\u043b\u043d \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a \u0432 \u043d\u0435\u0434\u0435\u043b\u044e), \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0432 \u0432\u0440\u0435\u0434\u043e\u043d\u043e\u0441\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e 1.14.1. \u041e\u043a\u043d\u043e \u0430\u0442\u0430\u043a\u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u0432\u0441\u0435\u0433\u043e 3 \u0447\u0430\u0441\u0430, \u043d\u043e \u043c\u043e\u0433\u043b\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044c \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432.<\/p>\n<h4>Min Release Age \u2014 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/h4>\n<p>\u041e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b, \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u043d\u0435\u0435 N \u0434\u043d\u0435\u0439 \u043d\u0430\u0437\u0430\u0434. \u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0432\u0440\u0435\u0434\u043e\u043d\u043e\u0441\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 1\u20133 \u0434\u043d\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 7 \u0434\u043d\u0435\u0439 \u2014 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0435\u0441\u0442\u044c \u0432\u00a0<code>.npmrc<\/code>\u00a0(<code>min-release-age=7<\/code>) \u0438\u00a0<code>uv.toml<\/code>\u00a0(<code>exclude-newer = \"7 days\"<\/code>), \u043d\u043e NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432 \u0438 per-registry \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0432\u00a0<\/strong><code><strong>helm-values.yaml<\/strong><\/code><strong>\u00a0(\u0441\u0435\u043a\u0446\u0438\u044f\u00a0<\/strong><code><strong>config.curation<\/strong><\/code><strong>):<\/strong><\/p>\n<pre><code>config:  curation:    mode: \"enforce\"    min_release_age: \"7d\"    npm:      min_release_age: \"3d\"    pypi:      min_release_age: \"5d\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:\u00a0<code>7d<\/code>\u00a0(\u0434\u043d\u0438),\u00a0<code>24h<\/code>\u00a0(\u0447\u0430\u0441\u044b),\u00a0<code>1w<\/code>\u00a0(\u043d\u0435\u0434\u0435\u043b\u0438),\u00a0<code>1w2d<\/code>\u00a0(\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438).<\/p>\n<p><strong>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u0442\u044b \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438<\/strong>\u00a0\u2014 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u0442\u044b \u0438\u0437 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445: npm\u00a0<code>time<\/code>, PyPI\u00a0<code>upload-time<\/code>, Cargo, Go, NuGet, Conan, <a href=\"http:\/\/pub.dev\" rel=\"noopener noreferrer nofollow\">pub.dev<\/a>, Maven Central, RubyGems, Ansible Galaxy, Terraform. NORA \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0434\u0430\u0442\u0443 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0430 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0435\u0451 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p><strong>Digest quarantine<\/strong>\u00a0\u2014 \u0434\u043b\u044f \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432 \u0431\u0435\u0437 \u0434\u0430\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 (Docker\/OCI) NORA \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e content digest. \u041d\u043e\u0432\u044b\u0435 digest \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d\u0435 \u0434\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u043e\u0433\u0430. \u042d\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u044b \u0441\u0430\u043c\u043e\u0439 NORA, \u0430 \u043d\u0435 unsigned upstream \u0434\u0430\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>Fail-closed<\/strong>\u00a0\u2014 \u0435\u0441\u043b\u0438 \u0434\u0430\u0442\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0438 \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0430\u043a\u0442\u0438\u0432\u0435\u043d, \u043f\u0430\u043a\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f (\u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f).<\/p>\n<\/li>\n<li>\n<p><strong>Bypass token<\/strong>\u00a0\u2014 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a\u00a0<code>X-Nora-Bypass-Token<\/code>\u00a0\u0434\u043b\u044f \u044d\u043a\u0441\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 (\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0432 constant-time).<\/p>\n<\/li>\n<\/ul>\n<h4>CVE Blocking \u2014 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e-\u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/h4>\n<p>NORA \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b \u0441 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 CVE \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c blocklist. \u042d\u0442\u043e \u043d\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 CVE (\u043a\u0430\u043a Trivy \u0438\u043b\u0438 Snyk), \u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u043b\u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u0431\u0430\u0437 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<pre><code>{  \"version\": 1,  \"rules\": [    {      \"registry\": \"npm\",      \"name\": \"event-stream\",      \"version\": \"3.3.6\",      \"reason\": \"CVE-2018-16396 \u2014 malicious flatmap-stream dependency\"    },    {      \"registry\": \"*\",      \"name\": \"log4j*\",      \"version\": \"2.*\",      \"reason\": \"CVE-2021-44228 \u2014 Log4Shell RCE\"    }  ]}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 glob-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b (<code>*<\/code>,\u00a0<code>foo*<\/code>,\u00a0<code><em>foo<\/em><\/code><em>,\u00a0<\/em><code><em>foo.<\/em>*<\/code>\u00a0\u0434\u043b\u044f Maven groupId,\u00a0<code>foo\/**<\/code>\u00a0\u0434\u043b\u044f Go \u043c\u043e\u0434\u0443\u043b\u0435\u0439) \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 15 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c\u0438 \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432.<\/p>\n<p><strong>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u00a0<\/strong><code><strong>helm-values.yaml<\/strong><\/code><strong>:<\/strong><\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c ConfigMap \u0441 blocklist \u0438 (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e) Secret \u0441 allowlist:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt;  blocklist.json{  \"version\": 1,  \"rules\": [    {      \"registry\": \"npm\",      \"name\": \"event-stream\",      \"version\": \"3.3.6\",      \"reason\": \"CVE-2018-16396 \u2014 malicious flatmap-stream dependency\"    },    {      \"registry\": \"*\",      \"name\": \"log4j*\",      \"version\": \"2.*\",      \"reason\": \"CVE-2021-44228 \u2014 Log4Shell RCE\"    }  ]}EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c ConfigMap \u0434\u043b\u044f blocklist:<\/p>\n<pre><code>kubectl create configmap nora-blocklist \\  --from-file=blocklist.json=blocklist.json<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u00a0<code>allowlist.json<\/code>:<\/p>\n<pre><code>cat &lt;&lt;EOF &gt;  allowlist.json{  \"version\": 1,  \"mode\": \"default-deny\",  \"rules\": [    {      \"registry\": \"npm\",      \"name\": \"lodash\",      \"version\": \"4.17.21\",      \"sha256\": \"e3c89c3d2e05c3e0f0b7c1c3e1d2a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1\"    },    {      \"registry\": \"pypi\",      \"name\": \"flask\",      \"version\": \"3.*\"    }  ]}EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0435\u00a0<code>mode<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>default-deny<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0451 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u044b\u00a0<strong>\u0442\u043e\u043b\u044c\u043a\u043e<\/strong>\u00a0\u043f\u0430\u043a\u0435\u0442\u044b \u0438\u0437\u00a0<code>rules<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>default-allow<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0451 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e, \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043a\u0435\u0442\u044b \u0438\u0437\u00a0<code>rules<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u043e\u043b\u0435\u00a0<code>sha256<\/code>\u00a0(\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e) \u2014 \u043f\u0438\u043d\u043d\u0438\u043d\u0433 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438: \u043f\u0430\u043a\u0435\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0445\u0435\u0448 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c ConfigMap \u0434\u043b\u044f allowlist (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e):<\/p>\n<pre><code>kubectl create configmap nora-allowlist \\  --from-file=allowlist.json=allowlist.json<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Helm-\u0447\u0430\u0440\u0442 (\u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 0.4.0) \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c\u00a0<code>existingConfigMap<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>existingSecret<\/code>:<\/p>\n<pre><code>config:  curation:    mode: \"enforce\"    blocklist:      existingConfigMap: nora-blocklist      # key: blocklist.json          # \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e; \u0444\u0430\u0439\u043b \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 &lt;mountPath&gt;\/&lt;key&gt;      # mountPath: \/etc\/nora         # \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e    allowlist:      existingConfigMap: nora-allowlist<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Chart \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0451\u0442 volume \u0438 volumeMount, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u00a0<code>curation.blocklist_path<\/code>\u00a0\/\u00a0<code>curation.allowlist_path<\/code>\u00a0\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 NORA. \u041d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0430\u0442\u0447\u0438\u0442\u044c Deployment \u2014 \u043d\u0438\u00a0<code>kubectl patch<\/code>, \u043d\u0438\u00a0<code>kubectl cp<\/code>\u00a0\u043d\u0435 \u043d\u0443\u0436\u043d\u044b.<\/p>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 glob-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b (<code>*<\/code>,\u00a0<code>foo*<\/code>,\u00a0<code><em>foo<\/em><\/code><em>,\u00a0<\/em><code><em>foo.<\/em>*<\/code>\u00a0\u0434\u043b\u044f Maven groupId,\u00a0<code>foo\/**<\/code>\u00a0\u0434\u043b\u044f Go \u043c\u043e\u0434\u0443\u043b\u0435\u0439) \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 15 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c\u0438 \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432.<\/p>\n<p>\u0412 \u0440\u0435\u0436\u0438\u043c\u0435\u00a0<code>audit<\/code>\u00a0\u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0442\u0441\u044f, \u043d\u043e \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u2014 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f dry-run \u043f\u0435\u0440\u0435\u0434 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0432 production.<\/p>\n<h4>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0440\u043e\u0432\u043d\u0438 \u0437\u0430\u0449\u0438\u0442\u044b<\/h4>\n<ul>\n<li>\n<p><strong>Allowlist<\/strong>\u00a0\u2014 \u0440\u0435\u0436\u0438\u043c default-deny: \u0442\u043e\u043b\u044c\u043a\u043e \u044f\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435\u00a0<code>(registry, name, version)<\/code>\u00a0\u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442, \u0441 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c SHA-256 \u043f\u0438\u043d\u043d\u0438\u043d\u0433\u043e\u043c \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0437\u043e\u043b\u044f\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0438\u043c\u0451\u043d<\/strong>\u00a0\u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430, \u0434\u0430\u0436\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435\u00a0<code>off<\/code>. \u041f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 dependency confusion \u2014 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0438\u043c\u0435\u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 upstream \u0440\u0435\u0435\u0441\u0442\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438<\/strong>\u00a0\u2014 SHA-256\/SHA-512 checksums \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435, compile-time typestate \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0431\u0430\u0439\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>Bypass token<\/strong>\u00a0\u2014 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a\u00a0<code>X-Nora-Bypass-Token<\/code>\u00a0\u0441 constant-time \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u044d\u043a\u0441\u0442\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0430 curation.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435 \u044d\u0442\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, TOML-\u043a\u043e\u043d\u0444\u0438\u0433 \u0438\u043b\u0438 YAML \u0432 Helm values, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e\u0432\u0435\u0440\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 proxy\/cache \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b NORA \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>helm-values.yaml.tpl<\/code>\u00a0\u0441 \u0432\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u043e\u0439 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 supply chain \u0430\u0442\u0430\u043a (\u0434\u043e\u043c\u0435\u043d \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442 Terraform):<\/p>\n<pre><code>ingress:  enabled: true  className: traefik  hosts:    - host: ${fqdn}      paths:        - path: \/          pathType: Prefix  annotations:    cert-manager.io\/cluster-issuer: letsencrypt-prod  tls:    - secretName: nora-tls      hosts:        - ${fqdn}persistence:  enabled: falseconfig:  server:    public_url: \"https:\/\/${fqdn}\"  storage:    mode: s3    path: \/data\/storage    s3_url: https:\/\/storage.yandexcloud.net    bucket: nora-storage-anton-patsev    s3_region: ru-central1  registries:    enable: \"all\"  curation:    mode: \"enforce\"    min_release_age: \"7d\"    blocklist:      existingConfigMap: nora-blocklist    allowlist:      existingConfigMap: nora-allowlist    npm:      min_release_age: \"3d\"    pypi:      min_release_age: \"5d\"  auth:    enabled: true    # \u041d\u0443\u0436\u043d\u043e \u0434\u043b\u044f Terraform network_mirror: \u043a\u043b\u0438\u0435\u043d\u0442 Terraform \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442    # \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a Authorization, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c    # \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435. \u0417\u0430\u043f\u0438\u0441\u044c (push) \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.    anonymous_read: true    htpasswd:      existingSecret: nora-htpasswd      secretKey: users.htpasswdextraEnv:  - name: NORA_STORAGE_S3_ACCESS_KEY    valueFrom:      secretKeyRef:        name: nora-s3-credentials        key: S3_ACCESS_KEY  - name: NORA_STORAGE_S3_SECRET_KEY    valueFrom:      secretKeyRef:        name: nora-s3-credentials        key: S3_SECRET_KEYresources:  limits:    memory: 512Mi    cpu: \"1\"  requests:    memory: 128Mi    cpu: \"0.25\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>Air-gapped: \u0440\u0430\u0431\u043e\u0442\u0430 \u0432 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u0430\u0445<\/h3>\n<p>NORA \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443\u00a0<code>nora mirror<\/code>\u00a0\u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u042d\u0442\u043e \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u0441\u0440\u0435\u0434 \u0431\u0435\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442.<\/p>\n<h4>\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e lockfile<\/h4>\n<pre><code># npm \u2014 \u043f\u043e package-lock.jsonnora mirror npm --lockfile package-lock.json \\  --registry https:\/\/$NORA_FQDN# pip \u2014 \u043f\u043e requirements.txtnora mirror pip --requirement requirements.txt \\  --registry https:\/\/$NORA_FQDN# Cargo \u2014 \u043f\u043e Cargo.locknora mirror cargo --lockfile Cargo.lock \\  --registry https:\/\/$NORA_FQDN# Maven \u2014 \u043f\u043e pom.xmlnora mirror maven --pom pom.xml \\  --registry https:\/\/$NORA_FQDN<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 Docker-\u043e\u0431\u0440\u0430\u0437\u043e\u0432<\/h4>\n<pre><code>nora mirror docker \\  --images \"nginx:latest,redis:7,node:20-alpine,python:3.12\" \\  --registry https:\/\/$NORA_FQDN<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0420\u0430\u0431\u043e\u0442\u0430 \u0432 air-gapped \u0441\u0440\u0435\u0434\u0435<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0435\u0440\u043a\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f NORA \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e \u2014 \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u0434\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0430, \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u043c \u043d\u0435\u0442.<\/p>\n<h3>\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433<\/h3>\n<p>NORA \u043e\u0442\u0434\u0430\u0451\u0442 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 Prometheus \u043f\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0443\u00a0<code>\/metrics<\/code>.<\/p>\n<h4>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u044f<\/h4>\n<pre><code># \u041e\u0431\u0449\u0438\u0439 health checkcurl https:\/\/$NORA_FQDN\/health# Readiness probecurl https:\/\/$NORA_FQDN\/ready<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Prometheus<\/h4>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 NORA \u0432\u00a0<code>prometheus.yml<\/code>:<\/p>\n<pre><code>scrape_configs:  - job_name: 'nora'    scrape_interval: 15s    static_configs:      - targets: ['$NORA_FQDN:443']    scheme: https    metrics_path: \/metrics<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Grafana<\/h4>\n<p>NORA \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u0440\u0438\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><code>nora_requests_total<\/code>\u00a0\u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u043c<\/p>\n<\/li>\n<li>\n<p><code>nora_request_duration_seconds<\/code>\u00a0\u2014 latency<\/p>\n<\/li>\n<li>\n<p><code>nora_storage_bytes<\/code>\u00a0\u2014 \u043e\u0431\u044a\u0451\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430<\/p>\n<\/li>\n<li>\n<p><code>nora_artifacts_total<\/code>\u00a0\u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<h4>\u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">URL<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/ui\/<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Web UI (dashboard, \u043f\u043e\u0438\u0441\u043a, \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/health<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/ready<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Readiness probe<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/metrics<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u0435\u0442\u0440\u0438\u043a\u0438 Prometheus<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>\/api-docs<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Swagger\/OpenAPI<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>\u0411\u044d\u043a\u0430\u043f \u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435<\/h3>\n<p>NORA \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 S3-\u0431\u0430\u043a\u0435\u0442\u0435 (Yandex Object Storage). \u0411\u044d\u043a\u0430\u043f \u2014 \u044d\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0431\u0430\u043a\u0435\u0442\u0430.<\/p>\n<h4>\u0427\u0435\u0440\u0435\u0437 CLI NORA<\/h4>\n<pre><code># \u0411\u044d\u043a\u0430\u043fnora backup --output \/data\/nora-backup.tar.gz# \u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435nora restore --input \/data\/nora-backup.tar.gz<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0427\u0435\u0440\u0435\u0437 S3 lifecycle \/ \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h4>\n<p>Yandex Object Storage \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 lifecycle-\u043f\u0440\u0430\u0432\u0438\u043b\u0430. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0431\u0430\u043a\u0435\u0442\u0435\u00a0<code>nora-storage-anton-patsev<\/code>\u00a0\u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f:<\/p>\n<pre><code>yc storage bucket update nora-storage-anton-patsev --versioning enabled<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0427\u0435\u0440\u0435\u0437 yc CLI (\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0430\u043a\u0435\u0442\u0430)<\/h4>\n<pre><code># \u0411\u044d\u043a\u0430\u043f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0431\u0430\u043a\u0435\u0442yc storage s3 cp s3:\/\/nora-storage-anton-patsev s3:\/\/nora-backup-$(date +%Y%m%d) --recursive<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>NORA \u2014 \u044d\u0442\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 Nexus, Artifactory \u0438 Harbor \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d enterprise-overhead. \u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430:<\/p>\n<ul>\n<li>\n<p><strong>\u041f\u0440\u043e\u0441\u0442\u043e\u0442\u0430<\/strong>\u00a0\u2014 \u043e\u0434\u0438\u043d \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a, \u043e\u0434\u0438\u043d \u043a\u043e\u043d\u0444\u0438\u0433, S3-\u0431\u0430\u043a\u0435\u0442. \u0414\u0430\u043d\u043d\u044b\u0435 \u0436\u0438\u0432\u0443\u0442 \u0432 Object Storage, stateless-\u043f\u043e\u0434\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/strong>\u00a0\u2014 &lt; 3 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430 \u0441\u0442\u0430\u0440\u0442, &lt; 50 \u041c\u0411 RAM. Rust, Tokio, Axum.<\/p>\n<\/li>\n<li>\n<p><strong>15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432<\/strong>\u00a0\u2014 Docker, Maven, npm, PyPI, Cargo, Go, Raw, RubyGems, Terraform, Ansible, NuGet, Pub, Conan, RPM, Debian\/APT.<\/p>\n<\/li>\n<li>\n<p><strong>\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c<\/strong>\u00a0\u2014 OpenSSF Scorecard, \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0440\u0435\u043b\u0438\u0437\u044b, SBOM, 1200+ \u0442\u0435\u0441\u0442\u043e\u0432, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (min-release-age), CVE blocklist, digest quarantine, namespace isolation.<\/p>\n<\/li>\n<li>\n<p><strong>Air-gapped ready<\/strong>\u00a0\u2014 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 \u0437\u0435\u0440\u043a\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0440\u0435\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 Terraform-\u043a\u043e\u0434\u043e\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438:\u00a0<a href=\"https:\/\/github.com\/patsevanton\/nora-yandex-k8s-deploy\" rel=\"noopener noreferrer nofollow\">github.com\/patsevanton\/nora-yandex-k8s-deploy<\/a><\/p>\n<ul>\n<li>\n<p>GitHub:\u00a0<a href=\"https:\/\/github.com\/getnora-io\/nora\" rel=\"noopener noreferrer nofollow\">github.com\/getnora-io\/nora<\/a><\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f:\u00a0<a href=\"http:\/\/getnora.dev\" rel=\"noopener noreferrer nofollow\">getnora.dev<\/a><\/p>\n<\/li>\n<li>\n<p>Telegram:\u00a0<a href=\"https:\/\/t.me\/getnora\" rel=\"noopener noreferrer nofollow\">t.me\/getnora<\/a><\/p>\n<\/li>\n<li>\n<p>Artifact Hub:\u00a0<a href=\"https:\/\/artifacthub.io\/packages\/helm\/nora\/nora\" rel=\"noopener noreferrer nofollow\">artifacthub.io\/packages\/helm\/nora\/nora<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1074042\/\">https:\/\/habr.com\/ru\/articles\/1074042\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432: Docker-\u043e\u0431\u0440\u0430\u0437\u044b, npm-\u043f\u0430\u043a\u0435\u0442\u044b, Maven-\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b, Python wheels. \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u0432\u0430 \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0435\u0441\u0442\u0440\u044b (Docker Hub, npmjs.org, PyPI) \u0438\u043b\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c Nexus \/ Artifactory \/ Harbor. \u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0435\u0441\u0442\u0440\u044b \u043d\u0435\u043d\u0430\u0434\u0451\u0436\u043d\u044b \u0438\u0437-\u0437\u0430 rate limit \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a. \u0410 Nexus \u0438 Artifactory \u2014 \u044d\u0442\u043e \u0442\u044f\u0436\u0451\u043b\u0430\u044f Java-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430: JVM, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0421\u0423\u0411\u0414 (OrientDB\/PostgreSQL), 2\u20134 \u0413\u0411 RAM \u0443\u0436\u0435 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u043c\u0438\u043d\u0443\u0442 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442.NORA\u00a0\u2014 open-source \u0440\u0435\u0435\u0441\u0442\u0440 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u043d\u0430 Rust, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u0430\u043a \u043f\u0440\u044f\u043c\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u044d\u0442\u0438\u043c \u0433\u0438\u0433\u0430\u043d\u0442\u0430\u043c. \u0412\u043c\u0435\u0441\u0442\u043e Java-\u0441\u0442\u0435\u043a\u0430 \u2014 \u043e\u0434\u0438\u043d \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a &lt; 27 \u041c\u0411. \u0412\u043c\u0435\u0441\u0442\u043e 2\u20134 \u0413\u0411 RAM \u2014 &lt; 50 \u041c\u0411 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u0442.\u0435. \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043c\u0435\u043d\u044c\u0448\u0435. \u0412\u043c\u0435\u0441\u0442\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043c\u0438\u043d\u0443\u0442 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442 \u2014 3 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0412\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435: \u043d\u0438 Java 11+, \u043d\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 \u2014 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0441\u0440\u0430\u0437\u0443 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 S3, \u0447\u0435\u0433\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 Nexus \u0438 Artifactory \u043d\u0435 \u0443\u043c\u0435\u044e\u0442. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432: Docker, Maven, npm, PyPI, Cargo, Go, Raw, RubyGems, Terraform, Ansible Galaxy, NuGet, Pub (Dart\/Flutter), Conan (C\/C++), RPM (yum\/dnf), Debian\/APT. \u041f\u043b\u044e\u0441 Helm-\u0447\u0430\u0440\u0442\u044b \u0447\u0435\u0440\u0435\u0437 OCI, \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (Min Release Age), \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 (CVE Blocking) \u0438 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u044f MIT.\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0451\u043c NORA \u0432 Kubernetes \u043d\u0430 Yandex Managed Kubernetes, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.NORA vs Nexus vs Artifactory vs Harbor\u0421\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435\/\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438: NORA (MIT), Nexus Repository OSS, Artifactory OSS \u0438 Harbor (Apache 2.0).\u041c\u0435\u0442\u0440\u0438\u043a\u0430NORANexusJFrog ArtifactoryHarborRAM (\u043f\u0440\u043e\u0441\u0442\u043e\u0439)&lt; 50 \u041c\u04112\u20134 \u0413\u04112\u20134 \u0413\u04112\u20134 \u0413\u0411\u0412\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430&lt; 3 \u0441\u0435\u043a30\u201360 \u0441\u0435\u043a30\u201360 \u0441\u0435\u043a30\u201360 \u0441\u0435\u043a\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u041d\u0435\u0442Java 11+Java 11+PostgreSQL, Redis\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445\u0424\u0430\u0439\u043b\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430OrientDB\/PostgreSQLOrientDB\/PostgreSQLPostgreSQL\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u04321530+30+Docker, OCI, Helm, CNABS3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u0414\u0430\u041d\u0435\u0442\u041d\u0435\u0442\u0414\u0430\u041b\u0438\u0446\u0435\u043d\u0437\u0438\u044fMITOSSOSSApache 2.0\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 (\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438)\u041e\u0434\u0438\u043d \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u043d\u0430 Rust, S3, \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e \u0432\u0435\u0440\u0441\u0438\u044f\u043chosted\/proxy\/group-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438Conan \u2014 \u0432 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u0438 CE \u0434\u043b\u044f C\/C++C\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 CVE image \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f trivy \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 imageNORA \u0443\u0441\u0442\u0443\u043f\u0430\u0435\u0442 Nexus\/Artifactory\/Harbor \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432. \u041d\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u043b\u0451\u0433\u043a\u0438\u0439 \u0438 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 registry \u0441 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c\u0438 \u2014 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440.\u041e\u0442\u043b\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c Nora \u044d\u0442\u043e:Min Release Age\u00a0\u2014 \u043a\u0430\u0440\u0430\u043d\u0442\u0438\u043d \u0441\u0432\u0435\u0436\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432CVE Blocking\u00a0\u2014 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e \u0432\u0435\u0440\u0441\u0438\u0438\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c ingress-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c, cert-manager, \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a S3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u0438 \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438\u0437 \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432, \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u043d\u044b\u0445 \u0433\u0435\u043e-\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Terraform Registry). \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043a \u0448\u0430\u0433\u0430\u043c 1\u20132 \u043d\u0438\u0436\u0435.\u0428\u0430\u0433 1. \u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e NORA \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u0435\u0437 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435). \u0414\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:\u0428\u0430\u0433 1. \u0421\u043e\u0437\u0434\u0430\u0451\u043c htpasswd-\u0444\u0430\u0439\u043bhtpasswd -Bbc users.htpasswd admin your-password# -B = bcrypt (\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f NORA), -b = \u043f\u0430\u0440\u043e\u043b\u044c \u0438\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, -c = \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u0428\u0430\u0433 2. \u0421\u043e\u0437\u0434\u0430\u0451\u043c Kubernetes Secretkubectl create secret generic nora-htpasswd \\  &#8212;from-file=users.htpasswd=.\/users.htpasswdNORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0438 \u0440\u043e\u043b\u0438:\u00a0read\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435),\u00a0write\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435 + \u0437\u0430\u043f\u0438\u0441\u044c),\u00a0admin\u00a0(\u0432\u0441\u0451 + \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438). \u0420\u043e\u043b\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u043a\u0435\u043d\u044b (\u0441\u043c. \u043d\u0438\u0436\u0435).\u0428\u0430\u0433 3. \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c Kubernetes Secret \u0434\u043b\u044f S3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430\u041d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c S3-\u0431\u0430\u043a\u0435\u0442 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u00a0secret_for_bucket.yaml. \u0424\u0430\u0439\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:apiVersion: v1kind: Secretmetadata:  name: nora-s3-credentialstype: OpaquestringData:  S3_ACCESS_KEY: YCAJE&#8230;  S3_SECRET_KEY: YCNL9&#8230;\u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440:kubectl apply -f secret_for_bucket.yaml\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e Secret \u0441\u043e\u0437\u0434\u0430\u043dkubectl get secret nora-s3-credentials# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0439kubectl get secret nora-s3-credentials -o jsonpath='{.data.S3_ACCESS_KEY}&#8217; | base64 -d &amp;&amp; echokubectl get secret nora-s3-credentials -o jsonpath='{.data.S3_SECRET_KEY}&#8217; | base64 -d &amp;&amp; echo\u0428\u0430\u0433 2. \u0414\u0435\u043f\u043b\u043e\u0439 NORA \u0447\u0435\u0440\u0435\u0437 Helm\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Helm-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439helm repo add nora https:\/\/getnora-io.github.io\/helm-chartshelm repo update\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0447\u0430\u0440\u0442 \u0432\u0435\u0440\u0441\u0438\u0438\u00a00.4.4\u00a0(\u043e\u043d\u0430 \u0443\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0438\u0436\u0435 \u0447\u0435\u0440\u0435\u0437\u00a0&#8212;version 0.4.4) \u0441 \u043f\u0438\u043d\u043e\u043c \u043e\u0431\u0440\u0430\u0437\u0430\u00a0NORA v1.2.0\u00a0\u0447\u0435\u0440\u0435\u0437\u00a0image.tag\u00a0\u0432 values. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:helm search repo nora\/nora &#8212;versions\u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0439\u0434\u0435\u0442 \u0447\u0430\u0440\u0442\u00a00.4.5\u00a0(appVersion 1.2.0), \u043f\u0438\u043d\u00a0image.tag: &#171;1.2.0&#187;\u00a0\u0438\u0437\u00a0helm-values.yaml.tpl\u00a0\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u2014 \u0447\u0430\u0440\u0442 \u043d\u0430\u0447\u043d\u0451\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c appVersion \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.values-\u0444\u0430\u0439\u043b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435\u00a0helm-values.yaml:image:  # NORA v1.2.0; \u0447\u0430\u0440\u0442 0.4.4 \u0435\u0449\u0451 \u0438\u043c\u0435\u0435\u0442 appVersion 1.1.0, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0438\u043d\u0438\u043c \u0442\u0435\u0433 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.  # \u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0439\u0434\u0435\u0442 \u0447\u0430\u0440\u0442 0.4.5 (appVersion 1.2.0), \u0441\u0442\u0440\u043e\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c.  tag: &#171;1.2.0&#187;ingress:  enabled: true  className: traefik  hosts:    &#8212; host: ${fqdn}      paths:        &#8212; path: \/          pathType: Prefix  annotations:    cert-manager.io\/cluster-issuer: letsencrypt-prod  tls:    &#8212; secretName: nora-tls      hosts:        &#8212; ${fqdn}# \u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f S3, \u0442\u043e \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0438\u0441\u043a.persistence:  enabled: falseconfig:  server:    public_url: &#171;https:\/\/${fqdn}&#187;  storage:    mode: s3    path: \/data\/storage    s3_url: https:\/\/storage.yandexcloud.net    bucket: nora-storage-anton-patsev    s3_region: ru-central1  registries:    enable: &#171;all&#187;  auth:    enabled: true    anonymous_read: true # \u0414\u043b\u044f terraform    htpasswd:      existingSecret: nora-htpasswd      secretKey: users.htpasswdextraEnv:  &#8212; name: NORA_STORAGE_S3_ACCESS_KEY    valueFrom:      secretKeyRef:        name: nora-s3-credentials        key: S3_ACCESS_KEY  &#8212; name: NORA_STORAGE_S3_SECRET_KEY    valueFrom:      secretKeyRef:        name: nora-s3-credentials        key: S3_SECRET_KEYresources:  limits:    memory: 512Mi    cpu: &#171;1&#187;  requests:    memory: 128Mi    cpu: &#171;0.25&#187;\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043chelm upgrade &#8212;install nora nora\/nora &#8212;version 0.4.4 -f helm-values.yaml\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c# \u0416\u0434\u0451\u043c \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434\u0430kubectl wait &#8212;for=condition=ready pod -l app.kubernetes.io\/name=nora &#8212;timeout=120s# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c healthcurl https:\/\/$NORA_FQDN\/health# \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c Web UIopen https:\/\/$NORA_FQDN\/ui\/\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e NORA \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443\u00a0https:\/\/$NORA_FQDN. Web UI \u043f\u043e\u043a\u0430\u0436\u0435\u0442 dashboard \u0441 15 \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u043c\u0438.NORA Dashboard\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u0432NORA \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 API-\u0442\u043e\u043a\u0435\u043d\u044b \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c\u00a0nra_\u00a0\u0432\u043c\u0435\u0441\u0442\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430\u00a0\/auth\/token\u00a0(\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0441\u0442\u044c \u0432 Docker Hub \/ GHCR, \u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 NORA).NORA \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0438 \u0440\u043e\u043b\u0438:\u00a0read\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435),\u00a0write\u00a0(\u0447\u0442\u0435\u043d\u0438\u0435 + \u0437\u0430\u043f\u0438\u0441\u044c),\u00a0admin\u00a0(\u0432\u0441\u0451 + \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438).# \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043dcurl -X POST https:\/\/$NORA_FQDN\/api\/tokens \\  -H &#171;Content-Type: application\/json&#187; \\  -d &#8216;{    &#171;username&#187;: &#171;admin&#187;,    &#171;password&#187;: &#171;your-password&#187;,    &#171;role&#187;: &#171;write&#187;,    &#171;ttl_days&#187;: 90,    &#171;description&#187;: &#171;CI\/CD pipeline token&#187;  }&#8217;# {&#171;token&#187;: &#171;nra_13ef0a4c309d4750907648409f57a65c&#8230;&#187;, &#171;expires_in_days&#187;: 90}# \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u0430curl -H &#171;Authorization: Bearer nra_13ef0a4c309d4750907648409f57a65c&#187; \\  https:\/\/$NORA_FQDN\/v2\/_catalog\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435: \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430NORA v1.2.0 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432, \u043d\u043e \u043d\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f (push\/publish). \u0427\u0430\u0441\u0442\u044c \u0440\u0435\u0435\u0441\u0442\u0440\u043e\u0432 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u2014\u00a0proxy\/cache\u00a0(\u0437\u0435\u0440\u043a\u0430\u043b\u043e \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 \u0441 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c). \u0421\u0432\u043e\u0434\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430:\u0424\u043e\u0440\u043c\u0430\u0442Pull (proxy\/cache)Push\/Publish\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435Docker \/ OCI\u2705\u2705hosted + proxyHelm OCI\u2705\u2705\u0447\u0435\u0440\u0435\u0437 Docker\/OCI endpointnpm\u2705\u2705hosted + proxyPyPI\u2705\u2705hosted + proxyMaven\u2705\u2705hosted + proxyCargo\u2705\u2705hosted + proxy (sparse index)Go\u2705\u2014\u0442\u043e\u043b\u044c\u043a\u043e proxy (\u043c\u043e\u0434\u0443\u043b\u0438 immutable, push \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u043c)Terraform\u2705\u2014\u0442\u043e\u043b\u044c\u043a\u043e proxy (\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430)Raw\u2705\u2705hosted only, \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 PUT (ETag\/If-Match \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 local-\u0431\u044d\u043a\u0435\u043d\u0434\u0435, \u0441\u043c. \u0440\u0430\u0437\u0434\u0435\u043b Raw)RPM\u2705\u2705hosted + proxy, \u0430\u0432\u0442\u043e-\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f repodataDebian\/APT\u2705\u2705hosted + proxy, \u0430\u0432\u0442\u043e-\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f Packages\/ReleaseRubyGems\u2705\u274c\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache\u00a0(gem push)NuGet\u2705\u274c\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache\u00a0(dotnet nuget push)Ansible Galaxy\u2705\u274c\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache\u00a0(ansible-galaxy collection publish)Pub (Dart)\u2705\u274c\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache\u00a0(dart pub publish)Conan\u2705\u274c\u0442\u043e\u043b\u044c\u043a\u043e proxy\/cache\u00a0(conan upload)\u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0445 \u274c \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 Push, \u0440\u0430\u0437\u0434\u0435\u043b\u044b \u043d\u0438\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 \u043e\u043d\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u0431\u0443\u0434\u0443\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b, \u043a\u043e\u0433\u0434\u0430 NORA \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b. \u0421\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a pull-through \u043a\u044d\u0448.\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432\u0418\u0437 15 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0442\u043e\u043b\u044c\u043a\u043e Raw \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430 \u2014 \u044d\u0442\u043e hosted-only \u0440\u0435\u0435\u0441\u0442\u0440 (\u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b). \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 14 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u0430\u043a\u00a0proxy\/cache: \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0442 \u043f\u0430\u043a\u0435\u0442\u044b\/\u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0430. \u0421\u0432\u043e\u0434\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (\u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u00a0proxies\u00a0\u0432\u00a0helm-values.yaml):\u0424\u043e\u0440\u043c\u0430\u0442\u041a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u0410\u043f\u0441\u0442\u0440\u0438\u043c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u0422\u0438\u043f \u043a\u044d\u0448\u0430\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435Docker \/ OCI\u2705registry-1.docker.ioimmutable blobs + TTL manifesthosted + proxy; \u043a\u044d\u0448 \u0432\u043a\u043b\u044e\u0447\u0451\u043d, \u043a\u043e\u0433\u0434\u0430\u00a0docker.upstreams\u00a0\u043d\u0435\u043f\u0443\u0441\u0442\u043e\u0439 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e Docker Hub)Helm OCI\u2705\u0447\u0435\u0440\u0435\u0437 Docker\/OCI endpoint\u2014hosted + proxy (\u0447\u0435\u0440\u0435\u0437 Docker endpoint)npm\u2705registry.npmjs.orgpackuments (TTL) + tarball (immutable)hosted + proxyPyPI\u2705pypi.org\/simple\/index (TTL) + \u0444\u0430\u0439\u043b\u044b (immutable)hosted + proxyMaven\u2705repo1.maven.org\/maven2metadata (TTL) + \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b (immutable)hosted + proxyCargo\u2705crates.io\u00a0(sparse index)index (TTL) + .crate (immutable)hosted + proxyGo\u2705proxy.golang.org@v\/list,@latest (TTL) + .info\/.mod\/.zip (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxyTerraform\u2705registry.terraform.iodiscovery (TTL) + \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxy; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u00a0anonymous_read: trueRubyGems\u2705rubygems.orgspecs\/latest_specs\/info (TTL) + gem\/gemspec (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxyNuGet\u2705api.nuget.orgregistration\/query (TTL) + .nupkg\/.nuspec (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxyAnsible Galaxy\u2705galaxy.ansible.comcollection list\/detail (TTL) + tarball (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxyPub (Dart)\u2705pub.devpackage metadata (TTL) + archive (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxyConan\u2705*center2.conan.iorevisions (TTL) + recipe\/package files (immutable)\u0442\u043e\u043b\u044c\u043a\u043e proxy; v2 API + v1\/ping (\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c Conan 2.x \u0441 NORA v1.2.0)RPM\u2705*\u2014 (\u043d\u0435\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)\u043f\u0430\u043a\u0435\u0442\u044b (immutable) + repodata (\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f)hosted; pull-through \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0447\u0435\u0440\u0435\u0437\u00a0config.registries.rpm.proxies\u00a0(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0fedora: https:\/\/download.fedoraproject.org\/&#8230;), \u043f\u043e&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-492052","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/492052","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=492052"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/492052\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=492052"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=492052"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=492052"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}