docs: Dockerized cnpmjs.org configuration with installation guide (#1191)
* add dockerizing file * using mysql for dockerized cnpmjsorg * add configure file for the dockrized instance * update dockerized configuration for work properly on test env * add dockerized cnpmjs.org install guide * add named Docker volume * update dockerized configuration, enable abbreviated meta data by default
This commit is contained in:
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
28
Dockerfile
Normal file
28
Dockerfile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
FROM node:6.11
|
||||||
|
MAINTAINER Bono Lv <lvscar {aT} gmail.com>
|
||||||
|
|
||||||
|
# Working enviroment
|
||||||
|
ENV \
|
||||||
|
CNPM_DIR="/var/app/cnpmjs.org" \
|
||||||
|
CNPM_DATA_DIR="/var/data/cnpm_data"
|
||||||
|
|
||||||
|
RUN mkdir -p ${CNPM_DIR}
|
||||||
|
|
||||||
|
WORKDIR ${CNPM_DIR}
|
||||||
|
|
||||||
|
COPY package.json ${CNPM_DIR}
|
||||||
|
|
||||||
|
RUN npm set registry https://registry.npm.taobao.org
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . ${CNPM_DIR}
|
||||||
|
COPY docs/dockerize/config.js ${CNPM_DIR}/config/
|
||||||
|
|
||||||
|
EXPOSE 7001/tcp 7002/tcp
|
||||||
|
|
||||||
|
VOLUME ["/var/data/cnpm_data"]
|
||||||
|
|
||||||
|
# Entrypoint
|
||||||
|
CMD ["node", "dispatch.js"]
|
||||||
|
|
||||||
55
README.md
55
README.md
@@ -103,6 +103,61 @@ $ make autod
|
|||||||
$ make dev
|
$ make dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Dockerized cnpmjs.org Installation Guide
|
||||||
|
|
||||||
|
Cnpmjs.org shipped with a simple but pragmatic Docker Compose configuration.With the configuration, you can set up a MySQL backed cnpmjs.org instance by executing just one command on Docker installed environment.
|
||||||
|
|
||||||
|
#### Preparation
|
||||||
|
|
||||||
|
* [Install Docker](https://www.docker.com/community-edition)
|
||||||
|
* [Install Docker Compose](https://docs.docker.com/compose/install/) (Docker for Mac, Docker for Windows include Docker Compose, so most Mac and Windows users do not need to install Docker Compose separately)
|
||||||
|
* (Optional) Speed up Docker images downloading by setting up [Docker images download accelerator](https://yq.aliyun.com/articles/29941)
|
||||||
|
|
||||||
|
|
||||||
|
#### Dockerized cnpmjs.org control command
|
||||||
|
|
||||||
|
Make sure your current working directory is the root of this GitHub repository.
|
||||||
|
|
||||||
|
##### Run dockerized cnpmjs.org
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$docker-compose up
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will build a Docker image using the current code of repository. Then set up a dockerized MySQL instance with data initialized. After Docker container running, you can access your cnpmjs.org web portal at http://127.0.0.1:7002 and npm register at http://127.0.0.1:7001.
|
||||||
|
|
||||||
|
#### Run cnpmjs.org in the backend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Rebuild cnpmjs.org Docker image
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$docker-compose build
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Remove current dockerized cnpmjs.org instance
|
||||||
|
|
||||||
|
The current configuration set 2 named Docker Volume for your persistent data. If you haven't change the repository directory name, them will be "cnpmjsorg_cnpm-files-volume" & "cnpmjsorg_cnpm-db-volume".
|
||||||
|
|
||||||
|
Be Careful, the following commands will remove them.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$docker-compose rm
|
||||||
|
$docker volume rm cnpmjsorg_cnpm-files-volume
|
||||||
|
$docker volume rm cnpmjsorg_cnpm-db-volume
|
||||||
|
```
|
||||||
|
|
||||||
|
You can get more information about your data volumes using the below commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$docker volume ls // list all of your Docker volume
|
||||||
|
$docker volume inspect cnpmjsorg_cnpm-files-volume
|
||||||
|
$docker volume inspect cnpmjsorg_cnpm-db-volume
|
||||||
|
```
|
||||||
|
|
||||||
## How to contribute
|
## How to contribute
|
||||||
|
|
||||||
* Clone the project
|
* Clone the project
|
||||||
|
|||||||
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
image: cnpmjs.org
|
||||||
|
depends_on:
|
||||||
|
- mysql-db
|
||||||
|
volumes:
|
||||||
|
- cnpm-files-volume:/var/data/cnpm_data
|
||||||
|
ports:
|
||||||
|
- "7001:7001"
|
||||||
|
- "7002:7002"
|
||||||
|
|
||||||
|
mysql-db:
|
||||||
|
image: mysql:5.6
|
||||||
|
restart: always
|
||||||
|
environment :
|
||||||
|
MYSQL_USER: root
|
||||||
|
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||||
|
MYSQL_DATABASE: cnpmjs_test
|
||||||
|
MYSQL_ROOT_HOST: "%"
|
||||||
|
volumes:
|
||||||
|
- ./docs/db.sql:/docker-entrypoint-initdb.d/cnpm-init.sql
|
||||||
|
- cnpm-db-volume:/var/lib/mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
cnpm-files-volume:
|
||||||
|
cnpm-db-volume:
|
||||||
261
docs/dockerize/config.js
Normal file
261
docs/dockerize/config.js
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var mkdirp = require('mkdirp');
|
||||||
|
var copy = require('copy-to');
|
||||||
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var os = require('os');
|
||||||
|
|
||||||
|
var version = require('../package.json').version;
|
||||||
|
|
||||||
|
var root = path.dirname(__dirname);
|
||||||
|
var dataDir = process.env.CNPM_DATA_DIR ;
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
version: version,
|
||||||
|
dataDir: dataDir,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cluster mode
|
||||||
|
*/
|
||||||
|
enableCluster: false,
|
||||||
|
numCPUs: os.cpus().length,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* server configure
|
||||||
|
*/
|
||||||
|
|
||||||
|
registryPort: 7001,
|
||||||
|
webPort: 7002,
|
||||||
|
bindingHost: '0.0.0.0', // binding on 0.0.0.0 for outside of container access
|
||||||
|
|
||||||
|
// debug mode
|
||||||
|
// if in debug mode, some middleware like limit wont load
|
||||||
|
// logger module will print to stdout
|
||||||
|
debug: process.env.NODE_ENV === 'development',
|
||||||
|
// page mode, enable on development env
|
||||||
|
pagemock: process.env.NODE_ENV === 'development',
|
||||||
|
// session secret
|
||||||
|
sessionSecret: 'cnpmjs.org test session secret',
|
||||||
|
// max request json body size
|
||||||
|
jsonLimit: '10mb',
|
||||||
|
// log dir name
|
||||||
|
logdir: path.join(dataDir, 'logs'),
|
||||||
|
// update file template dir
|
||||||
|
uploadDir: path.join(dataDir, 'downloads'),
|
||||||
|
// web page viewCache
|
||||||
|
viewCache: false,
|
||||||
|
|
||||||
|
// config for koa-limit middleware
|
||||||
|
// for limit download rates
|
||||||
|
limit: {
|
||||||
|
enable: false,
|
||||||
|
token: 'koa-limit:download',
|
||||||
|
limit: 1000,
|
||||||
|
interval: 1000 * 60 * 60 * 24,
|
||||||
|
whiteList: [],
|
||||||
|
blackList: [],
|
||||||
|
message: 'request frequency limited, any question, please contact fengmk2@gmail.com',
|
||||||
|
},
|
||||||
|
|
||||||
|
enableCompress: false, // enable gzip response or not
|
||||||
|
|
||||||
|
// default system admins
|
||||||
|
admins: {
|
||||||
|
// name: email
|
||||||
|
fengmk2: 'fengmk2@gmail.com',
|
||||||
|
admin: 'admin@cnpmjs.org',
|
||||||
|
dead_horse: 'dead_horse@qq.com',
|
||||||
|
},
|
||||||
|
|
||||||
|
// email notification for errors
|
||||||
|
// check https://github.com/andris9/Nodemailer for more informations
|
||||||
|
mail: {
|
||||||
|
enable: false,
|
||||||
|
appname: 'cnpmjs.org',
|
||||||
|
from: 'cnpmjs.org mail sender <adderss@gmail.com>',
|
||||||
|
service: 'gmail',
|
||||||
|
auth: {
|
||||||
|
user: 'address@gmail.com',
|
||||||
|
pass: 'your password'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
logoURL: 'https://os.alipayobjects.com/rmsportal/oygxuIUkkrRccUz.jpg', // cnpm logo image url
|
||||||
|
adBanner: '',
|
||||||
|
customReadmeFile: '', // you can use your custom readme file instead the cnpm one
|
||||||
|
customFooter: '', // you can add copyright and site total script html here
|
||||||
|
npmClientName: 'cnpm', // use `${name} install package`
|
||||||
|
packagePageContributorSearch: true, // package page contributor link to search, default is true
|
||||||
|
|
||||||
|
// max handle number of package.json `dependencies` property
|
||||||
|
maxDependencies: 200,
|
||||||
|
// backup filepath prefix
|
||||||
|
backupFilePrefix: '/cnpm/backup/',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* database config
|
||||||
|
*/
|
||||||
|
|
||||||
|
database: {
|
||||||
|
db: 'cnpmjs_test',
|
||||||
|
username: 'root',
|
||||||
|
password: '',
|
||||||
|
|
||||||
|
// the sql dialect of the database
|
||||||
|
// - currently supported: 'mysql', 'sqlite', 'postgres', 'mariadb'
|
||||||
|
dialect: 'mysql',
|
||||||
|
|
||||||
|
// the Docker container network hostname defined at docker-compose.yml
|
||||||
|
host: 'mysql-db',
|
||||||
|
|
||||||
|
// custom port; default: 3306
|
||||||
|
port: 3306,
|
||||||
|
|
||||||
|
// use pooling in order to reduce db connection overload and to increase speed
|
||||||
|
// currently only for mysql and postgresql (since v1.5.0)
|
||||||
|
pool: {
|
||||||
|
maxConnections: 10,
|
||||||
|
minConnections: 0,
|
||||||
|
maxIdleTime: 30000
|
||||||
|
},
|
||||||
|
|
||||||
|
// the storage engine for 'sqlite'
|
||||||
|
// default store into ~/.cnpmjs.org/data.sqlite
|
||||||
|
//storage: path.join(dataDir, 'data.sqlite'),
|
||||||
|
|
||||||
|
logging: !!process.env.SQL_DEBUG,
|
||||||
|
},
|
||||||
|
|
||||||
|
// package tarball store in local filesystem by default
|
||||||
|
nfs: require('fs-cnpm')({
|
||||||
|
dir: path.join(dataDir, 'nfs')
|
||||||
|
}),
|
||||||
|
// if set true, will 302 redirect to `nfs.url(dist.key)`
|
||||||
|
downloadRedirectToNFS: false,
|
||||||
|
|
||||||
|
// registry url name
|
||||||
|
registryHost: '127.0.0.1:7001',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registry mode config
|
||||||
|
*/
|
||||||
|
|
||||||
|
// enable private mode or not
|
||||||
|
// private mode: only admins can publish, other users just can sync package from source npm
|
||||||
|
// public mode: all users can publish
|
||||||
|
enablePrivate: false,
|
||||||
|
|
||||||
|
// registry scopes, if don't set, means do not support scopes
|
||||||
|
scopes: [ '@cnpm', '@cnpmtest', '@cnpm-test' ],
|
||||||
|
|
||||||
|
// some registry already have some private packages in global scope
|
||||||
|
// but we want to treat them as scoped private packages,
|
||||||
|
// so you can use this white list.
|
||||||
|
privatePackages: [],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sync configs
|
||||||
|
*/
|
||||||
|
|
||||||
|
// the official npm registry
|
||||||
|
// cnpm wont directly sync from this one
|
||||||
|
// but sometimes will request it for some package infomations
|
||||||
|
// please don't change it if not necessary
|
||||||
|
officialNpmRegistry: 'https://registry.npmjs.com',
|
||||||
|
officialNpmReplicate: 'https://replicate.npmjs.com',
|
||||||
|
|
||||||
|
// sync source, upstream registry
|
||||||
|
// If you want to directly sync from official npm's registry
|
||||||
|
// please drop them an email first
|
||||||
|
sourceNpmRegistry: 'https://registry.npm.taobao.org',
|
||||||
|
|
||||||
|
// upstream registry is base on cnpm/cnpmjs.org or not
|
||||||
|
// if your upstream is official npm registry, please turn it off
|
||||||
|
sourceNpmRegistryIsCNpm: true,
|
||||||
|
|
||||||
|
// if install return 404, try to sync from source registry
|
||||||
|
syncByInstall: true,
|
||||||
|
|
||||||
|
// sync mode select
|
||||||
|
// none: do not sync any module, proxy all public modules from sourceNpmRegistry
|
||||||
|
// exist: only sync exist modules
|
||||||
|
// all: sync all modules
|
||||||
|
syncModel: 'none', // 'none', 'all', 'exist'
|
||||||
|
|
||||||
|
syncConcurrency: 1,
|
||||||
|
// sync interval, default is 10 minutes
|
||||||
|
syncInterval: '10m',
|
||||||
|
|
||||||
|
// sync polular modules, default to false
|
||||||
|
// because cnpm can't auto sync tag change for now
|
||||||
|
// so we want to sync popular modules to ensure their tags
|
||||||
|
syncPopular: false,
|
||||||
|
syncPopularInterval: '1h',
|
||||||
|
// top 100
|
||||||
|
topPopular: 100,
|
||||||
|
|
||||||
|
// sync devDependencies or not, default is false
|
||||||
|
syncDevDependencies: false,
|
||||||
|
|
||||||
|
// changes streaming sync
|
||||||
|
syncChangesStream: false,
|
||||||
|
handleSyncRegistry: 'http://127.0.0.1:7001',
|
||||||
|
|
||||||
|
// badge subject on http://shields.io/
|
||||||
|
badgePrefixURL: 'https://img.shields.io/badge',
|
||||||
|
badgeSubject: 'cnpm',
|
||||||
|
|
||||||
|
// custom user service, @see https://github.com/cnpm/cnpmjs.org/wiki/Use-Your-Own-User-Authorization
|
||||||
|
// when you not intend to ingegrate with your company's user system, then use null, it would
|
||||||
|
// use the default cnpm user system
|
||||||
|
userService: null,
|
||||||
|
|
||||||
|
// always-auth https://docs.npmjs.com/misc/config#always-auth
|
||||||
|
// Force npm to always require authentication when accessing the registry, even for GET requests.
|
||||||
|
alwaysAuth: false,
|
||||||
|
|
||||||
|
// if you're behind firewall, need to request through http proxy, please set this
|
||||||
|
// e.g.: `httpProxy: 'http://proxy.mycompany.com:8080'`
|
||||||
|
httpProxy: null,
|
||||||
|
|
||||||
|
// snyk.io root url
|
||||||
|
snykUrl: 'https://snyk.io',
|
||||||
|
|
||||||
|
// https://github.com/cnpm/cnpmjs.org/issues/1149
|
||||||
|
// if enable this option, must create module_abbreviated and package_readme table in database
|
||||||
|
enableAbbreviatedMetadata: true,
|
||||||
|
|
||||||
|
// global hook function: function* (envelope) {}
|
||||||
|
// envelope format please see https://github.com/npm/registry/blob/master/docs/hooks/hooks-payload.md#payload
|
||||||
|
globalHook: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'test') {
|
||||||
|
var customConfig;
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
customConfig = path.join(root, 'config', 'config.js');
|
||||||
|
} else {
|
||||||
|
// 1. try to load `$dataDir/config.json` first, not exists then goto 2.
|
||||||
|
// 2. load config/config.js, everything in config.js will cover the same key in index.js
|
||||||
|
customConfig = path.join(dataDir, 'config.json');
|
||||||
|
if (!fs.existsSync(customConfig)) {
|
||||||
|
customConfig = path.join(root, 'config', 'config.js');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fs.existsSync(customConfig)) {
|
||||||
|
copy(require(customConfig)).override(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdirp.sync(config.logdir);
|
||||||
|
mkdirp.sync(config.uploadDir);
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
|
|
||||||
|
config.loadConfig = function (customConfig) {
|
||||||
|
if (!customConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
copy(customConfig).override(config);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user