build: separate .env.build for packaging, keep .env dev-only

The previous setup packaged the development `.env` into the installer
resources, mixing local server settings (PORT/HOST/SESSION_SECRET) with
the build-time site domain. Introduce a dedicated `.env.build`:

- electron-builder configs now copy `.env.build` (gitignored) into
  `resources/`, no longer touching the dev `.env`.
- `loadEnv()` prefers `resources/.env.build` first, falling back to
  `resources/.env` (for operators who hand-edit the packaged file),
  then `<root>/.env.build`, then `<root>/.env`.
- `.env.build.example` documents the build-only keys (SITE_BASE_URL,
  MANIFEST_URL, MUSIC_CONCURRENCY); server-side keys stay in `.env`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 01:03:22 +09:00
parent dfb60046c8
commit c8da4207fc
5 changed files with 55 additions and 8 deletions

View File

@@ -7,9 +7,14 @@ import { projectRoot } from './paths.js'
* `.env` 를 읽어 `process.env` 에 주입.
*
* 탐색 순서(처음 발견된 것만 사용):
* 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env`
* — electron-builder 의 extraResources 로 빌드 시점 `.env` 가 함께 배포됨.
* 2. `<프로젝트 루트>/.env`
* 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env.build`
* — electron-builder 의 extraResources 로 빌드 시점 `.env.build` 가 함께
* 배포됨. 빌드용 도메인/설정을 dev `.env` 와 분리해 관리하기 위함.
* 2. 패키징된 Electron 앱이면 `process.resourcesPath/.env`
* — 운영자가 패키징 후 직접 `.env` 를 옆에 두고 덮어쓰는 경우를 대비한 폴백.
* 3. `<프로젝트 루트>/.env.build`
* — 개발 환경에서도 빌드용 값을 그대로 테스트하고 싶을 때.
* 4. `<프로젝트 루트>/.env`
* — 개발 실행(npm start / npm run installer*) 및 서버 운영용.
*
* - 이미 설정된 환경변수는 덮어쓰지 않음(쉘/systemd 에서 넘긴 값이 우선).
@@ -20,8 +25,10 @@ export function loadEnv(): void {
const candidates: string[] = []
const resourcesPath = (process as NodeJS.Process & { resourcesPath?: string }).resourcesPath
if (typeof resourcesPath === 'string' && resourcesPath.length > 0) {
candidates.push(path.join(resourcesPath, '.env.build'))
candidates.push(path.join(resourcesPath, '.env'))
}
candidates.push(path.join(projectRoot, '.env.build'))
candidates.push(path.join(projectRoot, '.env'))
for (const envPath of candidates) {