CentOS 7/8 部署 Nexus 3 私有制品仓库:从安装到生产级运维
1. 为什么需要一个私有的制品仓库如果你是一名后端或运维工程师每天的工作离不开mvn clean install或者docker pull那你肯定对“下载依赖”这件事又爱又恨。爱的是它能快速引入成熟的轮子恨的是网络波动、公共仓库限速、甚至某个Jar包突然从中央仓库消失都能让整个构建流程瞬间卡壳。更别提在团队协作中大家重复下载相同的依赖既浪费带宽也拖慢了CI/CD流水线的速度。这时候一个部署在公司内网的私有制品仓库就显得至关重要。它就像在你家门口建了一个“超市分仓”所有常用的“商品”如Java的jar包、Node.js的npm包、Docker镜像、Python的whl包等都缓存一份在本地。第一次有人需要时从远程仓库拉取并缓存下来之后团队里任何人再需要都直接从本地“分仓”高速获取。这带来的好处是立竿见影的构建速度成倍提升、网络依赖降到最低、对第三方服务的稳定性要求降低并且还能统一管理内部开发的组件实现安全审计和版本控制。Sonatype Nexus Repository Manager通常简称Nexus正是这个领域里的“老大哥”。它不仅仅是一个简单的缓存代理更是一个全功能的制品管理平台支持Maven、npm、Docker、PyPI、NuGet等几十种仓库格式。对于使用CentOS这类稳定、常见的服务器操作系统的团队来说在CentOS上部署Nexus是搭建企业级DevOps基础架构非常标准且关键的一步。虽然网上教程很多但我在多次部署和运维中发现了一些关乎长期稳定运行的细节比如服务管理、磁盘规划、初始安全配置等这些往往是新手容易踩坑的地方。接下来我就结合最新版的Nexus 3手把手带你走一遍在CentOS 7/8上的完整安装、配置与优化流程。2. 部署前的核心准备环境与资源规划在直接执行安装命令之前合理的规划能避免后续很多麻烦。很多人安装后才发现磁盘空间不足或者因为Java版本问题导致服务无法启动这都是前期准备不充分导致的。2.1 系统与硬件要求首先确认你的CentOS系统版本。Nexus 3支持CentOS 7及更高版本。我个人推荐使用CentOS 7.9这是一个经过长期验证的、非常稳定的版本。你可以通过cat /etc/redhat-release命令查看。硬件方面对于中小型团队日均构建次数在几百次以内以下配置可以作为起点CPU: 2核或以上。Nexus本身对CPU要求不高但如果有大量的制品扫描或清理任务多核会有帮助。内存: 至少4GB推荐8GB。JVM堆内存的大小直接影响了Nexus的性能特别是处理大量并发请求时。内存不足是导致Nexus响应缓慢甚至OOM崩溃的主要原因。磁盘:这是最需要重点规划的部分。Nexus的仓库数据、索引、日志等都会存储在磁盘上。一个活跃的仓库其数据增长是持续的。系统盘至少40GB用于安装操作系统、Nexus软件本身和JRE。数据盘强烈建议单独挂载一块大容量磁盘专门用于存放Nexus的数据目录sonatype-work。这个目录会存放所有缓存的制品、索引、数据库文件。根据你缓存仓库的数量和类型初期建议预留200GB以上。如果团队使用Docker镜像较多那么1TB甚至更大都可能很快被填满。你可以使用df -h命令查看现有磁盘布局。注意务必区分df和du命令。有时你会遇到df显示磁盘空间快满了但du -sh统计目录大小却差很多的情况。这通常是因为文件被删除后其空间并未被立即释放例如被某个未退出的进程占用。在规划时以df的可用空间为准。2.2 Java环境安装与验证Nexus 3是一个Java应用运行需要Java 8或Java 11。官方推荐使用Oracle JRE 8或OpenJDK 8。在CentOS上我们通常使用OpenJDK因为它开源且易于管理。安装OpenJDK 11目前更主流且支持更久# 对于CentOS 7/8使用yum或dnf安装 sudo yum install -y java-11-openjdk-devel如果你想安装OpenJDK 8命令是sudo yum install -y java-1.8.0-openjdk-devel。验证安装java -version你应该看到类似openjdk version 11.0.xx的输出。确认版本符合要求。设置JAVA_HOME环境变量虽然不是Nexus启动的必须项但有益无害# 查找Java安装路径 sudo alternatives --config java # 通常会输出类似 /usr/lib/jvm/java-11-openjdk-11.0.xx.x86_64/bin/java # 那么JAVA_HOME就是 /usr/lib/jvm/java-11-openjdk-11.0.xx.x86_64 # 将其添加到全局环境变量例如编辑 /etc/profile echo export JAVA_HOME/usr/lib/jvm/java-11-openjdk-11.0.xx.x86_64 | sudo tee -a /etc/profile echo export PATH$JAVA_HOME/bin:$PATH | sudo tee -a /etc/profile source /etc/profile2.3 创建专用系统用户为了安全我们不建议使用root用户直接运行Nexus。创建一个专用的、无登录权限的系统用户来运行它。sudo groupadd nexus sudo useradd -g nexus -s /bin/false -M nexus-g nexus: 指定主组为nexus。-s /bin/false: 禁止该用户登录shell。-M: 不创建家目录。3. 分步详解Nexus的安装与初始启动完成准备工作后我们进入正式的安装环节。3.1 下载并解压Nexus软件包访问Sonatype官网获取下载链接。你可以直接使用wget命令下载。这里以目前最新的Nexus 3.xx.x版本为例请替换为官网最新版本号。# 切换到临时目录比如 /tmp cd /tmp # 下载Nexus压缩包示例链接请以官网为准 wget https://download.sonatype.com/nexus/3/nexus-3.xx.x-xx-unix.tar.gz如果下载速度慢可以尝试在本地下载后通过SCP工具如WinSCP上传到服务器。规划安装目录。我习惯将软件放在/opt目录下。sudo mkdir -p /opt/nexus sudo tar -zxvf nexus-3.xx.x-xx-unix.tar.gz -C /opt/nexus --strip-components1--strip-components1参数会解压后去掉压缩包根目录的那一层直接将nexus-3.xx.x-xx目录内的内容放到/opt/nexus下。此时/opt/nexus目录下会有两个关键子目录nexus-3.xx.x-xx/: 这是Nexus运行程序本身。sonatype-work/:这是数据目录所有仓库数据、配置、日志都存放在这里。我们后续需要将其指向我们规划的大容量数据盘。3.2 关键配置调整内存、数据路径与运行用户修改JVM堆内存参数。Nexus的JVM参数配置文件位于/opt/nexus/bin/nexus.vmoptions。根据你的服务器内存大小调整对于4GB内存的机器以下配置是安全的起点sudo vim /opt/nexus/bin/nexus.vmoptions找到以下行并进行修改如果不存在则添加-Xms512m -Xmx1024m -XX:MaxDirectMemorySize2G-Xms: JVM堆内存初始大小。设为512MB。-Xmx: JVM堆内存最大大小。设为1024MB1GB。如果你的内存充足如8GB可以设置为-Xmx2048m2GB以获得更好性能。-XX:MaxDirectMemorySize: 直接内存大小用于处理网络IO等建议设置为-Xmx的1-2倍。配置数据目录可选但强烈推荐。如果你有单独的数据盘例如挂载在/data你可以将sonatype-work目录移动过去并创建软链接。# 停止Nexus如果已启动 # 移动数据目录 sudo mv /opt/nexus/sonatype-work /data/ # 创建软链接 sudo ln -s /data/sonatype-work /opt/nexus/sonatype-work这样做的好处是即使未来需要升级或重装Nexus程序你的所有仓库数据都能完好无损。修改运行用户。编辑/opt/nexus/bin/nexus.rc文件取消run_as_user行的注释并设置为之前创建的nexus用户。sudo vim /opt/nexus/bin/nexus.rc修改为run_as_usernexus更改目录所有权。将Nexus安装目录和数据目录的所有权都赋予nexus用户。sudo chown -R nexus:nexus /opt/nexus sudo chown -R nexus:nexus /data/sonatype-work # 如果你移动了数据目录3.3 配置系统服务Systemd实现开机自启使用Systemd管理服务是最规范的方式比直接运行启动脚本更可靠。创建Systemd服务单元文件sudo vim /etc/systemd/system/nexus.service写入以下内容请根据你的实际路径调整[Unit] DescriptionNexus Repository Manager Afternetwork.target [Service] Typeforking LimitNOFILE65536 # 提高文件描述符限制应对高并发 Usernexus Groupnexus ExecStart/opt/nexus/bin/nexus start ExecStop/opt/nexus/bin/nexus stop Restarton-abort SuccessExitStatus143 TimeoutStopSec120 WorkingDirectory/opt/nexus [Install] WantedBymulti-user.target重新加载Systemd配置并启动服务sudo systemctl daemon-reload sudo systemctl start nexus sudo systemctl enable nexus # 设置开机自启检查服务状态与日志sudo systemctl status nexus # 查看实时日志 sudo journalctl -u nexus -f启动过程可能需要1-2分钟请耐心等待。当日志中出现“Started Sonatype Nexus”或类似字样时说明启动成功。4. 首次登录与基础安全加固服务启动后默认监听在http://你的服务器IP:8081。在浏览器中访问该地址。4.1 获取初始管理员密码首次访问你会被要求输入管理员密码。这个密码存储在数据目录下的一个文件中。# 使用nexus用户查看密码文件 sudo cat /data/sonatype-work/nexus3/admin.password将输出的随机密码复制粘贴到登录页面。登录后系统会强制你修改密码、设置是否允许匿名访问等。4.2 关键安全配置步骤修改管理员密码务必设置一个强密码。谨慎选择匿名访问Anonymous Access如果你希望未登录用户也能拉取下载公共仓库的缓存可以启用。但如果你希望所有操作都经过认证则禁用。对于内部私有仓库我通常建议禁用匿名访问以增强安全性。创建新的管理角色和用户极其重要不要长期使用默认的admin账户进行日常操作。应该创建一个新的、具有管理员权限的用户例如deploy-admin并禁用或妥善保管默认admin账户的密码。这符合权限最小化和审计原则。点击顶部齿轮图标设置-Security-Users-Create local user。填写用户名、密码。在Roles部分赋予其nx-admin角色。用新用户登录验证权限。4.3 配置仓库代理与仓库组这是Nexus的核心功能。以最常用的Maven仓库为例。创建代理仓库Proxy Repository用于代理远程公共仓库。进入Repository-Repositories-Create repository。选择maven2 (proxy)。Name: 起个易懂的名字如maven-central。Remote storage: 填写远程仓库URL对于Maven中央仓库就是https://repo1.maven.org/maven2/。Blob store: 选择default它决定了制品文件存储在磁盘上的哪个区域。其他选项保持默认点击Create repository。创建仓库组Repository Group将多个仓库包括代理仓库和本地仓库聚合起来客户端只需配置一个地址即可访问组内所有仓库。Create repository- 选择maven2 (group)。Name: 如maven-public。在Member repositories列表中将左边可用的仓库如你刚创建的maven-central和内置的maven-releases,maven-snapshots添加到右边。顺序决定了搜索的优先级可以将速度快的或内部仓库放在上面。现在在你的Maven项目的settings.xml中就可以将mirror或repository的URL指向http://你的Nexus IP:8081/repository/maven-public/。这样所有依赖请求都会先经过你的Nexus。5. 生产环境运维与深度优化指南将Nexus跑起来只是第一步要让它稳定、高效地服务于生产环境还需要进行一系列优化和日常维护。5.1 性能调优与JVM参数进阶默认的JVM参数可能不适合高负载场景。除了之前修改的堆内存还有几个关键点垃圾回收器调优对于Nexus这类需要较低延迟的服务可以考虑使用G1垃圾回收器。在nexus.vmoptions中添加-XX:UseG1GC -XX:MaxGCPauseMillis200调整文件描述符限制我们在systemd服务文件中已经设置了LimitNOFILE65536。你还可以在系统层面确认ulimit -n。如果值太小如1024在高并发拉取镜像或构件时可能会遇到“Too many open files”错误。Nexus专属属性编辑$data-dir/nexus3/etc/nexus.properties文件可以调整一些内部参数例如HTTP/HTTPS连接器线程数。但除非遇到明确性能瓶颈否则不建议新手修改。5.2 存储空间管理与清理策略这是运维中最常见的问题。sonatype-work目录会不断增长主要来自缓存的第三方构件。上传的内部发行版构件。系统日志和临时文件。定期清理策略使用内置的清理任务Cleanup Policies在Nexus管理界面进入Repository-Cleanup Policies-Create cleanup policy。你可以创建基于“最后下载时间”的策略。例如创建一个策略删除超过180天未被下载的Snapshots版本构件。创建后在具体仓库的配置页面Repository-Repositories- 点击仓库名 -Cleanup标签关联这个策略。注意谨慎对Release仓库使用此策略Release版本通常需要长期保留。手动清理Docker仓库的旧镜像层Docker镜像采用分层存储删除一个镜像标签并不会立即删除其独有的层。Nexus提供了“Docker - Delete unused manifests and images”的管理任务可以定期运行来清理孤儿层。设置Blob Store的配额在Blob Stores中可以为某个Blob Store设置软配额Soft Quota。当存储使用量超过配额时Nexus会发出警告并阻止新内容写入。这是一个很好的预防机制。日志轮转Nexus的日志在$data-dir/nexus3/log下。可以通过配置logback.xml来设置日志文件大小和保留天数避免日志撑满磁盘。更简单的做法是使用Linux自带的logrotate工具。5.3 备份与恢复方案备份Nexus主要是备份sonatype-work数据目录。必须在Nexus服务停止的情况下进行否则备份文件可能损坏。完整备份脚本示例#!/bin/bash BACKUP_DIR/backup/nexus DATA_DIR/data/sonatype-work DATE$(date %Y%m%d_%H%M%S) # 1. 停止Nexus服务 sudo systemctl stop nexus # 2. 创建备份 sudo tar -czf ${BACKUP_DIR}/nexus_backup_${DATE}.tar.gz -C ${DATA_DIR} . # 3. 启动Nexus服务 sudo systemctl start nexus # 4. 删除7天前的旧备份 find ${BACKUP_DIR} -name nexus_backup_*.tar.gz -mtime 7 -delete将脚本加入cron定时任务例如每周日凌晨3点执行。恢复恢复时同样先停止Nexus服务清空或移动现有数据目录然后将备份包解压到数据目录位置最后修改目录权限并启动服务。5.4 高可用与反向代理配置对于核心生产系统单点部署有风险。Nexus的商业版支持集群开源版可以通过以下方式提升可用性定期备份并准备冷备机这是最简单有效的方式。使用Nginx/Apache作为反向代理隐藏端口让用户通过标准的80/443端口访问。配置SSL使用反向代理处理HTTPS证书比在Nexus内配置更简单。负载均衡商业版集群如果是集群部署反向代理可以将请求分发到多个Nexus节点。一个简单的Nginx配置示例如下server { listen 80; server_name nexus.yourcompany.com; # 强制跳转HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name nexus.yourcompany.com; ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; location / { proxy_pass http://localhost:8081; # 指向Nexus服务 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 设置较长的超时时间用于处理大文件上传/下载 proxy_read_timeout 600s; proxy_connect_timeout 600s; proxy_send_timeout 600s; client_max_body_size 0; # 不限制上传文件大小 } }配置完成后重启Nginx并通过域名https://nexus.yourcompany.com访问你的Nexus。6. 常见问题排查与故障解决即使按照教程操作也可能会遇到问题。这里列举几个我踩过的坑及其解决方案。6.1 服务无法启动端口冲突与权限问题现象执行systemctl start nexus后systemctl status nexus显示失败日志中有Address already in use或权限错误。排查端口占用Nexus默认使用8081端口。使用sudo netstat -tlnp | grep 8081查看是否被其他进程占用。如果是可以修改Nexus的监听端口配置文件在$data-dir/nexus3/etc/nexus.properties修改application-port和application-host。用户权限确保/opt/nexus和/data/sonatype-work目录的所有者和组都是nexus。使用ls -la查看。SELinux在CentOS上SELinux可能会阻止Nexus进程访问其目录。可以尝试临时禁用SELinux进行测试sudo setenforce 0。如果问题解决则需要为Nexus目录添加正确的SELinux上下文或将其设置为永久宽容模式生产环境不推荐。6.2 客户端连接失败防火墙与网络策略现象服务器本地curl http://localhost:8081能通但外部机器无法访问。解决检查CentOS防火墙# CentOS 7 sudo firewall-cmd --permanent --add-port8081/tcp sudo firewall-cmd --reload # 如果使用Nginx反向代理则需要开放80和443端口 sudo firewall-cmd --permanent --add-servicehttp --add-servicehttps sudo firewall-cmd --reload检查云服务商安全组如果你使用的是阿里云、AWS等云服务器需要在控制台的安全组规则中放行8081端口或80/443端口的入站流量。6.3 磁盘空间告急的紧急处理现象df -h显示磁盘使用率100%Nexus无法写入新构件。紧急清理查找大文件使用du -sh /data/sonatype-work/* | sort -rh | head -20找出占用空间最大的子目录。清理Docker仓库孤儿层立即在Nexus管理界面运行 “Docker - Delete unused manifests and images” 任务。清理临时文件可以安全删除$data-dir/nexus3/tmp目录下的内容需停止服务。清理旧日志$data-dir/nexus3/log下的.log.gz文件可以删除。终极方案如果以上都无法释放足够空间需要先扩容磁盘或者将整个sonatype-work目录迁移到新的、更大的磁盘上操作前务必完整备份并停止服务。6.4 上传内部组件失败权限与仓库类型现象使用Mavendeploy命令上传内部Jar包到Nexus时返回401 Unauthorized或403 Forbidden。排查认证失败 (401)检查Mavensettings.xml中配置的服务器(server)用户名和密码是否正确是否与Nexus中创建的用户匹配。权限不足 (403)确认该Nexus用户是否拥有向目标仓库通常是maven-releases或maven-snapshots写的权限。在Nexus的Roles配置中确保用户所属角色包含了nx-repository-view-*-*-edit这类权限。仓库类型不匹配不能向代理仓库(proxy)或仓库组(group)上传构件。必须上传到托管仓库(hosted)如maven-releases(用于正式版) 或maven-snapshots(用于快照版)。