feat: allow to set sourceRegistry by CNPMCORE_CONFIG_SOURCE_REGISTRY (#753)
Improve the local development process based on docker-compose <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a centralized configuration utility that validates environment variable types and provides fallback defaults. - **Refactor** - Standardized environment variable handling across configuration files, improving maintainability and consistency in system setup. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
9
.env.example
Normal file
9
.env.example
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# CNPMCORE_DATABASE_TYPE=MySQL
|
||||||
|
# CNPMCORE_DATABASE_USER=root
|
||||||
|
# CNPMCORE_DATABASE_PASSWORD=
|
||||||
|
# CNPMCORE_DATABASE_NAME=cnpmcore
|
||||||
|
|
||||||
|
# CNPMCORE_DATABASE_TYPE=PostgreSQL
|
||||||
|
# CNPMCORE_DATABASE_USER=postgres
|
||||||
|
# CNPMCORE_DATABASE_PASSWORD=postgres
|
||||||
|
# CNPMCORE_DATABASE_NAME=cnpmcore
|
||||||
46
DEVELOPER.md
46
DEVELOPER.md
@@ -4,14 +4,32 @@
|
|||||||
|
|
||||||
本项目的外部服务依赖有:MySQL 数据库或 PostgreSQL 数据库、Redis 缓存服务。
|
本项目的外部服务依赖有:MySQL 数据库或 PostgreSQL 数据库、Redis 缓存服务。
|
||||||
|
|
||||||
可以通过 Docker 来快速启动本地开发环境:
|
生成本地开发环境配置文件:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 启动本地依赖服务
|
cp .env.example .env
|
||||||
docker-compose up -d
|
```
|
||||||
|
|
||||||
|
可以通过 Docker 来快速启动本地开发环境:
|
||||||
|
|
||||||
|
MySQL 开发环境:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动本地依赖服务 - MySQL + Redis
|
||||||
|
docker-compose -f docker-compose.yml up -d
|
||||||
|
|
||||||
# 关闭本地依赖服务
|
# 关闭本地依赖服务
|
||||||
docker-compose down
|
docker-compose -f docker-compose.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
PostgreSQL 开发环境:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动本地依赖服务 - PostgreSQL + Redis
|
||||||
|
docker-compose -f docker-compose-postgres.yml up -d
|
||||||
|
|
||||||
|
# 关闭本地依赖服务
|
||||||
|
docker-compose -f docker-compose-postgres.yml down
|
||||||
```
|
```
|
||||||
|
|
||||||
> 手动初始化依赖服务参见[本地开发环境 - MySQL](./docs/setup.md) 或 [本地开发环境 - PostgreSQL](./docs/setup-with-postgresql.md)
|
> 手动初始化依赖服务参见[本地开发环境 - MySQL](./docs/setup.md) 或 [本地开发环境 - PostgreSQL](./docs/setup-with-postgresql.md)
|
||||||
@@ -35,6 +53,9 @@ npm run dev
|
|||||||
|
|
||||||
# 访问
|
# 访问
|
||||||
curl -v http://127.0.0.1:7001
|
curl -v http://127.0.0.1:7001
|
||||||
|
|
||||||
|
# cnpmcore_admin 注册管理员
|
||||||
|
npm login --registry=http://127.0.0.1:7001
|
||||||
```
|
```
|
||||||
|
|
||||||
### 开发运行 - PostgreSQL
|
### 开发运行 - PostgreSQL
|
||||||
@@ -50,6 +71,23 @@ npm run dev:postgresql
|
|||||||
curl -v http://127.0.0.1:7001
|
curl -v http://127.0.0.1:7001
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 登录和测试发包
|
||||||
|
|
||||||
|
注册 cnpmcore_admin 管理员
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm login --registry=http://127.0.0.1:7001
|
||||||
|
|
||||||
|
# 验证登录
|
||||||
|
npm whoami --registry=http://127.0.0.1:7001
|
||||||
|
```
|
||||||
|
|
||||||
|
发包
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm publish --registry=http://127.0.0.1:7001
|
||||||
|
```
|
||||||
|
|
||||||
### 单元测试
|
### 单元测试
|
||||||
|
|
||||||
MySQL
|
MySQL
|
||||||
|
|||||||
37
app/common/EnvUtil.ts
Normal file
37
app/common/EnvUtil.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
export type ValueType = 'string' | 'boolean' | 'number';
|
||||||
|
|
||||||
|
export function env(key: string, valueType: ValueType, defaultValue: string): string;
|
||||||
|
export function env(key: string, valueType: ValueType, defaultValue: boolean): boolean;
|
||||||
|
export function env(key: string, valueType: ValueType, defaultValue: number): number;
|
||||||
|
export function env(key: string, valueType: ValueType, defaultValue: string | boolean | number): string | boolean | number {
|
||||||
|
const value = process.env[key];
|
||||||
|
if (value === undefined) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueType === 'string') {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueType === 'boolean') {
|
||||||
|
let booleanValue = false;
|
||||||
|
if (value === 'true' || value === '1') {
|
||||||
|
booleanValue = true;
|
||||||
|
} else if (value === 'false' || value === '0') {
|
||||||
|
booleanValue = false;
|
||||||
|
} else {
|
||||||
|
throw new TypeError(`Invalid boolean value: ${value} on process.env.${key}`);
|
||||||
|
}
|
||||||
|
return booleanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueType === 'number') {
|
||||||
|
const numberValue = Number(value);
|
||||||
|
if (isNaN(numberValue)) {
|
||||||
|
throw new TypeError(`Invalid number value: ${value} on process.env.${key}`);
|
||||||
|
}
|
||||||
|
return numberValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new TypeError(`Invalid value type: ${valueType}`);
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import { strict as assert } from 'node:assert';
|
import { strict as assert } from 'node:assert';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { join } from 'node:path';
|
import { join } from 'node:path';
|
||||||
import { EggAppConfig, PowerPartial } from 'egg';
|
import { EggAppConfig, PowerPartial, Context } from 'egg';
|
||||||
import OSSClient from 'oss-cnpm';
|
import OSSClient from 'oss-cnpm';
|
||||||
import { patchAjv } from '../app/port/typebox';
|
import { patchAjv } from '../app/port/typebox';
|
||||||
import { ChangesStreamMode, NOT_IMPLEMENTED_PATH, SyncDeleteMode, SyncMode } from '../app/common/constants';
|
import { ChangesStreamMode, NOT_IMPLEMENTED_PATH, SyncDeleteMode, SyncMode } from '../app/common/constants';
|
||||||
|
import { env } from '../app/common/EnvUtil';
|
||||||
import type { CnpmcoreConfig } from '../app/port/config';
|
import type { CnpmcoreConfig } from '../app/port/config';
|
||||||
import { database } from './database';
|
import { database } from './database';
|
||||||
|
|
||||||
@@ -12,8 +13,8 @@ export const cnpmcoreConfig: CnpmcoreConfig = {
|
|||||||
name: 'cnpm',
|
name: 'cnpm',
|
||||||
hookEnable: false,
|
hookEnable: false,
|
||||||
hooksLimit: 20,
|
hooksLimit: 20,
|
||||||
sourceRegistry: 'https://registry.npmjs.org',
|
sourceRegistry: env('CNPMCORE_CONFIG_SOURCE_REGISTRY', 'string', 'https://registry.npmjs.org'),
|
||||||
sourceRegistryIsCNpm: false,
|
sourceRegistryIsCNpm: env('CNPMCORE_CONFIG_SOURCE_REGISTRY_IS_CNPM', 'boolean', false),
|
||||||
syncUpstreamFirst: false,
|
syncUpstreamFirst: false,
|
||||||
sourceRegistrySyncTimeout: 180000,
|
sourceRegistrySyncTimeout: 180000,
|
||||||
taskQueueHighWaterSize: 100,
|
taskQueueHighWaterSize: 100,
|
||||||
@@ -33,7 +34,7 @@ export const cnpmcoreConfig: CnpmcoreConfig = {
|
|||||||
checkChangesStreamInterval: 500,
|
checkChangesStreamInterval: 500,
|
||||||
changesStreamRegistry: 'https://replicate.npmjs.com',
|
changesStreamRegistry: 'https://replicate.npmjs.com',
|
||||||
changesStreamRegistryMode: ChangesStreamMode.streaming,
|
changesStreamRegistryMode: ChangesStreamMode.streaming,
|
||||||
registry: process.env.CNPMCORE_CONFIG_REGISTRY || 'http://localhost:7001',
|
registry: env('CNPMCORE_CONFIG_REGISTRY', 'string', 'http://localhost:7001'),
|
||||||
alwaysAuth: false,
|
alwaysAuth: false,
|
||||||
allowScopes: [
|
allowScopes: [
|
||||||
'@cnpm',
|
'@cnpm',
|
||||||
@@ -45,7 +46,7 @@ export const cnpmcoreConfig: CnpmcoreConfig = {
|
|||||||
admins: {
|
admins: {
|
||||||
cnpmcore_admin: 'admin@cnpmjs.org',
|
cnpmcore_admin: 'admin@cnpmjs.org',
|
||||||
},
|
},
|
||||||
enableWebAuthn: !!process.env.CNPMCORE_CONFIG_ENABLE_WEB_AUTHN,
|
enableWebAuthn: env('CNPMCORE_CONFIG_ENABLE_WEB_AUTHN', 'boolean', false),
|
||||||
enableCDN: false,
|
enableCDN: false,
|
||||||
cdnCacheControlHeader: 'public, max-age=300',
|
cdnCacheControlHeader: 'public, max-age=300',
|
||||||
cdnVaryHeader: 'Accept, Accept-Encoding',
|
cdnVaryHeader: 'Accept, Accept-Encoding',
|
||||||
@@ -57,7 +58,7 @@ export const cnpmcoreConfig: CnpmcoreConfig = {
|
|||||||
enableSyncUnpkgFiles: true,
|
enableSyncUnpkgFiles: true,
|
||||||
enableSyncUnpkgFilesWhiteList: false,
|
enableSyncUnpkgFilesWhiteList: false,
|
||||||
strictSyncSpecivicVersion: false,
|
strictSyncSpecivicVersion: false,
|
||||||
enableElasticsearch: !!process.env.CNPMCORE_CONFIG_ENABLE_ES,
|
enableElasticsearch: env('CNPMCORE_CONFIG_ENABLE_ES', 'boolean', false),
|
||||||
elasticsearchIndex: 'cnpmcore_packages',
|
elasticsearchIndex: 'cnpmcore_packages',
|
||||||
strictValidateTarballPkg: false,
|
strictValidateTarballPkg: false,
|
||||||
strictValidatePackageDeps: false,
|
strictValidatePackageDeps: false,
|
||||||
@@ -69,14 +70,14 @@ export const cnpmcoreConfig: CnpmcoreConfig = {
|
|||||||
export default (appInfo: EggAppConfig) => {
|
export default (appInfo: EggAppConfig) => {
|
||||||
const config = {} as PowerPartial<EggAppConfig>;
|
const config = {} as PowerPartial<EggAppConfig>;
|
||||||
|
|
||||||
config.keys = process.env.CNPMCORE_EGG_KEYS || randomUUID();
|
config.keys = env('CNPMCORE_EGG_KEYS', 'string', randomUUID());
|
||||||
config.cnpmcore = cnpmcoreConfig;
|
config.cnpmcore = cnpmcoreConfig;
|
||||||
|
|
||||||
// override config from framework / plugin
|
// override config from framework / plugin
|
||||||
config.dataDir = process.env.CNPMCORE_DATA_DIR || join(appInfo.root, '.cnpmcore');
|
config.dataDir = env('CNPMCORE_DATA_DIR', 'string', join(appInfo.root, '.cnpmcore'));
|
||||||
config.orm = {
|
config.orm = {
|
||||||
...database,
|
...database,
|
||||||
database: database.name ?? 'cnpmcore',
|
database: database.name || 'cnpmcore',
|
||||||
charset: 'utf8mb4',
|
charset: 'utf8mb4',
|
||||||
logger: {
|
logger: {
|
||||||
// https://github.com/cyjake/leoric/blob/master/docs/zh/logging.md#logqueryerror
|
// https://github.com/cyjake/leoric/blob/master/docs/zh/logging.md#logqueryerror
|
||||||
@@ -90,10 +91,10 @@ export default (appInfo: EggAppConfig) => {
|
|||||||
|
|
||||||
config.redis = {
|
config.redis = {
|
||||||
client: {
|
client: {
|
||||||
port: Number(process.env.CNPMCORE_REDIS_PORT || 6379),
|
port: env('CNPMCORE_REDIS_PORT', 'number', 6379),
|
||||||
host: process.env.CNPMCORE_REDIS_HOST || '127.0.0.1',
|
host: env('CNPMCORE_REDIS_HOST', 'string', '127.0.0.1'),
|
||||||
password: process.env.CNPMCORE_REDIS_PASSWORD || '',
|
password: env('CNPMCORE_REDIS_PASSWORD', 'string', ''),
|
||||||
db: Number(process.env.CNPMCORE_REDIS_DB || 0),
|
db: env('CNPMCORE_REDIS_DB', 'number', 0),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ export default (appInfo: EggAppConfig) => {
|
|||||||
|
|
||||||
config.cors = {
|
config.cors = {
|
||||||
// allow all domains
|
// allow all domains
|
||||||
origin: (ctx): string => {
|
origin: (ctx: Context): string => {
|
||||||
return ctx.get('Origin');
|
return ctx.get('Origin');
|
||||||
},
|
},
|
||||||
credentials: true,
|
credentials: true,
|
||||||
@@ -115,59 +116,61 @@ export default (appInfo: EggAppConfig) => {
|
|||||||
|
|
||||||
config.nfs = {
|
config.nfs = {
|
||||||
client: null,
|
client: null,
|
||||||
dir: process.env.CNPMCORE_NFS_DIR || join(config.dataDir, 'nfs'),
|
dir: env('CNPMCORE_NFS_DIR', 'string', join(config.dataDir, 'nfs')),
|
||||||
};
|
};
|
||||||
/* c8 ignore next 17 */
|
/* c8 ignore next 17 */
|
||||||
// enable oss nfs store by env values
|
// enable oss nfs store by env values
|
||||||
if (process.env.CNPMCORE_NFS_TYPE === 'oss') {
|
const nfsType = env('CNPMCORE_NFS_TYPE', 'string', '');
|
||||||
assert(process.env.CNPMCORE_NFS_OSS_BUCKET, 'require env CNPMCORE_NFS_OSS_BUCKET');
|
if (nfsType === 'oss') {
|
||||||
assert(process.env.CNPMCORE_NFS_OSS_ENDPOINT, 'require env CNPMCORE_NFS_OSS_ENDPOINT');
|
const ossConfig = {
|
||||||
assert(process.env.CNPMCORE_NFS_OSS_ID, 'require env CNPMCORE_NFS_OSS_ID');
|
cdnBaseUrl: env('CNPMCORE_NFS_OSS_CDN', 'string', ''),
|
||||||
assert(process.env.CNPMCORE_NFS_OSS_SECRET, 'require env CNPMCORE_NFS_OSS_SECRET');
|
endpoint: env('CNPMCORE_NFS_OSS_ENDPOINT', 'string', ''),
|
||||||
config.nfs.client = new OSSClient({
|
bucket: env('CNPMCORE_NFS_OSS_BUCKET', 'string', ''),
|
||||||
cdnBaseUrl: process.env.CNPMCORE_NFS_OSS_CDN,
|
accessKeyId: env('CNPMCORE_NFS_OSS_ID', 'string', ''),
|
||||||
endpoint: process.env.CNPMCORE_NFS_OSS_ENDPOINT,
|
accessKeySecret: env('CNPMCORE_NFS_OSS_SECRET', 'string', ''),
|
||||||
bucket: process.env.CNPMCORE_NFS_OSS_BUCKET,
|
|
||||||
accessKeyId: process.env.CNPMCORE_NFS_OSS_ID,
|
|
||||||
accessKeySecret: process.env.CNPMCORE_NFS_OSS_SECRET,
|
|
||||||
defaultHeaders: {
|
defaultHeaders: {
|
||||||
'Cache-Control': 'max-age=0, s-maxage=60',
|
'Cache-Control': 'max-age=0, s-maxage=60',
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
} else if (process.env.CNPMCORE_NFS_TYPE === 's3') {
|
assert(ossConfig.cdnBaseUrl, 'require env CNPMCORE_NFS_OSS_BUCKET');
|
||||||
assert(process.env.CNPMCORE_NFS_S3_CLIENT_ENDPOINT, 'require env CNPMCORE_NFS_S3_CLIENT_ENDPOINT');
|
assert(ossConfig.endpoint, 'require env CNPMCORE_NFS_OSS_ENDPOINT');
|
||||||
assert(process.env.CNPMCORE_NFS_S3_CLIENT_ID, 'require env CNPMCORE_NFS_S3_CLIENT_ID');
|
assert(ossConfig.accessKeyId, 'require env CNPMCORE_NFS_OSS_ID');
|
||||||
assert(process.env.CNPMCORE_NFS_S3_CLIENT_SECRET, 'require env CNPMCORE_NFS_S3_CLIENT_SECRET');
|
assert(ossConfig.accessKeySecret, 'require env CNPMCORE_NFS_OSS_SECRET');
|
||||||
assert(process.env.CNPMCORE_NFS_S3_CLIENT_BUCKET, 'require env CNPMCORE_NFS_S3_CLIENT_BUCKET');
|
config.nfs.client = new OSSClient(ossConfig);
|
||||||
|
} else if (nfsType === 's3') {
|
||||||
|
const s3Config = {
|
||||||
|
region: env('CNPMCORE_NFS_S3_CLIENT_REGION', 'string', 'default'),
|
||||||
|
endpoint: env('CNPMCORE_NFS_S3_CLIENT_ENDPOINT', 'string', ''),
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: env('CNPMCORE_NFS_S3_CLIENT_ID', 'string', ''),
|
||||||
|
secretAccessKey: env('CNPMCORE_NFS_S3_CLIENT_SECRET', 'string', ''),
|
||||||
|
},
|
||||||
|
bucket: env('CNPMCORE_NFS_S3_CLIENT_BUCKET', 'string', ''),
|
||||||
|
forcePathStyle: env('CNPMCORE_NFS_S3_CLIENT_FORCE_PATH_STYLE', 'boolean', false),
|
||||||
|
disableURL: env('CNPMCORE_NFS_S3_CLIENT_DISABLE_URL', 'boolean', false),
|
||||||
|
};
|
||||||
|
assert(s3Config.endpoint, 'require env CNPMCORE_NFS_S3_CLIENT_ENDPOINT');
|
||||||
|
assert(s3Config.credentials.accessKeyId, 'require env CNPMCORE_NFS_S3_CLIENT_ID');
|
||||||
|
assert(s3Config.credentials.secretAccessKey, 'require env CNPMCORE_NFS_S3_CLIENT_SECRET');
|
||||||
|
assert(s3Config.bucket, 'require env CNPMCORE_NFS_S3_CLIENT_BUCKET');
|
||||||
|
// TODO(@fengmk2): should change to use import to support esm
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const S3Client = require('s3-cnpmcore');
|
const S3Client = require('s3-cnpmcore');
|
||||||
config.nfs.client = new S3Client({
|
config.nfs.client = new S3Client(s3Config);
|
||||||
region: process.env.CNPMCORE_NFS_S3_CLIENT_REGION || 'default',
|
|
||||||
endpoint: process.env.CNPMCORE_NFS_S3_CLIENT_ENDPOINT,
|
|
||||||
credentials: {
|
|
||||||
accessKeyId: process.env.CNPMCORE_NFS_S3_CLIENT_ID,
|
|
||||||
secretAccessKey: process.env.CNPMCORE_NFS_S3_CLIENT_SECRET,
|
|
||||||
},
|
|
||||||
bucket: process.env.CNPMCORE_NFS_S3_CLIENT_BUCKET,
|
|
||||||
forcePathStyle: !!process.env.CNPMCORE_NFS_S3_CLIENT_FORCE_PATH_STYLE,
|
|
||||||
disableURL: !!process.env.CNPMCORE_NFS_S3_CLIENT_DISABLE_URL,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.logger = {
|
config.logger = {
|
||||||
enablePerformanceTimer: true,
|
enablePerformanceTimer: true,
|
||||||
enableFastContextLogger: true,
|
enableFastContextLogger: true,
|
||||||
appLogName: process.env.CNPMCORE_APP_LOG_NAME || `${appInfo.name}-web.log`,
|
appLogName: env('CNPMCORE_APP_LOG_NAME', 'string', `${appInfo.name}-web.log`),
|
||||||
coreLogName: process.env.CNPMCORE_CORE_LOG_NAME || 'egg-web.log',
|
coreLogName: env('CNPMCORE_CORE_LOG_NAME', 'string', 'egg-web.log'),
|
||||||
agentLogName: process.env.CNPMCORE_AGENT_LOG_NAME || 'egg-agent.log',
|
agentLogName: env('CNPMCORE_AGENT_LOG_NAME', 'string', 'egg-agent.log'),
|
||||||
errorLogName: process.env.CNPMCORE_ERROR_LOG_NAME || 'common-error.log',
|
errorLogName: env('CNPMCORE_ERROR_LOG_NAME', 'string', 'common-error.log'),
|
||||||
outputJSON: Boolean(process.env.CNPMCORE_LOG_JSON_OUTPUT || false),
|
outputJSON: env('CNPMCORE_LOG_JSON_OUTPUT', 'boolean', false),
|
||||||
};
|
};
|
||||||
if (process.env.CNPMCORE_LOG_DIR) {
|
const logDir = env('CNPMCORE_LOG_DIR', 'string', '');
|
||||||
config.logger.dir = process.env.CNPMCORE_LOG_DIR;
|
if (logDir) {
|
||||||
}
|
config.logger.dir = logDir;
|
||||||
if (process.env.CNPMCORE_LOG_JSON_OUTPUT) {
|
|
||||||
config.logger.outputJSON = Boolean(process.env.CNPMCORE_LOG_JSON_OUTPUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.logrotator = {
|
config.logrotator = {
|
||||||
@@ -207,10 +210,10 @@ export default (appInfo: EggAppConfig) => {
|
|||||||
if (config.cnpmcore.enableElasticsearch) {
|
if (config.cnpmcore.enableElasticsearch) {
|
||||||
config.elasticsearch = {
|
config.elasticsearch = {
|
||||||
client: {
|
client: {
|
||||||
node: process.env.CNPMCORE_CONFIG_ES_CLIENT_NODE,
|
node: env('CNPMCORE_CONFIG_ES_CLIENT_NODE', 'string', ''),
|
||||||
auth: {
|
auth: {
|
||||||
username: process.env.CNPMCORE_CONFIG_ES_CLIENT_AUTH_USERNAME as string,
|
username: env('CNPMCORE_CONFIG_ES_CLIENT_AUTH_USERNAME', 'string', ''),
|
||||||
password: process.env.CNPMCORE_CONFIG_ES_CLIENT_AUTH_PASSWORD as string,
|
password: env('CNPMCORE_CONFIG_ES_CLIENT_AUTH_PASSWORD', 'string', ''),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -218,3 +221,4 @@ export default (appInfo: EggAppConfig) => {
|
|||||||
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default (appInfo: EggAppConfig) => {
|
|||||||
config.dataDir = join(appInfo.root, '.cnpmcore_unittest');
|
config.dataDir = join(appInfo.root, '.cnpmcore_unittest');
|
||||||
|
|
||||||
config.orm = {
|
config.orm = {
|
||||||
database: database.name ?? 'cnpmcore_unittest',
|
database: database.name || 'cnpmcore_unittest',
|
||||||
};
|
};
|
||||||
|
|
||||||
config.nfs = {
|
config.nfs = {
|
||||||
|
|||||||
@@ -1,33 +1,35 @@
|
|||||||
|
import { env } from '../app/common/EnvUtil';
|
||||||
|
|
||||||
export enum DATABASE_TYPE {
|
export enum DATABASE_TYPE {
|
||||||
MySQL = 'MySQL',
|
MySQL = 'MySQL',
|
||||||
PostgreSQL = 'PostgreSQL',
|
PostgreSQL = 'PostgreSQL',
|
||||||
SQLite = 'SQLite',
|
SQLite = 'SQLite',
|
||||||
}
|
}
|
||||||
|
|
||||||
const dbType = process.env.CNPMCORE_DATABASE_TYPE ?? DATABASE_TYPE.MySQL;
|
const dbType = env('CNPMCORE_DATABASE_TYPE', 'string', DATABASE_TYPE.MySQL);
|
||||||
let dbName = process.env.CNPMCORE_DATABASE_NAME;
|
let dbName = env('CNPMCORE_DATABASE_NAME', 'string', '');
|
||||||
let dbHost = process.env.CNPMCORE_DATABASE_HOST;
|
let dbHost = env('CNPMCORE_DATABASE_HOST', 'string', '');
|
||||||
let dbPort = process.env.CNPMCORE_DATABASE_PORT;
|
let dbPort = env('CNPMCORE_DATABASE_PORT', 'number', 0);
|
||||||
let dbUser = process.env.CNPMCORE_DATABASE_USER;
|
let dbUser = env('CNPMCORE_DATABASE_USER', 'string', '');
|
||||||
let dbPassword = process.env.CNPMCORE_DATABASE_PASSWORD;
|
let dbPassword = env('CNPMCORE_DATABASE_PASSWORD', 'string', '');
|
||||||
let dialect = 'mysql';
|
let dialect = 'mysql';
|
||||||
let dbClient = 'mysql2';
|
let dbClient = 'mysql2';
|
||||||
if (dbType === DATABASE_TYPE.MySQL) {
|
if (dbType === DATABASE_TYPE.MySQL) {
|
||||||
// Compatible mysql configurations
|
// Compatible mysql configurations
|
||||||
dbName = dbName ?? process.env.CNPMCORE_MYSQL_DATABASE ?? process.env.MYSQL_DATABASE;
|
dbName = dbName || env('CNPMCORE_MYSQL_DATABASE', 'string', '') || env('MYSQL_DATABASE', 'string', '') || '';
|
||||||
dbHost = dbHost ?? process.env.CNPMCORE_MYSQL_HOST ?? process.env.MYSQL_HOST ?? '127.0.0.1';
|
dbHost = dbHost || env('CNPMCORE_MYSQL_HOST', 'string', '') || env('MYSQL_HOST', 'string', '') || '127.0.0.1';
|
||||||
dbPort = dbPort ?? process.env.CNPMCORE_MYSQL_PORT ?? process.env.MYSQL_PORT ?? '3306';
|
dbPort = dbPort || env('CNPMCORE_MYSQL_PORT', 'number', 0) || env('MYSQL_PORT', 'number', 0) || 3306;
|
||||||
dbUser = dbUser ?? process.env.CNPMCORE_MYSQL_USER ?? process.env.MYSQL_USER ?? 'root';
|
dbUser = dbUser || env('CNPMCORE_MYSQL_USER', 'string', '') || env('MYSQL_USER', 'string', '') || 'root';
|
||||||
dbPassword = dbPassword ?? process.env.CNPMCORE_MYSQL_PASSWORD ?? process.env.MYSQL_PASSWORD;
|
dbPassword = dbPassword || env('CNPMCORE_MYSQL_PASSWORD', 'string', '') || env('MYSQL_PASSWORD', 'string', '');
|
||||||
} else if (dbType === DATABASE_TYPE.PostgreSQL) {
|
} else if (dbType === DATABASE_TYPE.PostgreSQL) {
|
||||||
dbClient = 'pg';
|
dbClient = 'pg';
|
||||||
dialect = 'postgres';
|
dialect = 'postgres';
|
||||||
dbHost = dbHost ?? process.env.CNPMCORE_POSTGRES_HOST ?? process.env.POSTGRES_HOST;
|
dbHost = dbHost || env('CNPMCORE_POSTGRES_HOST', 'string', '') || env('POSTGRES_HOST', 'string', '') || '127.0.0.1';
|
||||||
dbPort = dbPort ?? process.env.CNPMCORE_POSTGRES_PORT ?? process.env.POSTGRES_PORT ?? '5432';
|
dbPort = dbPort || env('CNPMCORE_POSTGRES_PORT', 'number', 0) || env('POSTGRES_PORT', 'number', 0) || 5432;
|
||||||
dbUser = dbUser ?? process.env.CNPMCORE_POSTGRES_USER ?? process.env.POSTGRES_USER;
|
dbUser = dbUser || env('CNPMCORE_POSTGRES_USER', 'string', '') || env('POSTGRES_USER', 'string', '') || 'postgres';
|
||||||
dbPassword = dbPassword ?? process.env.CNPMCORE_POSTGRES_PASSWORD ?? process.env.POSTGRES_PASSWORD;
|
dbPassword = dbPassword || env('CNPMCORE_POSTGRES_PASSWORD', 'string', '') || env('POSTGRES_PASSWORD', 'string', '') || 'postgres';
|
||||||
} else if (dbType === DATABASE_TYPE.SQLite) {
|
} else if (dbType === DATABASE_TYPE.SQLite) {
|
||||||
// TODO
|
// TODO: Implement SQLite
|
||||||
dbClient = 'sqlite';
|
dbClient = 'sqlite';
|
||||||
dialect = 'sqlite';
|
dialect = 'sqlite';
|
||||||
}
|
}
|
||||||
|
|||||||
61
docker-compose-postgres.yml
Normal file
61
docker-compose-postgres.yml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
name: cnpmcore_dev_services_postgres
|
||||||
|
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
image: redis:6-alpine
|
||||||
|
# command: redis-server --appendonly yes --requirepass cnpm
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- cnpm-redis:/data
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
|
networks:
|
||||||
|
- cnpm-postgres
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
image: postgres:17
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
networks:
|
||||||
|
- cnpm-postgres
|
||||||
|
volumes:
|
||||||
|
- cnpm-postgres:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
# https://github.com/khezen/compose-postgres/blob/master/docker-compose.yml
|
||||||
|
pgadmin:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
image: dpage/pgadmin4
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
||||||
|
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org}
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
|
||||||
|
PGADMIN_CONFIG_SERVER_MODE: 'False'
|
||||||
|
volumes:
|
||||||
|
- cnpm-pgadmin:/var/lib/pgadmin
|
||||||
|
ports:
|
||||||
|
- 8888:80
|
||||||
|
networks:
|
||||||
|
- cnpm-postgres
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
cnpm-redis:
|
||||||
|
cnpm-postgres:
|
||||||
|
cnpm-pgadmin:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
cnpm-postgres:
|
||||||
|
name: cnpm-postgres
|
||||||
|
driver: bridge
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
version: '3.6'
|
name: cnpmcore_dev_services_mysql
|
||||||
|
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
image: redis:6-alpine
|
image: redis:6-alpine
|
||||||
# command: redis-server --appendonly yes --requirepass cnpm
|
# command: redis-server --appendonly yes --requirepass cnpm
|
||||||
restart: always
|
restart: always
|
||||||
@@ -9,41 +12,42 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
networks:
|
networks:
|
||||||
- cnpm
|
- cnpm-mysql
|
||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
image: mariadb
|
env_file:
|
||||||
|
- .env
|
||||||
|
image: mysql:9
|
||||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD:
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-}
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
|
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
|
||||||
# MYSQL_DATABASE: 'cnpmcore_unittest'
|
MYSQL_DATABASE: ${MYSQL_DATABASE:-cnpmcore}
|
||||||
MYSQL_USER: user
|
|
||||||
MYSQL_PASSWORD: pass
|
|
||||||
volumes:
|
volumes:
|
||||||
- cnpm-mysql:/var/lib/mysql
|
- cnpm-mysql:/var/lib/mysql
|
||||||
# - ./conf.d/mysql/:/etc/mysql/conf.d
|
|
||||||
# - ./init.d/mysql/:/docker-entrypoint-initdb.d
|
|
||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
networks:
|
networks:
|
||||||
- cnpm
|
- cnpm-mysql
|
||||||
|
|
||||||
# database explorer
|
# database explorer
|
||||||
phpmyadmin:
|
phpmyadmin:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
image: phpmyadmin
|
image: phpmyadmin
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD:
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-}
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
|
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
|
||||||
MYSQL_USER: user
|
MYSQL_DATABASE: ${MYSQL_DATABASE:-cnpmcore}
|
||||||
MYSQL_PASSWORD: pass
|
# MYSQL_USER: ${MYSQL_USER:-user}
|
||||||
|
# MYSQL_PASSWORD: ${MYSQL_PASSWORD:-pass}
|
||||||
PMA_HOST: 'mysql'
|
PMA_HOST: 'mysql'
|
||||||
ports:
|
ports:
|
||||||
- 8080:80
|
- 8080:80
|
||||||
networks:
|
networks:
|
||||||
- cnpm
|
- cnpm-mysql
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
- mysql
|
||||||
|
|
||||||
@@ -51,8 +55,7 @@ volumes:
|
|||||||
cnpm-redis:
|
cnpm-redis:
|
||||||
cnpm-mysql:
|
cnpm-mysql:
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
cnpm:
|
cnpm-mysql:
|
||||||
name: cnpm
|
name: cnpm-mysql
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# set -ex
|
||||||
|
|
||||||
# read variables from environment
|
# read variables from environment
|
||||||
db_host=${CNPMCORE_DATABASE_HOST:-127.0.0.1}
|
db_host=${CNPMCORE_DATABASE_HOST:-127.0.0.1}
|
||||||
db_port=${CNPMCORE_DATABASE_PORT:-3306}
|
db_port=${CNPMCORE_DATABASE_PORT:-3306}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
# set -ex
|
# set -ex
|
||||||
|
|
||||||
# read variables from environment
|
# read variables from environment
|
||||||
db_host=${POSTGRES_HOST:-}
|
db_host=${POSTGRES_HOST:-127.0.0.1}
|
||||||
db_port=${POSTGRES_PORT:-5432}
|
db_port=${POSTGRES_PORT:-5432}
|
||||||
db_username=${POSTGRES_USER:-}
|
db_username=${POSTGRES_USER:-postgres}
|
||||||
db_password=${POSTGRES_PASSWORD:-} # default to empty password
|
db_password=${POSTGRES_PASSWORD:-postgres} # default to empty password
|
||||||
db_name=${CNPMCORE_DATABASE_NAME:-cnpmcore_unittest}
|
db_name=${CNPMCORE_DATABASE_NAME:-cnpmcore_unittest}
|
||||||
|
|
||||||
# prepare PostgreSQL param
|
# prepare PostgreSQL param
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export class TestUtil {
|
|||||||
static getDatabaseConfig() {
|
static getDatabaseConfig() {
|
||||||
return {
|
return {
|
||||||
...database,
|
...database,
|
||||||
database: database.name ?? 'cnpmcore_unittest',
|
database: database.name || 'cnpmcore_unittest',
|
||||||
multipleStatements: true,
|
multipleStatements: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user