![](https://i-blog.csdnimg.cn/blog_migrate/56f7f8166ef4885a72f9c4c0cd5bca73.png)
我们都致力于项目,这使我们有机会构建可重复使用的组件。 大多数情况下,这些组件最终位于项目的共享文件夹中。 然后,将该文件夹复制粘贴到多个项目中,随着时间的流逝,这将成为更新的噩梦,因为我们无法轻松拥有组件的多个版本,并且在多个分支上维护相同的代码,因为版本是解决此问题的一种有力的解决方案。
在本文中,我们将介绍Nexus Repository Manager(又名Nexus),它是Sonatype提供的开源资源库管理器。 我们将讨论如何创建私有存储库(由Amazon S3支持)并将其与公共NPM注册表相结合,以提供一个完整的解决方案,该解决方案可以使我们的私有存储库保持私有,允许版本控制以及缓存存储库。
最后,我们将创建两个应用程序,其中一个将被推送到Nexus,另一个将被Nexus使用。 在整篇文章中,我们仅涉及本地部署的Nexus。
评估需求
在开始详细介绍之前,有必要考虑一下Nexus之类的需求与npmjs提供的私有存储库(价格)之间的关系。 我个人认为,如果您的组织没有适当的云基础架构,则托管在npmjs上的存储库是一种更轻松,更干净的解决方案。 托管Nexus,定期备份,运行状况检查(如果尚未构建到您的云基础架构中)都是开销。 现在让我们假设所有这些都已经到位并继续进行。
目录:
- 在本地运行Nexus Repository Manager
- 了解卷
- 创建一个斑点
- 创建托管存储库
- 创建NPM代理和组
- 将二进制文件推送到Nexus
- 从Nexus提取二进制文件
- 结论
在本地运行Nexus Repository Manager
得益于Docker的日益普及,如今运行任何软件都像找到正确的(docker)映像一样容易。 幸运的是,Sonatype提供了Nexus的docker镜像,可以使用以下pull命令轻松在本地将其镜像。
docker pull sonatype/nexus
一旦图像被拉出。 要运行,只需执行以下命令:
docker run --rm -it -p 8081:8081/tcp sonatype/nexus3:latest
这将启动运行我们的Nexus实例的容器。 要进行尝试,请在浏览器中打开http:// localhost:8081,默认凭据为admin / admin123。
![](https://i-blog.csdnimg.cn/blog_migrate/b6ad156d023a506a7fff240cdb4406cb.png)
Nexus有很多不同的功能。 目前,我们只会使用为NPM设置私有存储库所需的存储库,但是这些概念也可以轻松地应用于其他形式的项目(maven,NuGet,docker等)。
基本概念
Nexus公开了一组存储库,这些存储库在内部是我们的私有存储库(按Nexus术语又称为托管存储库)和公共NPM注册中心的代理的组合。
必须有公共注册表的代理,因为我们仍然需要一种从NPM注册表访问所有公共可用存储库的方法。 每当我们使用这些公共软件包时,它们都会被缓存在代理中,我们将在本文结尾处看到它们。
因此,当我们要安装新的私有或公共NPM软件包时,我们将项目注册表指向该组(使用.npmrc),以便它可以安装任何必需的软件包(使用npm或yarn)。 并且,要创建或更新现有存储库,请将发布操作指向托管存储库(使用package.json中的publishConfig选项)。
这就是为什么我们在首次加载Nexus时会看到为我们创建的一组默认的组/托管/代理存储库组合的原因。
组=托管+代理。 从组中读取并写入托管存储库
![](https://i-blog.csdnimg.cn/blog_migrate/73163a08a030922d8d2ce661898a42dc.png)
用户管理
引导Nexus时,会为我们(和所有使用Nexus的所有人)创建一个默认用户。 因此,全世界几乎所有的Nexus用户都知道默认的用户名和密码是什么。 这就是为什么一旦创建新的管理员用户,我们应该删除/禁用默认用户。 默认情况下,我们只有两个角色,但我们总是可以创建更多角色(这是特权的组合),并根据需要将它们添加到用户中。
![](https://i-blog.csdnimg.cn/blog_migrate/4a2085b72586de45285335d6d68ba267.png)
尽管这不是强制性的,但强烈建议创建自定义角色,并仅根据其需要将其分配给用户。
![](https://i-blog.csdnimg.cn/blog_migrate/83a40bd5d25293e148928d413465d81f.png)
接下来,让我们阻止未经授权的用户访问我们的服务器,单击“安全性”下的“匿名”,然后取消选中允许访问服务器的选项:
![](https://i-blog.csdnimg.cn/blog_migrate/98782480913e22380c438733343fae1d.png)
现在,我们已经创建了一个名为npmuser的新管理员,并阻止了匿名用户访问我们的存储库,我们已经准备好进行下一步。
了解卷
每当我们将Docker映像作为容器运行时,包含的所有信息都是无状态的,即,如果我们的容器由于某种原因重新启动,则数据可能会丢失。 例如,在我们的情况下,我们已经在Nexus中创建了一个管理员用户,如果我们要重新启动容器,则我们创建的用户在重新启动时将不可用,因为它是一个从头开始的全新容器。
为了绕开这个问题(以及其他类似问题),Docker允许我们将卷挂载到可以持久存储数据的容器中。 并且在重新启动的情况下,只要将新容器重新安装到与先前相同的卷上,它就可以保留信息。
首先,让我们创建一个目录,在该目录中,我们将放置有关此示例生成的所有关系数据。
mkdir nexus-data
这是我们将用于Nexus映像的临时卷的文件夹。 现在,在发出容器的运行命令时,我们需要提供卷的路径:
docker run --rm -it -p 8081:8081 -v /Users/../../nexus-data:/nexus-data sonatype/nexus3
上面突出显示的部分是使这一切有所不同的部分,我们指定了nexus-data目录的完整路径,并将其安装在Nexus容器内的默认数据目录nexus-data中。 其他属性和配置在此处列出。
运行列出的命令后,我们将在创建的nexus-data文件夹下看到创建的不同文件夹。
![](https://i-blog.csdnimg.cn/blog_migrate/06c55f906ab7ac8e01a44d0b670aab01.png)
现在,我们在Nexus中所做的所有更改都将同步回该文件夹。 如果您感到好奇,请再次以管理员角色创建npmuser,停止容器并重新启动它。 新创建的用户将按预期保留。
创建一个斑点
现在,我们准备创建一个Blob存储库,该存储库是我们要针对不同项目类型强制执行的逻辑分区,即,我们希望隔离NPM二进制文件和Maven二进制文件以避免任何冲突(名称冲突或其他冲突)。 在内部,Nexus只会为我们创建的每个Blob存储创建不同的文件夹。
要创建Blob,请转到“设置”页面>存储库> Blob存储>创建Blob存储
![](https://i-blog.csdnimg.cn/blog_migrate/20ee23b54a263321799fbd7eadd88fc1.png)
这个Blob一旦创建,就会按预期显示在我们的体积中:
![](https://i-blog.csdnimg.cn/blog_migrate/f81d59bf0cc6d68397e437e3fc7a212d.png)
我们现在上传到该Blob的任何软件包都将保留在与之关联的文件夹下的卷中。
我们还将使用基于AWS S3的Blob,它是Nexus提供的基于文件的Blob的替代方案。 要配置基于S3的Blob,只需从“类型”下拉列表中选择S3,然后填写所需的信息。 相同的示例如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/48b89a61733f19f30626bcc155b58743.png)
这最终在S3存储桶中创建了一些默认文件:
![](https://i-blog.csdnimg.cn/blog_migrate/3a08d138c25a0a343e7e7b6584c7ad5c.png)
使用此Blob推送到存储库的所有内容都将由S3更新和管理,但是,我们提供给Nexus的有关S3存储桶的配置仍保留在我们先前安装的卷上。 这就是为什么重要的是确保我们有定期的卷备份。
由于多个原因,我们希望减少对体积的依赖:
- 在生产集群中,我们必须继续备份容器附带的卷以进行灾难恢复(DR)。 尽管无法完全避免这种情况(因为我们需要保留用户,自定义角色和其他有状态信息),但我们可以将备份减少到无法与云同步的备份,例如S3。
- 备份到S3,使我们可以在AWS S3存储桶上添加其他规则,以便在需要时将旧程序包移动到冷存储中。
这样,我们就可以进入流程的下一个阶段,创建存储库。
创建托管存储库
如前所述,托管存储库是我们创建的用于存储私有包的私有存储库。 使这些存储库成为私有的原因在于,如果没有authToken,则无法读取这些存储库的内容。 我们将在本文结尾处的示例中看到这一点。
要创建托管存储库,请转到“设置”页面>存储库>存储库>创建存储库。
当我们单击“创建存储库”时,Nexus足以为我们提供配方,该配方定义了如何配置某种类型的存储库,在本例中,我们只关心与npm相关的配方。
![](https://i-blog.csdnimg.cn/blog_migrate/98d70b18001c902749b81c67667a6f8c.png)
让我们首先选择npm(hosted)选项,因为这是我们要开始的。 它要求我们提供两件事,即托管存储库的名称和该存储库中需要保留数据的Blob。 单击创建存储库按钮以完成存储库的创建。
![](https://i-blog.csdnimg.cn/blog_migrate/f920bb2798974dea3a06cf2e955d12db.png)
就是这样。 我们已经为所有npm项目创建了私有(托管)存储库。
创建NPM代理和组
现在我们已经建立了私有存储库,我们准备创建npm代理,它将所有读取请求代理到公共NPM注册表。 我们可以通过将托管存储库和代理存储库组合成一个组来完成更改。
创建代理存储库
在创建存储库屏幕中,选择npm(代理),这将使我们进入配置页面,我们要代理NPM公共注册表,该注册表位于URL https://registry.npmjs.org。
我们仅在此处输入3个必填字段:
- 名称-npm-proxy
- 代理位置-https: //registry.npmjs.org
- Blob存储(用于缓存存储,配置等)— NPM-S3(先前创建)
这将按预期创建代理存储库。
![](https://i-blog.csdnimg.cn/blog_migrate/3bf0ca5b20d7c27a4c98aad2c9cc8609.png)
创建组存储库
如前所述,创建组存储库是将托管存储库和代理存储库相结合,这使读取变得更加容易。 让我们创建类似于托管和代理存储库的npm(组)存储库。
它接受与之前类似的配置,例如名称,blob存储等。我们正在选择npm-private和npm-proxy存储库,并使它们成为该组的活跃成员。
将来,如果我们有更多兼容的存储库,它们将显示在“可用”列表下,可以选择该列表并将其移至“成员”部分。
![](https://i-blog.csdnimg.cn/blog_migrate/60ca44b211e7fd1c82ac02219b5bfc55.png)
将二进制文件推送到Nexus
现在我们已经准备好必要的存储库,现在可以根据需要在项目中使用这些存储库。 让我们首先创建一个带有空白index.js文件的示例NodeJS项目,并将其推送到我们的托管存储库中:
mkdir npm-app1 && cd npm-app1
npm init -y
touch index.js
要发布此项目,我们需要使用publishConfig来更新package.json文件,该文件指向我们新的托管存储库。
如果我们尝试使用npm publish命令立即发布项目,则会如预期的那样看到以下错误,表明我们需要身份验证:
![](https://i-blog.csdnimg.cn/blog_migrate/434dfb931de97b12864af4d8230cfb26.png)
让我们使用与Nexus信息板相同的凭据添加身份验证(如错误消息中所建议):
注意:请注意,注册表URL包含存储库名称
![](https://i-blog.csdnimg.cn/blog_migrate/ab376c0a4cf8d4ecbe187ee15eaf0d87.png)
让我们再试一次! 现在,我们看到了另一个错误,说它无法发出Put请求:
![](https://i-blog.csdnimg.cn/blog_migrate/0af37116e719000276392368c5fe5730.png)
发生这种情况的原因是Nexus中安全性的工作方式,领域的概念决定了任何用户如何与Nexus进行交互。 应用的默认领域称为本地身份验证和本地授权领域,其根据文档的职责如下:
它们使资源库管理器无需其他外部系统即可管理安全设置。
我们需要添加其他领域以启用npm publish功能。 要启用其他领域,请转至设置>安全性>领域。
添加npm Bearer Token Realm并保存更改。 有关领域的更多信息,请参见此处 。
![](https://i-blog.csdnimg.cn/blog_migrate/560c038a42f9def45020d01c13414f6a.png)
现在,我们准备重试发布命令,该命令可以按预期工作:
![](https://i-blog.csdnimg.cn/blog_migrate/8f0952334ebc634371d7ed9945d846cb.png)
为了进行验证,我们可以浏览存储库并按预期方式查看该软件包。 从顶部导航栏>浏览> npm-private中选择浏览选项,以查看软件包,如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/8f3e59834c1d1600892913eab09081ca.png)
我们也可以验证此文件是否已在S3中上传到名为content的文件夹下,尽管它在存储时会转换为Blob,但对我们而言却不清晰。
从Nexus提取二进制文件
现在,我们已将二进制文件发布到Nexus,让我们创建另一个项目,我们将尝试从中使用npm-app1。
mkdir npm-app2 && cd npm-app2
npm init -y
在尝试进行npm安装以从我们的存储库中检索npm-app1之前,让我们删除之前执行npm登录时添加的凭据。 我们这样做是为了避免使用这些凭据来检索软件包。 理想情况下,我们希望复制正在使用我们的应用程序的新开发人员的经验。
要删除这些凭据,只需运行以下命令:
npm logout --registry= http://localhost:8081/repository/npm-private/
现在,让我们尝试从新的npm-app2项目中安装npm-app1:
npm i -S npm-app1
正如预期的那样,我们看到一个404错误,因为在公共注册表中未找到npm-app1,默认情况下npm指向该目录。
![](https://i-blog.csdnimg.cn/blog_migrate/45c169f569a388d430cd1bbe6235a361.png)
要解决此问题,我们需要在项目本地添加一个.npmrc文件。 该.npmrc文件包含我们需要指向以提取软件包的注册表以及任何其他所需的凭据。
touch .npmrc
我们首先添加需要指向的注册表才能检索包
registry= http://localhost:8081/repository/npm-group /
注意,我们要指向npm-group而不是npm-private存储库,因为我们要访问私有和代理npm公共包。 我们可以看到该项目已找到,但由于未经授权,无法安装。
![](https://i-blog.csdnimg.cn/blog_migrate/b45454e4c350de5e204e1cbffd7e9ba2.png)
最简单的解决方案是添加完成此工作所需的authToken。
作为最佳实践,我建议创建一个对所有存储库具有只读角色的新用户。 我们这样做是因为我们不想将Nexus的管理员身份验证令牌添加到源代码中。
为此,使用与读取和浏览相关的所有特权来创建角色,最简单的方法是为该角色提供nx-repository-view-*-*-browse和nx-repository-view-*-*-读取权限
![](https://i-blog.csdnimg.cn/blog_migrate/b316739ec7586f7c95b8257f421608b7.png)
然后创建具有此角色的用户:
![](https://i-blog.csdnimg.cn/blog_migrate/563bf8b0739d32f228154dd2210805c7.png)
接下来,要获取该用户的身份验证令牌,请执行指向我们的npm-group存储库的npm登录:
![](https://i-blog.csdnimg.cn/blog_migrate/a379243e7b9c46ab38e0b9d4de4a4b1e.png)
执行登录将凭据添加到计算机根目录的.npmrc文件中。 打开全局.npmrc文件,然后找到类似于以下内容的行:
//localhost:8081/repository/npm-group/:_authToken=NpmToken.bb495270–9831–3046–8c24-a2978853d3a1
_authToken是上面打印的行的最后一位。 现在,我们可以将_authToken添加到npm-app2项目中的.npmrc文件中。 我们这样做是为了避免必须在克隆此存储库的每台计算机上登录。
让我们先退出,然后再继续:
npm logout --registry= http://localhost:8081/repository/npm-group/
项目中.npmrc文件的最终形式如下:
这样,我们现在应该能够安装和使用任何软件包,如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/a9839cb55bbeb7ca84ff36782db804e2.png)
当我们浏览存储库时,我们可以看到对代理程序包的缓存(在本例中为破折号):
![](https://i-blog.csdnimg.cn/blog_migrate/5b9a90f1e46ef7a5a099cc6191502722.png)
结论
本文仅介绍有关如何将Nexus用作存储库管理器的一些基础知识。 尽管我们运行容器并将卷安装到本地目录,但强烈建议您在所选的云提供商上尝试上述操作。 请记住,对于云提供商(或自托管),您将需要备份该卷以进行灾难恢复。
如果您喜欢这个博客,请务必给它鼓掌, 阅读更多内容 或在 LinkedIn 上关注我 。
![](https://i-blog.csdnimg.cn/blog_migrate/b0d6f63ec05bbde13549dff50a873b77.png)
From: https://hackernoon.com/deploying-private-npm-packages-to-nexus-a16722cc8166