merge: 런타임 공통 메뉴 영속 설정 반영
This commit is contained in:
@@ -105,6 +105,12 @@ mode 0600 secret 파일에만 둡니다.
|
||||
- PostgreSQL, Redis, Core clone/worktree, PM2 상태와 Caddy 인증서는 named
|
||||
volume에 보존됩니다. 새 user icon은 외부 이미지 서비스가 보존하며 runtime의
|
||||
user icon volume은 기존 설치 호환용입니다.
|
||||
- Gateway와 게임 공통 메뉴는 runtime volume의 `/srv/data/navigation.json`을
|
||||
읽습니다. 최초 기동 때만 Core의 `resources/navigation.json`을 복사하며, 이후
|
||||
배포와 container 재생성은 운영자가 편집한 파일을 덮어쓰지 않습니다. JSON을
|
||||
유효하게 저장한 뒤 브라우저를 새로 열거나 새로고침하면 재빌드 없이 반영됩니다.
|
||||
잘못된 스키마나 `javascript:` URL은 API가 거부하므로 변경 전에 Core 문서의
|
||||
메뉴 설정 검증 명령을 실행합니다.
|
||||
- `/image/*`는 앱 artifact가 아니며 `data/image/`의 별도 운영 자산을 제공합니다.
|
||||
- 일반 `docker compose down`은 volume을 보존합니다. `down --volumes`는 DB와
|
||||
release 상태를 삭제하는 파괴적 명령이므로 backup 없이 실행하지 않습니다.
|
||||
|
||||
@@ -90,6 +90,7 @@ services:
|
||||
GATEWAY_API_PORT: '15001'
|
||||
GATEWAY_FRONTEND_PORT: '15000'
|
||||
GATEWAY_TRPC_PATH: /gateway/api/trpc
|
||||
CORE_NAVIGATION_CONFIG_FILE: /srv/data/navigation.json
|
||||
GATEWAY_INTERNAL_API_URL: http://127.0.0.1:15001
|
||||
GATEWAY_REDIS_PREFIX: sammo:gateway
|
||||
GATEWAY_WORKSPACE_ROOT: /srv/core/repository
|
||||
|
||||
@@ -71,6 +71,15 @@ esac
|
||||
git config --global --add safe.directory "$core_root"
|
||||
export GATEWAY_WORKSPACE_ROOT="$core_root"
|
||||
export RELEASE_CONTROLLER_WORKSPACE_ROOT="$core_root"
|
||||
|
||||
navigation_config_file=${CORE_NAVIGATION_CONFIG_FILE:-/srv/data/navigation.json}
|
||||
if [ ! -e "$navigation_config_file" ]; then
|
||||
navigation_config_dir=$(dirname "$navigation_config_file")
|
||||
mkdir -p "$navigation_config_dir"
|
||||
cp "$core_root/resources/navigation.json" "$navigation_config_file"
|
||||
chmod 644 "$navigation_config_file"
|
||||
fi
|
||||
|
||||
export DATABASE_URL="$(node -e 'const u=new URL("postgresql://localhost");u.username=process.env.POSTGRES_USER||"sammo";u.password=process.env.POSTGRES_PASSWORD;u.hostname=process.env.POSTGRES_HOST||"postgres";u.port=process.env.POSTGRES_PORT||"5432";u.pathname="/"+(process.env.POSTGRES_DB||"sammo");u.searchParams.set("schema","public");process.stdout.write(u.href)')"
|
||||
export GATEWAY_DATABASE_URL="$DATABASE_URL"
|
||||
export REDIS_URL="$(node -e 'const u=new URL("redis://localhost/0");u.password=process.env.REDIS_PASSWORD;u.hostname=process.env.REDIS_HOST||"redis";u.port=process.env.REDIS_PORT||"6379";process.stdout.write(u.href)')"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
test('runtime menu config is seeded once in persistent data and never overwritten', async () => {
|
||||
const entrypoint = await fs.readFile(new URL('../runtime/entrypoint.sh', import.meta.url), 'utf8');
|
||||
const existenceGuard = entrypoint.indexOf('if [ ! -e "$navigation_config_file" ]; then');
|
||||
const copy = entrypoint.indexOf('cp "$core_root/resources/navigation.json" "$navigation_config_file"');
|
||||
|
||||
assert.ok(existenceGuard >= 0, 'persistent navigation config must have an existence guard');
|
||||
assert.ok(copy > existenceGuard, 'the default config must only be copied inside that guard');
|
||||
assert.equal(entrypoint.indexOf('cp -f "$core_root/resources/navigation.json"'), -1);
|
||||
});
|
||||
Reference in New Issue
Block a user