feat(config): support PORT env override
This commit is contained in:
+13
-1
@@ -43,6 +43,18 @@
|
|||||||
"test_status": "pnpm test:run + pnpm typecheck passing"
|
"test_status": "pnpm test:run + pnpm typecheck passing"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"deployment-port-env-override": {
|
||||||
|
"status": "completed",
|
||||||
|
"date": "2026-02-16",
|
||||||
|
"updated": "2026-02-16",
|
||||||
|
"summary": "Added PORT environment variable override support so PaaS deployments can bind the gateway to the platform-assigned port without requiring config changes.",
|
||||||
|
"files_modified": [
|
||||||
|
"src/config/loader.ts",
|
||||||
|
"src/config/loader.test.ts"
|
||||||
|
],
|
||||||
|
"test_status": "pnpm test:run + pnpm typecheck passing"
|
||||||
|
},
|
||||||
|
|
||||||
"openclaw-gap-roadmap": {
|
"openclaw-gap-roadmap": {
|
||||||
"file": "2026-02-15-openclaw-gap-roadmap.md",
|
"file": "2026-02-15-openclaw-gap-roadmap.md",
|
||||||
"status": "planned",
|
"status": "planned",
|
||||||
@@ -2132,7 +2144,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"overall_progress": {
|
"overall_progress": {
|
||||||
"total_test_count": 1692,
|
"total_test_count": 1694,
|
||||||
"all_tests_passing": true,
|
"all_tests_passing": true,
|
||||||
"p0_completion": "3/3 (100%)",
|
"p0_completion": "3/3 (100%)",
|
||||||
"p1_completion": "4/4 (100%)",
|
"p1_completion": "4/4 (100%)",
|
||||||
|
|||||||
@@ -102,6 +102,68 @@ telegram:
|
|||||||
|
|
||||||
rmSync(testDir, { recursive: true });
|
rmSync(testDir, { recursive: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('overrides server.port from PORT env var when set', () => {
|
||||||
|
mkdirSync(testDir, { recursive: true });
|
||||||
|
const configPath = join(testDir, 'config.yaml');
|
||||||
|
|
||||||
|
const prevPort = process.env.PORT;
|
||||||
|
process.env.PORT = '3777';
|
||||||
|
|
||||||
|
writeFileSync(configPath, `
|
||||||
|
telegram:
|
||||||
|
bot_token: "test-token"
|
||||||
|
allowed_chat_ids: [123]
|
||||||
|
server:
|
||||||
|
port: 18800
|
||||||
|
models:
|
||||||
|
default:
|
||||||
|
provider: anthropic
|
||||||
|
model: claude-sonnet
|
||||||
|
`);
|
||||||
|
|
||||||
|
const config = loadConfig(configPath);
|
||||||
|
expect(config.server.port).toBe(3777);
|
||||||
|
|
||||||
|
if (prevPort !== undefined) {
|
||||||
|
process.env.PORT = prevPort;
|
||||||
|
} else {
|
||||||
|
delete process.env.PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmSync(testDir, { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignores invalid PORT env var values', () => {
|
||||||
|
mkdirSync(testDir, { recursive: true });
|
||||||
|
const configPath = join(testDir, 'config.yaml');
|
||||||
|
|
||||||
|
const prevPort = process.env.PORT;
|
||||||
|
process.env.PORT = 'not-a-number';
|
||||||
|
|
||||||
|
writeFileSync(configPath, `
|
||||||
|
telegram:
|
||||||
|
bot_token: "test-token"
|
||||||
|
allowed_chat_ids: [123]
|
||||||
|
server:
|
||||||
|
port: 18800
|
||||||
|
models:
|
||||||
|
default:
|
||||||
|
provider: anthropic
|
||||||
|
model: claude-sonnet
|
||||||
|
`);
|
||||||
|
|
||||||
|
const config = loadConfig(configPath);
|
||||||
|
expect(config.server.port).toBe(18800);
|
||||||
|
|
||||||
|
if (prevPort !== undefined) {
|
||||||
|
process.env.PORT = prevPort;
|
||||||
|
} else {
|
||||||
|
delete process.env.PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmSync(testDir, { recursive: true });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('loadConfig with overlay', () => {
|
describe('loadConfig with overlay', () => {
|
||||||
|
|||||||
+14
-1
@@ -81,5 +81,18 @@ export function loadConfig(configPath: string, overlayPath?: string): Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const expandedConfig = expandEnvVarsInObject(rawConfig);
|
const expandedConfig = expandEnvVarsInObject(rawConfig);
|
||||||
return configSchema.parse(expandedConfig);
|
const config = configSchema.parse(expandedConfig);
|
||||||
|
|
||||||
|
// PaaS convention: if PORT is set, bind the gateway to it.
|
||||||
|
// This is intentionally an override (even if config.server.port is set)
|
||||||
|
// to make deployments on Fly/Railway/Render/Heroku-style platforms work.
|
||||||
|
const envPort = process.env.PORT;
|
||||||
|
if (envPort && /^\d+$/.test(envPort)) {
|
||||||
|
const port = Number(envPort);
|
||||||
|
if (Number.isFinite(port) && port > 0 && port <= 65535) {
|
||||||
|
config.server.port = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user