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:
37
.env.build.example
Normal file
37
.env.build.example
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# 음악퀴즈 통합 패키지 — 빌드용 환경변수 템플릿
|
||||||
|
#
|
||||||
|
# 이 파일은 `npm run dist:win` / `npm run dist:win:rp` 로 exe 를 패키징할 때
|
||||||
|
# 설치기(installer / installer-rp) 안에 함께 묶이는 값들입니다.
|
||||||
|
# 개발 실행에서 쓰는 `.env` 와는 분리되어 있어, 운영 도메인 같은 값을 빌드용
|
||||||
|
# 으로만 관리할 수 있습니다.
|
||||||
|
#
|
||||||
|
# 사용법:
|
||||||
|
# 1) 이 파일을 복사해 `.env.build` 로 만든다.
|
||||||
|
# 2) 운영 도메인 등 배포에 들어갈 값으로 채운다.
|
||||||
|
# 3) `npm run dist:win` 또는 `npm run dist:win:rp` 로 빌드한다.
|
||||||
|
# → electron-builder 가 `.env.build` 를 패키지된 exe 의
|
||||||
|
# `resources/.env.build` 로 함께 배포.
|
||||||
|
# → 런타임에서 `env.ts` 가 우선 로드.
|
||||||
|
#
|
||||||
|
# `.env.build` 는 .gitignore 로 제외되어 있습니다.
|
||||||
|
# 서버(express) 운영용 PORT / HOST / SESSION_SECRET 같은 변수는 여기 두지 말고
|
||||||
|
# 서버 측 `.env` 에 두세요. 이 파일은 설치기 exe 에 묶이는 값 전용입니다.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# ----- 사이트 도메인(설치기가 manifest 를 받아갈 주소) -----
|
||||||
|
|
||||||
|
# 설치기 두 종(installer / installer-rp) 이 첫 화면에서 자동으로 채워 넣는
|
||||||
|
# manifest 의 호스트. 프로토콜 + 호스트(+포트) 까지만 적고 슬래시는 끝에 붙이지 않음.
|
||||||
|
# 예) 운영 도메인 : https://mq.example.com
|
||||||
|
# 로컬 개발 : http://127.0.0.1:3000
|
||||||
|
SITE_BASE_URL=https://mq.example.com
|
||||||
|
|
||||||
|
# 위 SITE_BASE_URL 로부터 자동으로 `${SITE_BASE_URL}/manifest.json` 이 생성됩니다.
|
||||||
|
# 특별히 다른 경로를 쓰고 싶을 때만 아래를 풀어서 우선 적용시키세요.
|
||||||
|
# MANIFEST_URL=https://mq.example.com/manifest.json
|
||||||
|
|
||||||
|
# ----- 리소스팩 설치기 -----
|
||||||
|
|
||||||
|
# yt-dlp 동시 다운로드 수(1~8). 비워두면 CPU 코어 수로 자동 결정.
|
||||||
|
# MUSIC_CONCURRENCY=
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ conversations/
|
|||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
.env.*.local
|
.env.*.local
|
||||||
|
.env.build
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ files:
|
|||||||
- installer-rp/**
|
- installer-rp/**
|
||||||
- build/icon.*
|
- build/icon.*
|
||||||
- package.json
|
- package.json
|
||||||
# 메인 설치기와 동일하게 .env, locales 를 함께 배포.
|
# 메인 설치기와 동일하게 빌드 전용 `.env.build` 와 locales 를 함께 배포.
|
||||||
extraResources:
|
extraResources:
|
||||||
- from: .
|
- from: .
|
||||||
to: .
|
to: .
|
||||||
filter:
|
filter:
|
||||||
- .env
|
- .env.build
|
||||||
- from: locales
|
- from: locales
|
||||||
to: locales
|
to: locales
|
||||||
filter:
|
filter:
|
||||||
|
|||||||
@@ -9,15 +9,17 @@ files:
|
|||||||
- installer/**
|
- installer/**
|
||||||
- build/icon.*
|
- build/icon.*
|
||||||
- package.json
|
- package.json
|
||||||
# 빌드 시점의 .env 를 설치기 옆에 함께 배포(없으면 조용히 패스).
|
# 빌드 전용 `.env.build` 를 설치기 옆에 함께 배포(없으면 조용히 패스).
|
||||||
# 패키징 후 운영자가 resources/.env 만 교체해서 도메인을 바꿀 수도 있음.
|
# `.env` 는 서버/개발 실행용이라 빌드 산출물에는 포함되지 않으며, 패키지된 exe
|
||||||
|
# 는 `resources/.env.build` 를 우선 로드함(없으면 `resources/.env` 로 폴백).
|
||||||
|
# 패키징 후 운영자가 `resources/.env.build` 만 교체해서 도메인을 바꿀 수 있음.
|
||||||
# locales/ 폴더는 i18n.ts 가 process.resourcesPath/locales/<component>/ko-kr.json
|
# locales/ 폴더는 i18n.ts 가 process.resourcesPath/locales/<component>/ko-kr.json
|
||||||
# 을 찾아 로드하므로, 빌드된 .exe 에서도 한국어 사전이 적용되도록 함께 배포.
|
# 을 찾아 로드하므로, 빌드된 .exe 에서도 한국어 사전이 적용되도록 함께 배포.
|
||||||
extraResources:
|
extraResources:
|
||||||
- from: .
|
- from: .
|
||||||
to: .
|
to: .
|
||||||
filter:
|
filter:
|
||||||
- .env
|
- .env.build
|
||||||
- from: locales
|
- from: locales
|
||||||
to: locales
|
to: locales
|
||||||
filter:
|
filter:
|
||||||
|
|||||||
@@ -7,9 +7,14 @@ import { projectRoot } from './paths.js'
|
|||||||
* `.env` 를 읽어 `process.env` 에 주입.
|
* `.env` 를 읽어 `process.env` 에 주입.
|
||||||
*
|
*
|
||||||
* 탐색 순서(처음 발견된 것만 사용):
|
* 탐색 순서(처음 발견된 것만 사용):
|
||||||
* 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env`
|
* 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env.build`
|
||||||
* — electron-builder 의 extraResources 로 빌드 시점 `.env` 가 함께 배포됨.
|
* — electron-builder 의 extraResources 로 빌드 시점 `.env.build` 가 함께
|
||||||
* 2. `<프로젝트 루트>/.env`
|
* 배포됨. 빌드용 도메인/설정을 dev `.env` 와 분리해 관리하기 위함.
|
||||||
|
* 2. 패키징된 Electron 앱이면 `process.resourcesPath/.env`
|
||||||
|
* — 운영자가 패키징 후 직접 `.env` 를 옆에 두고 덮어쓰는 경우를 대비한 폴백.
|
||||||
|
* 3. `<프로젝트 루트>/.env.build`
|
||||||
|
* — 개발 환경에서도 빌드용 값을 그대로 테스트하고 싶을 때.
|
||||||
|
* 4. `<프로젝트 루트>/.env`
|
||||||
* — 개발 실행(npm start / npm run installer*) 및 서버 운영용.
|
* — 개발 실행(npm start / npm run installer*) 및 서버 운영용.
|
||||||
*
|
*
|
||||||
* - 이미 설정된 환경변수는 덮어쓰지 않음(쉘/systemd 에서 넘긴 값이 우선).
|
* - 이미 설정된 환경변수는 덮어쓰지 않음(쉘/systemd 에서 넘긴 값이 우선).
|
||||||
@@ -20,8 +25,10 @@ export function loadEnv(): void {
|
|||||||
const candidates: string[] = []
|
const candidates: string[] = []
|
||||||
const resourcesPath = (process as NodeJS.Process & { resourcesPath?: string }).resourcesPath
|
const resourcesPath = (process as NodeJS.Process & { resourcesPath?: string }).resourcesPath
|
||||||
if (typeof resourcesPath === 'string' && resourcesPath.length > 0) {
|
if (typeof resourcesPath === 'string' && resourcesPath.length > 0) {
|
||||||
|
candidates.push(path.join(resourcesPath, '.env.build'))
|
||||||
candidates.push(path.join(resourcesPath, '.env'))
|
candidates.push(path.join(resourcesPath, '.env'))
|
||||||
}
|
}
|
||||||
|
candidates.push(path.join(projectRoot, '.env.build'))
|
||||||
candidates.push(path.join(projectRoot, '.env'))
|
candidates.push(path.join(projectRoot, '.env'))
|
||||||
|
|
||||||
for (const envPath of candidates) {
|
for (const envPath of candidates) {
|
||||||
|
|||||||
Reference in New Issue
Block a user