feat: change env
This commit is contained in:
parent
29d0709083
commit
f4af7d5c7f
18
.env.example
Normal file
18
.env.example
Normal file
@ -0,0 +1,18 @@
|
||||
# 代理配置
|
||||
PROXY_PORT=3005
|
||||
PROXY_DOMAIN=localhost
|
||||
PROXY_RESOURCES=http://localhost:9000/resources
|
||||
PROXY_ALLOWED_ORIGINS=localhost,xiongxiao.me,zxj.im
|
||||
PROXY_HOME=/ai/chat
|
||||
|
||||
# 后台代理
|
||||
API_HOST=http://localhost:4005
|
||||
API_PATH=/api/router
|
||||
|
||||
# Minio 配置
|
||||
MINIO_ENDPOINT=localhost
|
||||
MINIO_PORT=9000
|
||||
MINIO_BUCKET_NAME=resources
|
||||
MINIO_USE_SSL=false
|
||||
MINIO_ACCESS_KEY=username
|
||||
MINIO_SECRET_KEY=****
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -16,3 +16,7 @@ proxy-upload/*
|
||||
proxy-upload/.gitkeep
|
||||
|
||||
.env
|
||||
.env*
|
||||
!.env.example
|
||||
|
||||
pack-dist
|
@ -4,6 +4,7 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"basename": "/root/page-proxy",
|
||||
"app": {
|
||||
"key": "page-proxy",
|
||||
"entry": "dist/app.mjs",
|
||||
@ -22,7 +23,7 @@
|
||||
"build": "rimraf dist && rollup -c",
|
||||
"start": "pm2 start dist/app.mjs --name page-proxy",
|
||||
"release": "node ./scripts/release/index.mjs",
|
||||
"deploy": "envision switch root && envision pack -p -u",
|
||||
"deploy": "envision pack -p -u",
|
||||
"pub": "npm run build && npm run deploy",
|
||||
"ssl": "ssh -L 6379:localhost:6379 light"
|
||||
},
|
||||
@ -40,7 +41,7 @@
|
||||
"concurrently": "^9.1.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"nodemon": "^3.1.9",
|
||||
"rollup": "^4.36.0",
|
||||
"rollup": "^4.37.0",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useConfig } from '@kevisual/use-config';
|
||||
import { useConfig } from '@kevisual/use-config/env';
|
||||
import { useFileStore } from '@kevisual/use-config/file-store';
|
||||
export const fileStore = useFileStore('proxy-upload');
|
||||
|
||||
@ -37,7 +37,7 @@ type ConfigType = {
|
||||
* allow origin xiongxiao.me zxj.im silkyai.cn
|
||||
* 允许跨域访问的地址
|
||||
*/
|
||||
allowOrigin: string[];
|
||||
allowedOrigin: string[];
|
||||
|
||||
/**
|
||||
* home 不在代理范围内跳转到的地址
|
||||
@ -46,4 +46,25 @@ type ConfigType = {
|
||||
};
|
||||
};
|
||||
|
||||
export const config = useConfig<ConfigType>();
|
||||
// export const config = useConfig();
|
||||
export const envConfig = useConfig() as any;
|
||||
export const config: ConfigType = {
|
||||
api: {
|
||||
host: envConfig.API_HOST,
|
||||
path: envConfig.API_PATH,
|
||||
port: envConfig.PROXY_PORT,
|
||||
},
|
||||
apiList: [
|
||||
{
|
||||
path: '/api',
|
||||
target: envConfig.API_HOST,
|
||||
},
|
||||
],
|
||||
proxy: {
|
||||
port: envConfig.PROXY_PORT,
|
||||
domain: envConfig.PROXY_DOMAIN,
|
||||
resources: envConfig.PROXY_RESOURCES,
|
||||
allowedOrigin: (envConfig.PROXY_ALLOWED_ORIGINS as string)?.split(',') || [],
|
||||
home: envConfig.PROXY_HOME,
|
||||
},
|
||||
};
|
||||
|
@ -129,6 +129,17 @@ export class UserApp {
|
||||
app: fetchData.key,
|
||||
};
|
||||
redis.set(key, data.user + ':' + data.app, 'EX', 60 * 60 * 24 * 7); // 7天
|
||||
|
||||
const userDomainApp = 'user:domain:app:' + data.user + ':' + data.app;
|
||||
|
||||
const domainKeys = await redis.get(userDomainApp);
|
||||
let domainKeysList = domainKeys ? JSON.parse(domainKeys) : [];
|
||||
domainKeysList.push(domain);
|
||||
const uniq = (arr: string[]) => {
|
||||
return [...new Set(arr)];
|
||||
};
|
||||
domainKeysList = uniq(domainKeysList);
|
||||
await redis.set(userDomainApp, JSON.stringify(domainKeysList), 'EX', 60 * 60 * 24 * 7); // 7天
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
@ -282,6 +293,16 @@ export class UserApp {
|
||||
await redis.del('user:app:exist:' + app + ':' + user);
|
||||
await redis.del('user:app:set:' + app + ':' + user);
|
||||
await redis.del('user:app:status:' + app + ':' + user);
|
||||
const userDomainApp = 'user:domain:app:' + user + ':' + app;
|
||||
const domainKeys = await redis.get(userDomainApp);
|
||||
if (domainKeys) {
|
||||
const domainKeysList = JSON.parse(domainKeys);
|
||||
domainKeysList.forEach(async (domain: string) => {
|
||||
await redis.del('domain:' + domain);
|
||||
});
|
||||
}
|
||||
await redis.del(userDomainApp);
|
||||
|
||||
// 删除所有文件
|
||||
deleteUserAppFiles(user, app);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { getDNS, isLocalhost } from '@/utils/dns.ts';
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
import { UserApp } from './get-user-app.ts';
|
||||
import { config, fileStore } from '../module/config.ts';
|
||||
import path from 'path';
|
||||
@ -8,12 +7,11 @@ import fs from 'fs';
|
||||
import { getContentType } from './get-content-type.ts';
|
||||
import { createRefreshHtml } from './html/create-refresh-html.ts';
|
||||
import { fileProxy } from './proxy/file-proxy.ts';
|
||||
import net from 'net';
|
||||
import { httpProxy } from './proxy/http-proxy.ts';
|
||||
|
||||
const api = config?.api || { host: 'kevisual.xiongxiao.me', path: '/api/router' };
|
||||
const domain = config?.proxy?.domain || 'kevisual.xiongxiao.me';
|
||||
const allowedOrigins = config?.proxy?.allowOrigin || [];
|
||||
const allowedOrigins = config?.proxy?.allowedOrigin || [];
|
||||
const home = config?.proxy?.home || '/ai/chat';
|
||||
|
||||
const noProxyUrl = ['/', '/favicon.ico'];
|
||||
@ -43,6 +41,9 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
|
||||
}
|
||||
// 提取req的headers中的非HOST的header
|
||||
const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host');
|
||||
const host = req.headers['host'];
|
||||
console.log('host', host);
|
||||
console.log('headers', headers);
|
||||
headers.forEach((item) => {
|
||||
header[item] = req.headers[item];
|
||||
});
|
||||
@ -96,6 +97,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
|
||||
|
||||
let user, app;
|
||||
let domainApp = false;
|
||||
console.log('dns.hostName', dns.hostName, domain);
|
||||
if (isLocalhost(dns.hostName)) {
|
||||
// 本地开发环境 测试
|
||||
// user = 'root';
|
||||
@ -223,6 +225,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
|
||||
// console.log('isExist', isExist);
|
||||
if (!appFile) {
|
||||
const [indexFilePath, etag] = indexFile.split('||');
|
||||
// console.log('indexFilePath', indexFile, path.join(fileStore, indexFilePath));
|
||||
const contentType = getContentType(indexFilePath);
|
||||
const isHTML = contentType.includes('html');
|
||||
const filePath = path.join(fileStore, indexFilePath);
|
||||
|
@ -1,26 +1,21 @@
|
||||
import { Client, ClientOptions } from 'minio';
|
||||
import { useConfig } from '@kevisual/use-config';
|
||||
|
||||
type MinioConfig = {
|
||||
minio: ClientOptions & { bucketName: string };
|
||||
import { Client } from 'minio';
|
||||
import { useConfig } from '@kevisual/use-config/env';
|
||||
const config = useConfig();
|
||||
const minioConfig = {
|
||||
bucketName: config.MINIO_BUCKET_NAME,
|
||||
endPoint: config.MINIO_ENDPOINT,
|
||||
port: config.MINIO_PORT,
|
||||
useSSL: config.MINIO_USE_SSL === 'true',
|
||||
accessKey: config.MINIO_ACCESS_KEY,
|
||||
secretKey: config.MINIO_SECRET_KEY,
|
||||
};
|
||||
const config = useConfig<MinioConfig>();
|
||||
const { bucketName, ...minioRest } = config.minio;
|
||||
const { port, endPoint, useSSL } = minioRest;
|
||||
// const config = useConfig<MinioConfig>();
|
||||
const { port, endPoint, useSSL } = minioConfig;
|
||||
export const minioUrl = `http${useSSL ? 's' : ''}://${endPoint}:${port || 9000}`;
|
||||
export const minioResources = `${minioUrl}/resources`;
|
||||
export const minioClient = new Client(minioRest);
|
||||
export { bucketName };
|
||||
export const minioClient = new Client(minioConfig);
|
||||
export const bucketName = minioConfig.bucketName;
|
||||
|
||||
if (!minioClient) {
|
||||
throw new Error('Minio client not initialized');
|
||||
}
|
||||
// 验证权限
|
||||
// (async () => {
|
||||
// const bucketExists = await minioClient.bucketExists(bucketName);
|
||||
// if (!bucketExists) {
|
||||
// await minioClient.makeBucket(bucketName);
|
||||
// }
|
||||
// const res = await minioClient.putObject(bucketName, 'private/test/a.b', 'test');
|
||||
// console.log('minio putObject', res);
|
||||
|
||||
// })();
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { Redis } from 'ioredis';
|
||||
import { useConfig } from '@kevisual/use-config';
|
||||
import { useContextKey } from '@kevisual/use-config/context';
|
||||
console.log(process.env.REDIS_HOST);
|
||||
|
||||
const config = useConfig<{
|
||||
redis: ConstructorParameters<typeof Redis>;
|
||||
}>();
|
||||
const redisConfig = {
|
||||
host: 'localhost', // Redis 服务器的主机名或 IP 地址
|
||||
port: 6379, // Redis 服务器的端口号
|
||||
// password: 'your_password', // Redis 的密码 (如果有)
|
||||
};
|
||||
const init = () => {
|
||||
return new Redis({
|
||||
host: 'localhost', // Redis 服务器的主机名或 IP 地址
|
||||
@ -17,7 +19,7 @@ const init = () => {
|
||||
return Math.min(times * 50, 2000); // 每次重试时延迟增加
|
||||
},
|
||||
maxRetriesPerRequest: null, // 允许请求重试的次数 (如果需要无限次重试)
|
||||
...config.redis,
|
||||
...redisConfig,
|
||||
});
|
||||
};
|
||||
// 配置 Redis 连接
|
||||
|
@ -1,19 +1,15 @@
|
||||
import { useConfig } from '@kevisual/use-config';
|
||||
import { Sequelize } from 'sequelize';
|
||||
import { useContextKey, useContext } from '@kevisual/use-config/context';
|
||||
import { useConfig } from '@kevisual/use-config/env';
|
||||
const config = useConfig();
|
||||
|
||||
type PostgresConfig = {
|
||||
postgres: {
|
||||
username: string;
|
||||
password: string;
|
||||
host: string;
|
||||
port: number;
|
||||
database: string;
|
||||
};
|
||||
const postgresConfig = {
|
||||
username: config.POSTGRES_USERNAME,
|
||||
password: config.POSTGRES_PASSWORD,
|
||||
host: config.POSTGRES_HOST,
|
||||
port: config.POSTGRES_PORT,
|
||||
database: config.POSTGRES_DATABASE,
|
||||
};
|
||||
const config = useConfig<PostgresConfig>();
|
||||
|
||||
const postgresConfig = config.postgres;
|
||||
|
||||
if (!postgresConfig) {
|
||||
console.error('postgres config is required');
|
||||
|
@ -23,14 +23,18 @@ app
|
||||
path: 'app',
|
||||
key: 'list',
|
||||
middleware: ['auth-admin'],
|
||||
description: '获取应用列表',
|
||||
isDebug: true,
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const keys = await redis.keys('user:app:*');
|
||||
// const keys = await redis.keys('user:app:exist:*');
|
||||
// const data = await redis.mget(...keys);
|
||||
const domainList = await redis.keys('domain:*');
|
||||
ctx.body = {
|
||||
// data: data,
|
||||
keys,
|
||||
domainList,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { useConfig } from '@kevisual/use-config/env';
|
||||
|
||||
console.log(useConfig());
|
||||
|
||||
console.log(process.env);
|
22
src/scripts/query-config.ts
Normal file
22
src/scripts/query-config.ts
Normal file
@ -0,0 +1,22 @@
|
||||
const baseURL = 'https://kevisual.xiongxiao.me/api/router';
|
||||
export const fetchCnfig = async () => {
|
||||
const res = await fetch(baseURL, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
path: 'app',
|
||||
key: 'getApp',
|
||||
data: {
|
||||
user: 'root',
|
||||
key: 'code-center',
|
||||
},
|
||||
}),
|
||||
});
|
||||
return res.json();
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const res = await fetchCnfig();
|
||||
// console.log(res);
|
||||
console.log(JSON.stringify(res, null, 2));
|
||||
};
|
||||
main();
|
Loading…
x
Reference in New Issue
Block a user