Skip to content

Commit 965b17a

Browse files
SOIVclaude
andcommitted
feat(api): Setup 모드 시작 시 접속 가능한 IP 주소 콘솔 출력
서버가 설치 마법사 모드로 시작될 때 터미널에 박스 배너를 출력해 원격 서버·Docker 환경에서도 어떤 주소로 브라우저를 열면 되는지 바로 알 수 있도록 함. - localhost:PORT 항상 표시 - os.networkInterfaces()로 감지된 IPv4 네트워크 주소 목록도 함께 출력 (루프백 제외, Docker bridge / 로컬 LAN / 외부 인터페이스 포함) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d78a54d commit 965b17a

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

apps/api/src/index.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dotenv/config';
22

3+
import os from 'node:os';
34
import path from 'node:path';
45

56
import { validateEnv } from './config/env';
@@ -40,14 +41,52 @@ if (env.INSTALL_MODE === 'bypass') {
4041
// modules/ 디렉터리는 프로젝트 루트 기준 (apps/api/src → ../../../modules)
4142
const MODULES_DIR = path.join(__dirname, '..', '..', '..', 'modules');
4243

44+
// ── 네트워크 인터페이스 IP 수집 ────────────────────────────────
45+
46+
function getLocalIPs(): string[] {
47+
const ips: string[] = [];
48+
for (const ifaces of Object.values(os.networkInterfaces())) {
49+
for (const iface of ifaces ?? []) {
50+
// IPv4이고 루프백(127.x)이 아닌 것만
51+
if (iface.family === 'IPv4' && !iface.internal) {
52+
ips.push(iface.address);
53+
}
54+
}
55+
}
56+
return ips;
57+
}
58+
59+
function printSetupBanner(port: number) {
60+
const ips = getLocalIPs();
61+
const lines = [
62+
'',
63+
' ╔══════════════════════════════════════════════════════╗',
64+
' ║ Fieldstack — 설치 마법사 모드 ║',
65+
' ╠══════════════════════════════════════════════════════╣',
66+
' ║ 아래 주소 중 하나를 브라우저에서 열어 설치를 ║',
67+
' ║ 진행해 주세요. ║',
68+
' ╠══════════════════════════════════════════════════════╣',
69+
` ║ 로컬 → http://localhost:${port}`.padEnd(56) + '║',
70+
];
71+
for (const ip of ips) {
72+
lines.push(` ║ 네트워크 → http://${ip}:${port}`.padEnd(56) + '║');
73+
}
74+
if (ips.length === 0) {
75+
lines.push(' ║ (네트워크 인터페이스를 감지하지 못했습니다)'.padEnd(56) + '║');
76+
}
77+
lines.push(' ╚══════════════════════════════════════════════════════╝');
78+
lines.push('');
79+
console.log(lines.join('\n'));
80+
}
81+
4382
// ── Setup 모드 ─────────────────────────────────────────────────
4483
// installed.lock 없고 bypass 아닐 때 → Setup 마법사만 서빙
4584
async function startSetup() {
4685
console.log('[fieldstack][api] *** SETUP MODE — installation wizard active ***');
4786
const app = createSetupApp();
4887
finalizeApp(app);
4988
app.listen(env.PORT, () => {
50-
console.log(`[fieldstack][api] setup server listening on http://localhost:${env.PORT}`);
89+
printSetupBanner(env.PORT);
5190
});
5291
}
5392

0 commit comments

Comments
 (0)