chore(deploy): add same-host staging stack next to production
dev deploys to /opt/dukang-staging (819x, *-test domains); main deploys to production. Staging uses full Mock with shared WeChat app ids. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,19 +5,33 @@ import { resolve } from 'path';
|
||||
/**
|
||||
* 环境变量加载策略(后加载的文件覆盖先前的同名键):
|
||||
*
|
||||
* - 本地开发:仅 `.env` + `.env.local`
|
||||
* `.env.development` 仅作参考模板,不自动加载
|
||||
* - local:`.env` + `.env.local`
|
||||
* - staging:`.env.staging` + `.env.staging.local`(同机测试栈,APP_ENV=staging)
|
||||
* - production:`.env.production` + `.env.production.local`
|
||||
*
|
||||
* - 服务器(NODE_ENV=production):仅 `.env.production` + `.env.production.local`
|
||||
* 不使用 `.env`,避免与本地开发配置混淆
|
||||
* 判定:优先 `APP_ENV`;未设置时 `NODE_ENV=production` → production,否则 local。
|
||||
* staging 在 PM2 中仍设 `NODE_ENV=production`(构建产物),靠 `APP_ENV=staging` 区分。
|
||||
*/
|
||||
const apiRoot = resolve(__dirname, '..');
|
||||
const nodeEnv = process.env.NODE_ENV ?? 'development';
|
||||
const isProduction = nodeEnv === 'production';
|
||||
|
||||
const layers = isProduction
|
||||
? [resolve(apiRoot, '.env.production'), resolve(apiRoot, '.env.production.local')]
|
||||
: [resolve(apiRoot, '.env'), resolve(apiRoot, '.env.local')];
|
||||
function resolveAppEnv(): 'local' | 'staging' | 'production' {
|
||||
const raw = (process.env.APP_ENV ?? '').trim().toLowerCase();
|
||||
if (raw === 'staging' || raw === 'stage' || raw === 'test') return 'staging';
|
||||
if (raw === 'production' || raw === 'prod') return 'production';
|
||||
if (raw === 'local' || raw === 'development' || raw === 'dev') return 'local';
|
||||
if (nodeEnv === 'production') return 'production';
|
||||
return 'local';
|
||||
}
|
||||
|
||||
const appEnv = resolveAppEnv();
|
||||
|
||||
const layers =
|
||||
appEnv === 'staging'
|
||||
? [resolve(apiRoot, '.env.staging'), resolve(apiRoot, '.env.staging.local')]
|
||||
: appEnv === 'production'
|
||||
? [resolve(apiRoot, '.env.production'), resolve(apiRoot, '.env.production.local')]
|
||||
: [resolve(apiRoot, '.env'), resolve(apiRoot, '.env.local')];
|
||||
|
||||
for (const file of layers) {
|
||||
if (existsSync(file)) {
|
||||
@@ -28,3 +42,6 @@ for (const file of layers) {
|
||||
if (!process.env.NODE_ENV) {
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
}
|
||||
if (!process.env.APP_ENV) {
|
||||
process.env.APP_ENV = appEnv;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user