小标
2019-06-20
来源 :
阅读 2014
评论 0
摘要:本文主要向大家介绍了Linux运维知识之在 CentOS 7 平台使用 cnpmjs.org 搭建 npm 私有仓储,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助。
本文主要向大家介绍了Linux运维知识之在 CentOS 7 平台使用 cnpmjs.org 搭建 npm 私有仓储,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助。

1、下载 CentOS 7 系统镜像并安装,选择基本开发环境。
2、修改默认 yum 源为阿里云源,并添加 EPEL 源。
# 如提示 wget 不存在,可使用 curl 下载 # 备份默认源 sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak # 修改为阿里源 sudo wget -O /etc/yum.repos.d/CentOS-Base.repo //mirrors.aliyun.com/repo/Centos-7.repo # 添加 EPEL 源 sudo wget -O /etc/yum.repos.d/epel.repo //mirrors.aliyun.com/repo/epel-7.repo
3、安装 gcc 编译环境
sudo yum install gcc-c++ make
4、验证安装结果
# 验证 g++ 版本 g++ -v 使用内建 specs。 COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper 目标:x86_64-redhat-linux 配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=//bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux 线程模型:posix gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) # 验证 make 版本 make -v GNU Make 3.82 Built for x86_64-redhat-linux-gnu Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <//gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
1、执行环境检测脚本,下载 node 在相应环境的已编译包
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
2、安装 node 和 npm
sudo yum -y install nodejs
3、验证安装结果
# 验证 node 版本 node -v v8.9.4 # 验证 npm 版本 npm -v 5.6.0
1、安装 cnpmjs.org依赖
# 安装 cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org # 安装 node-pre-gyp cnpm install -g node-pre-gyp # 安装 sqlite3 直接安装会报错 node-pre-gyp: 未找到命令 cnpm install -g sqlite3 # 安装 cnpmjs.org cnpm install -g cnpmjs.org # 创建配置目录 ~/.cnpmjs.org cnpmjs.org start
2、验证安装结果
# 验证 cnpm 版本 cnpm -v cnpm@5.2.0 (/usr/lib/node_modules/cnpm/lib/parse_argv.js) npm@5.7.1 (/usr/lib/node_modules/cnpm/node_modules/npm/lib/npm.js) node@8.9.4 (/usr/bin/node) npminstall@3.3.0 (/usr/lib/node_modules/cnpm/node_modules/npminstall/lib/index.js) prefix=/usr linux x64 3.10.0-327.el7.x86_64 registry=https://registry.npm.taobao.org # 验证 node-pre-gyp 版本 node-pre-gyp -v v0.6.39 # 验证 sqlite3 版本 sqlite3 -version 3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668 # 验证 cnpmjs.org 版本 cnpmjs.org --version 2.19.4
3、添加防火墙例外
# 检查防火墙状态 systemctl status firewalld # 启动防火墙,未启动会报错 FirewallD is not running systemctl start firewalld # 添加 7001 端口 firewall-cmd --zone=public --add-port=7001/tcp --permanent # 添加 7002 端口 firewall-cmd --zone=public --add-port=7002/tcp --permanent # 根据需要,关闭防火墙 systemctl stop firewalld
1、修改 /root/.cnpmjs.org/config.json (实际使用中必须删除注释,否则 json 格式错误)
{
""registryPort"": 7001, // cnpmjs.org web 站点端口
""webPort"": 7002, // cnpmjs.org register 端口
""bindingHost"": ""0.0.0.0"", // 允许外部访问
""handleSyncRegistry"": ""//127.0.0.1:7001"", // 同步源
""registryHost"": ""registry.npm.xxxxxx.work"", // cnpmjs.org register 域名
""scopes"": [
""@xxxxxx"" // 私有包 scope 名称
],
""enablePrivate"": false, // 允许所有登录用户发布私有包
""syncModel"": ""none"", // 不同步公共包
""alwaysAuth"": false, // 不强制用户认证
""customReadmeFile"": ""/root/.cnpmjs.org/docs/web/readme.md"", // 自定义首页
""userService"": ""/root/.cnpmjs.org/services/custom_user_service.js"", // 自定义用户认证
""admins"": {
""admin"": ""admin@xxxx.com"" // cnpmjs.org 管理员
},
""database"": { // cnpmjs.org 数据库
""db"": ""cnpmjs_test"", // 数据库名称
""username"": ""root"", // 数据库用户名
""password"": """", // 数据库密码
""dialect"": ""sqlite"", // 数据库类型
""host"": ""127.0.0.1"", // 数据库 IP
""port"": 3306, // 数据库端口
""storage"": ""/root/.cnpmjs.org/data.sqlite"" // sqlite 数据库位置
}
}2、修改 cnpmjs.org 源码
/usr/lib/node_modules/cnpmjs.org/services/user.js
11 + if(typeof(config.userService) === 'string') {
12 + var CustomUserService = require(config.userService);
13 + config.userService = new CustomUserService();
14 + }3、自定义首页 /root/.cnpmjs.org/docs/web/readme.md
# 公司 npm 私有仓储 [npm.xxxxxx.work](//npm.xxxxxx.work) 基于 [cnpmjs.org](https://github.com/cnpm/cnpmjs.org) 搭建,使用 @xxxxxx 作为私有仓储的 [scope](https://docs.npmjs.com/getting-start) 仅用于托管公司私有包,不同步公共包,可使用 npm 或 cnpm 客户端。 ## npm 或 cnpm 客户端配置 1. 拦截 @xxxxxx 作用域下所有操作至私有仓储,可安装公司私有包。 ``bash # 或替换为 cnpm 命令 $ npm config set @xxxxxx:registry //registry.npm.xxxxxx.work `` 2. 使用 [git.xxxxxx.work](//git.xxxxxx.work) 用户名和[个人访问令牌](//git.xxxxxx.work/profile/personal_access_tokens)登录,可发布公司私有包。 ``bash # 或替换为 cnpm 命令 $ npm login --scope=@xxxxxx --registry=//registry.npm.xxxxxx.work Username: zhangsan # 用户名 Password: xxxxxxxxxxxxxxxxxxxx # 个人访问令牌(需勾选 Scopes 中 api 选项) Email: (this IS public) zhangsan@xxxx.com # 邮箱 `` ## 更多信息请查看[使用说明](//xxxxxx.wiki/pages/viewpage.action?pageId=8524381) **此处粘贴 /usr/lib/node_modules/cnpmjs.org/docs/web/readme.md 文件内容**
4、自定义用户认证 /root/.cnpmjs.org/services/custom_user_service.js
const http = require('http');
const isAdmin = require('cnpmjs.org/lib/common').isAdmin;
const config = require('cnpmjs.org/config');
// User: https://github.com/cnpm/cnpmjs.org/wiki/Use-Your-Own-User-Authorization#user-data-structure
// {
// ""login"": ""fengmk2"",
// ""email"": ""fengmk2@gmail.com"",
// ""name"": ""Yuan Feng"",
// ""html_url"": ""//fengmk2.github.com"",
// ""avatar_url"": ""https://avatars3.githubusercontent.com/u/156269?s=460"",
// ""im_url"": """",
// ""site_admin"": false,
// ""scopes"": [""@org1"", ""@org2""]
// }
const emailDomain = '@xxxx.com';
const defaultToken = 'xxxxxxxxxxxxxxxxxxxx';
function convertToUser(gitUser) {
let user = {
login: gitUser.username,
email: gitUser.email || `${gitUser.username}${emailDomain}`,
name: gitUser.name,
html_url: gitUser.web_url,
avatar_url: gitUser.avatar_url,
im_url: '',
site_admin: isAdmin(gitUser.username),
scopes: config.scopes,
};
return user;
}
function gitHttp(api, token) {
return new Promise((resolve, reject) => {
let options = {
method: 'GET',
port: 80,
hostname: 'git.xxxxxx.work',
path: `/api/v4${api}`,
headers: {
'PRIVATE-TOKEN': token
}
};
let req = http.request(options, (res) => {
if (res.statusCode === 200) {
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => {
rawData += chunk;
});
res.on('end', () => {
try {
let parsedData = JSON.parse(rawData);
console.log(`[CustomUserService] [${api}] [${token}] JSON.parse: success`, parsedData);
resolve(parsedData);
} catch (e) {
reject(`[CustomUserService] [${api}] [${token}] JSON.parse: ${e.message}`, e);
}
});
}
else {
reject(`[CustomUserService] [${api}] [${token}] statusCode: ${res.statusCode}`);
}
});
req.on('error', (e) => {
reject(`[CustomUserService] [${api}] [${token}] error: ${e.message}`, e);
});
req.end();
});
}
function* gitAuth(username, token) {
let data = yield gitHttp('/user', token);
let gitUser = null;
if (data && data.username === username) {
gitUser = data;
}
return gitUser;
}
function* gitGet(username) {
let data = yield gitHttp(`/users?username=${encodeURIComponent(username)}`, defaultToken);
let gitUser = null;
if (data && data.length > 0 && data[0].username === username) {
gitUser = data[0];
}
return gitUser;
}
function* gitList(usernames) {
let gitUsers = [];
if (usernames && usernames.length > 0) {
for (let i = 0; i < usernames.length; i++) {
let username = usernames[i];
let gitUser = yield gitGet(username);
if (gitUser) {
gitUsers.push(gitUser);
}
}
}
return gitUsers;
}
function* gitSearch(query, limit) {
let data = yield gitHttp(`/users?search=${encodeURIComponent(query)}&per_page=${limit}`, defaultToken);
let gitUsers = [];
if (data && data.length > 0) {
gitUsers = data;
}
return gitUsers;
}
function CustomUserService() { }
const proto = CustomUserService.prototype;
/**
* Auth user with login name and password
* @param {String} login login name
* @param {String} password login password
* @return {User}
*/
proto.auth = function* (login, password) {
console.log(`[CustomUserService] [auth]`, login, password);
let user = null;
try {
let gitUser = yield gitAuth(login, password);
if (gitUser) {
user = convertToUser(gitUser);
}
}
catch (e) {
console.log(`[CustomUserService] [auth]`, e);
}
return user;
};
/**
* Get user by login name
* @param {String} login login name
* @return {User}
*/
proto.get = function* (login) {
console.log(`[CustomUserService] [get]`, login);
let user = null;
try {
let gitUser = yield gitGet(login);
if (gitUser) {
user = convertToUser(gitUser);
}
}
catch (e) {
console.log(`[CustomUserService] [get]`, e);
}
return user;
};
/**
* List users
* @param {Array<String>} logins login names
* @return {Array<User>}
*/
proto.list = function* (logins) {
console.log(`[CustomUserService] [list]`, logins);
let users = [];
try {
let gitUsers = yield gitList(logins);
gitUsers.forEach((gitUser) => {
users.push(convertToUser(gitUser));
});
}
catch (e) {
console.log(`[CustomUserService] [list]`, e);
}
return users;
};
/**
* Search users
* @param {String} query query keyword
* @param {Object} [options] optional query params
* - {Number} limit match users count, default is `20`
* @return {Array<User>}
*/
proto.search = function* (query, options) {
console.log(`[CustomUserService] [search]`, query, options);
let users = [];
try {
options = options || {};
options.limit = parseInt(options.limit);
if (!options.limit || options.limit < 0) {
options.limit = 20;
}
let gitUsers = yield gitSearch(query, options.limit);
gitUsers.forEach((gitUser) => {
users.push(convertToUser(gitUser));
});
}
catch (e) {
console.log(`[CustomUserService] [search]`, e);
}
return users;
};
module.exports = CustomUserService;5、验证自定义配置
export NODE_PATH=/usr/lib/node_modules && /usr/bin/cnpmjs.org start
Starting cnpmjs.org ...
cluster: false
admins: {""admin"":""admin@xxxx.com""}
scopes: [""@xxxxxx""]
sourceNpmRegistry: https://registry.npm.taobao.org
syncModel: none
[Tue Mar 06 2018 17:05:20 GMT+0800 (CST)] [worker:8004] Server started, registry server listen at 0.0.0.0:7001, web listen at 0.0.0.0:7002, cluster: false1、创建服务并开机自启 /usr/lib/systemd/system/cnpmjs.org.service
[Unit] Description=cnpmjs.org After=network.target [Service] Type=simple User=root Environment=NODE_PATH=/usr/lib/node_modules ExecStart=/usr/bin/cnpmjs.org start ExecStop=/usr/bin/cnpmjs.org stop PrivateTmp=true [Install] WantedBy=multi-user.target
2、应用并启动 cnpmjs.org 服务
# 刷新服务守护进程 systemctl daemon-reload # 启动 cnpmjs.org 服务 systemctl start cnpmjs.org.service # 设置开机启动 systemctl enable cnpmjs.org.service # 查看启动日志 journalctl -u cnpmjs.org.service
3、配置 nginx 反向代理
# cnpmjs.org registry
server {
listen 80;
server_name registry.npm.xxxxxx.work;
location / {
#proxy_redirect off;
proxy_pass //192.168.21.23:7001;
}
}
# cnpmjs.org web
server {
listen 80;
server_name npm.xxxxxx.work;
location / {
#proxy_redirect off;
proxy_pass //192.168.21.23:7002;
}
}4、验证域名配置
curl npm.xxxxxx.work curl registry.npm.xxxxxx.work
5、创建备份脚本 /root/.cnpmjs.org/backup/backup.sh
由于 cnpmjs.org 使用文件方式存放已发布的包,因此只用备份 sqlite 数据库即可。
#!/bin/sh
# 当前时间
var_dateTime=$(date +%Y%m%d%H%M)
# cnpmjs.org 配置目录
var_workDir=""/root/.cnpmjs.org""
# 备份目录
var_backupDir=${var_workDir}""/backup/""${var_dateTime}
# 创建备份目录
mkdir -p ${var_backupDir}
# 数据库源位置
var_dataSource=${var_workDir}""/data.sqlite""
# 数据库目标位置
var_dataTarget=${var_backupDir}""/data.sqlite""
# 备份数据库
sqlite3 ${var_dataSource} "".backup ${var_dataTarget}""6、验证备份脚本
# 修改备份脚本执行权限 chmod a+x /root/.cnpmjs.org/backup/backup.sh # 执行备份脚本 /root/.cnpmjs.org/backup/backup.sh # 检查是否已经生成备份 ls -l /root/.cnpmjs.org/backup/
7、配置定时任务
# 编辑定时任务文件 /var/spool/cron/root crontab -e # 每周日 00:00 执行备份 0 0 * * 0 /root/.cnpmjs.org/backup/backup.sh # 如果未正常进行,检查以下文件 cat /var/log/cron cat /var/spool/mail/root
1、拦截 @xxxxxx 作用域下所有操作至私有仓储,可安装公司私有包。
# 或替换为 cnpm 命令 npm config set @xxxxxx:registry //registry.npm.xxxxxx.work
2、使用 git.xxxxxx.work 用户名和个人访问令牌登录,可发布公司私有包。
# 或替换为 cnpm 命令 npm login --scope=@xxxxxx --registry=//registry.npm.xxxxxx.work Username: zhangsan # 用户名 Password: xxxxxxxxxxxxxxxxxxxx # 个人访问令牌(需勾选 Scopes 中 api 选项) Email: (this IS public) zhangsan@xxxx.com # 邮箱本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注系统运维Linux频道!
喜欢 | 0
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号