我们都在项目上工作,这让我们有机会构建可重用的组件。大多数时候,这些组件最终出现在项目的文件夹中。然后,此文件夹被复制粘贴到多个项目中,随着时间的推移,这成为更新的噩梦,因为我们不能轻易地拥有多个版本的组件,并且在多个分支上维护相同的代码库,因为版本是解决这个问题的一种棘手解决方案。shared

在这篇文章中,我们将看看Nexus存储库管理器(即Nexus),这是一个开源存储库管理器提供的Synatype。我们将讨论如何创建专用存储库(由 Amazon S3 支持),并将它与公共 NPM 注册表相结合,以提供一个全面的解决方案,使我们的私有存储库保持私有性、允许版本控制和缓存存储库。

接近尾声时,我们将创建两个应用程序,其中一个将被推送到 Nexus,另一个将从 Nexus 使用。在整篇文章中,我们将只处理本地部署的 Nexus。

评估需求

在我们进入细节之前,值得考虑需要像 Nexus 和 npmjs 提供的专用存储库(价格)。就我个人而言,我认为,如果您的组织没有任何云基础架构,在 npmjs 上托管的存储库是一个更简单、更简洁的解决方案。托管 Nexus、定期备份、运行状况检查都是开销(如果尚未内置于云基础结构中)。现在让我们假设,这一切都已经到位,并继续下去。

目录:

  1. 在本地运行 Nexus 存储库管理器
  2. 了解卷
  3. 创建 Blob
  4. 创建托管存储库
  5. 创建 NPM 代理和组
  6. 将二进制文件推送到连结
  7. 从 Nexus 中拉出二进制文件
  8. 结论

在本地运行 Nexus 存储库管理器

由于 Docker 的日益普及,现在运行任何软件都像找到正确的(Docker)映像一样简单。幸运的是,Sonatype 为 Nexus 提供了 Docker 映像,可以使用以下拉取命令轻松地在本地提取该映像。

docker pull sonatype/nexus

拔出图像后。要运行,只需执行以下命令:

docker run –rm -it -p 8081:8081/tcp sonatype/nexus3:latest

这将启动运行我们 Nexus 实例的容器。要试用,请打开浏览器,并且,默认凭据为http://localhost:8081``````admin/admin123

Image for post

Image for post

Nexus 中有很多不同的功能。此时,我们将仅处理为 NPM 设置专用存储库所需的资源,但这些概念也可以轻松地应用于其他形式的项目(maven、NuGet、Docker 等)。

基本概念

Nexus 公开存储库,它是我们的存储库(即 Nexus 术语中的存储库)和公共 NPM 注册表的组合。group``````private``````hosted``````proxy

代理到公共注册表是必要的,因为我们仍然需要一种从 NPM 注册表访问所有公开可用的存储库的方法。每当我们使用这些公共包时,它们都会缓存在代理中,我们将在文章末尾看到这些代理。

因此,当我们想要安装新的私有或公共 NPM 包时,我们将项目注册表指向 (使用 ),以便它可以安装任何必要的包(使用 或 )。并且,若要创建或更新现有存储库,请将发布操作指向存储库(使用 中的选项)。group``````.npmrc``````npm``````yarn``````hosted``````publishConfig``````package.json

这就是为什么我们看到一组默认的组/托管/代理存储库组合为我们创建时,我们首次加载 Nexus。

组 = 托管 = 代理。从组读取并写入托管存储库

Image for post

Image for post

用户管理

引导 Nexus 时,将为我们(以及所有使用 Nexus 的用户)创建默认用户。因此,全世界几乎每个 Nexus 用户都知道默认用户名和密码是什么。这就是为什么我们应该删除/禁用默认用户,一旦我们创建一个新的管理员用户。默认情况下,我们只有两个角色,但我们始终可以创建更多角色(这是特权的组合),并根据需要将它们添加到用户。

Image for post

Image for post

尽管这不是强制性的,但强烈建议创建自定义角色,并且仅根据用户需要将其分配给用户。

Image for post

Image for post

接下来,让我们防止未经授权的用户访问我们的服务器,点击下并取消选中允许访问服务器的选项:Anonymous``````Security

Image for post

Image for post

现在,我们已创建了名为"新管理员"并阻止匿名用户访问我们的存储库,我们已准备好进入下一步。npmuser

了解卷

每当我们将 Docker 映像作为容器运行时,所附的所有信息都是无状态的,即如果我们的容器因任何原因重新启动,数据可能会丢失。例如,在我们的示例中,我们已经在 Nexus 中创建了一个管理员用户,如果我们重新启动容器,我们创建的用户在重新启动时将不可用,因为它是一个从头开始的全新的容器。

为了绕过此问题(以及其他类似的问题),Docker 允许将卷装载到它可以保存数据的容器。在重新启动的情况下,只要将新容器重新安装到与之前相同的卷,就可以保留信息。

首先,让我们创建一个目录,我们将在此示例中放置与此示例生成的所有关系数据。

mkdir nexus-data

这是我们将用作 Nexus 映像的临时卷的文件夹。现在,我们需要在发出容器的 run 命令时提供卷的路径:

docker run –rm -it -p 8081:8081 -v /Users/../../nexus-data:/nexus-data sonatype/nexus3

上面突出显示的部分是使所有差异,我们正在指定完整的路径到我们的目录,我们正在安装它到在 Nexus 容器中调用的默认数据目录。此处列出了其他属性和配置nexus-data``````nexus-data

运行列出的命令后,我们会看到在创建的文件夹下创建的不同文件夹。nexus-data

Image for post

Image for post

我们现在在 Nexus 中所做的任何和所有更改都会同步回此文件夹。如果您感到好奇,请再次创建 带角色,停止容器并重新启动它。新创建的用户将保留为预期。npmuser``````admin

创建 Blob

现在,我们已准备好创建 Blob 存储,这是一个逻辑分区,我们希望为不同的项目类型强制执行,即我们希望隔离 NPM 二进制文件和 maven 二进制文件,以避免任何冲突(名称或其他)。在内部,Nexus 只是为我们创建的每个 Blob 存储创建不同的文件夹。

要创建 Blob,请转到"设置"页 > 存储库 > Blob 存储 > 创建 Blob 存储

Image for post

Image for post

此 Blob 一旦创建,将在卷中如预期显示:

Image for post

Image for post

我们现在上传到该 Blob 的任何包都会保留在与其关联的文件夹下的卷中。

我们还将使用基于 AWS S3 的 Blob,这是 Nexus 提供的基于文件的 Blob 的替代方法。要配置基于 S3 的 Blob,只需从下拉列表中选择 S3 并填写所需信息即可。相同的示例如下所示:Type

Image for post

Image for post

这最终在 S3 存储桶中创建一些默认文件:

Image for post

Image for post

使用此 Blob 推送到存储库的任何和所有内容都将由 S3 更新和管理,但是,我们提供给 Nexus 的有关 S3 存储桶的配置仍保留在我们之前装载的卷上。这就是为什么确保我们有卷的定期备份很重要。

出于多种原因,我们希望减少对卷的依赖:

  1. 在生产群集中,我们必须继续备份与灾难恢复 (DR) 容器连接的卷。虽然这不能完全避免(因为我们需要持久化用户、自定义角色和其他有状态信息),但我们可以将备份减少为无法与云(如 S3)同步的备份。
  2. 备份到 S3 允许我们在 AWS S3 存储桶上添加其他规则,如果需要,可以将旧软件包移动到冷存储。

有了这个,我们就可以进入流程的下一阶段,创建存储库。

创建托管存储库

如前所述,托管存储库是我们为保存私有包而创建的私人存储库。使这些存储库具有私有性,是无法在没有 的情况下读取这些存储库的内容。我们将在文章末尾的一个示例中看到这一点。authToken

若要创建托管存储库,请转到"设置"页 > 存储库 > 存储库 > 创建存储库。

当我们单击创建存储库时,Nexus 非常亲切,可以向我们提供配方,这些配方定义了需要配置特定类型的存储库,在我们的案例中,我们只关心相关的配方。npm

Image for post

Image for post

让我们首先选择选项,因为这就是我们想要开始。它要求我们提供两件事情,托管存储库的名称和需要为该存储库保存数据的 Blob。单击"创建存储库"按钮完成存储库的创建。npm(hosted)

Image for post

Image for post

就是这个我们已为我们所有的项目创建了专用(托管)存储库。npm

创建 NPM 代理和组

现在,我们已设置了专用存储库,我们已准备好创建 npm 代理,该代理将我们所有的读取请求代理到公共 NPM 注册表。我们可以通过将 和 存储库合并为 来完成更改。hosted``````proxy``````group

创建代理存储库

在创建存储库屏幕中,选择哪个将我们带到配置页,我们希望代理到位于 URL 的 NPM 公共注册表npm (proxy)``````[https://registry.npmjs.org](https://zshipu.com/t?url=https://registry.npmjs.org.)

我们仅在此处输入 3 个必填字段:

  1. 名称 |npm-proxy
  2. 代理位置 |[https://registry.npmjs.org](https://zshipu.com/t?url=https://registry.npmjs.org.)
  3. Blob 存储(用于缓存存储、配置等) = (之前创建)NPM-S3

这将创建代理存储库。

Image for post

Image for post

创建组存储库

如前所述,创建组存储库是将托管存储库和代理存储库组合在一起,这样可以使读取更加容易。让我们创建类似于 和 的存储库。npm (group)``````hosted``````proxy

这接受与之前类似的配置,如名称、Blob 存储等。我们正在选择 和 存储库,并使其成为此组的活动成员。npm-private``````npm-proxy

将来,如果我们有更多的兼容存储库,它们将显示在列表下,可以选择这些存储库并移动到该部分。Available``````Members

Image for post

Image for post

将二进制文件推送到连结

现在,我们已经准备好必要的存储库了,现在我们可以根据需要在项目中使用这些存储库。让我们首先创建一个包含空白文件的示例 NodeJS 项目,然后推送到托管存储库:index.js

mkdir npm-app1 && cd npm-app1npm init -ytouch index.js

要发布此项目,我们需要更新文件,其中指向我们新的托管存储库。package.json``````publishConfig

如果我们现在尝试使用 命令发布项目,我们会看到以下错误,如预期的那样说我们需要身份验证:npm publish

Image for post

Image for post

让我们使用与 Nexus 仪表板相同的凭据添加身份验证(如错误消息中的建议):

注意: 请注意注册表 URL 包含存储库名称

Image for post

Image for post

让我们再试一次!现在我们看到一个不同的错误,说它不能发出请求:Put

Image for post

Image for post

这是因为安全性在 Nexus 中的工作方式,即确定任何用户如何与 Nexus 交互的概念。应用的默认值称为本地身份验证和本地授权,其职责根据文档如下:realms``````realm``````realm

它们允许存储库管理器在没有其他外部系统的情况下管理安全设置。

我们需要添加附加功能以启用功能。要启用其他领域,请转到"设置>安全>领域"。realms``````npm publish

添加 并保存更改。有关领域的其他信息可在此获得npm Bearer Token Realm

Image for post

Image for post

现在,我们准备重试发布命令,并可以正常使用:

Image for post

Image for post

为了验证,我们可以浏览我们的存储库,并按预期查看包。从顶部导航栏 > 浏览 > npm - 私人选择"浏览"选项,查看如下所示的套餐:

Image for post

Image for post

我们还可以验证要在 S3 中上载的文件夹称为 ,尽管它在存储时转换为 Blob 时无法清晰。content

从 Nexus 中拉出二进制文件

现在,我们已经发布了二进制到Nexus,让我们创建另一个项目,我们将尝试使用。npm-app1

mkdir npm-app2 && cd npm-app2npm init -y

在尝试从存储库中检索之前,让我们删除之前添加的凭据。我们这样做是为了避免使用这些凭据来检索包。理想情况下,我们希望复制使用我们应用程序的新开发人员的经验。npm install npm-app1``````npm login

要删除这些凭据,只需运行以下命令:

npm logout –registry=http://localhost:8081/repository/npm-private/

现在,让我们尝试从我们的新项目安装:npm-app1``````npm-app2

npm i -S npm-app1

不出所料,我们看到 404 错误,因为默认情况下在公共注册表上找不到该错误。npm-app1``````npm

Image for post

Image for post

要解决此问题,我们需要在本地向项目添加一个文件。此文件包含我们需要指向的提取包和所需的任何其他凭据。.npmrc``````.npmrc``````registry

touch .npmrc

我们首先添加注册表,我们需要指向该注册表,以便能够检索我们的包

registry=http://localhost:8081/repository/npm-group/

请注意,我们指向 的 不是 存储库,因为我们想要同时访问私有和近在近的公共包。我们可以看到,该项目位于,但不能安装,因为我们没有授权。npm-group``````npm-private``````npm

Image for post

Image for post

最简单的解决方案是添加使这项工作所需的。authToken

最佳做法是,我建议创建一个所有存储库都具有只读角色的新用户。我们这样做,因为不想将 Nexus 的管理员身份验证令牌添加到源代码中。

为此,创建具有与读取和浏览相关的所有权限的角色,最简单的方法是提供角色 和 特权nx-repository-view-*-*-browse``````nx-repository-view-*-*-read

Image for post

Image for post

然后创建具有以下角色的用户:

Image for post

Image for post

接下来,要获取此用户的身份验证令牌,请执行指向我们的存储库:npm login``````npm-group

Image for post

Image for post

执行登录将凭据添加到计算机根目录的文件。打开全局文件并找到类似于以下内容的行:.npmrc``````.npmrc

//localhost:8081/repository/npm-group/:_authToken=NpmToken.bb495270–9831–3046–8c24-a2978853d3a1

是上面打印的行的最后一位。现在,我们可以将 添加到项目中的文件。我们这样做是为了避免登录到克隆此存储库的每台计算机。_authToken``````_authToken``````.npmrc``````npm-app2

让我们在继续之前注销:

npm logout –registry=http://localhost:8081/repository/npm-group/

项目中文件的最终形式如下所示:.npmrc

有了这个,我们现在应该能够安装和使用任何和所有包,如下所示:

Image for post

Image for post

当我们浏览存储库时,我们可以看到代理包(本例中是 lodash)的缓存在行动:

Image for post

Image for post

结论

本文仅介绍如何使用 Nexus 作为存储库管理器的一些基础知识。尽管我们运行容器并将卷装载到本地目录,但强烈建议您在您选择的云提供商上试用上述内容。请记住,对于云提供商(或自托管),您需要备份卷以进行灾难恢复。