fix: real listener restart + remove listen_port editing from UI

Reviewer concerns:
1. POST /api/proxy/restart only saved config (reload), did not restart
   the listener. Now it touches data/restart.signal; proxy watcher
   polls that file separately and force-restarts the listener even
   when config is unchanged.
2. Editing proxy.listen_port via UI could break Docker port mapping
   (compose publishes 25565:25565 only). UI now shows it read-only;
   README documents how to change it together with compose.

- proxy/main.py: ProxyState.check_restart_signal() + watcher uses it
- api/config_io.py: touch_restart_signal() helper
- api/routes/status.py: /api/proxy/restart -> touch_restart_signal()
- frontend Settings: disabled listen_port input + 프록시 재시작 button
- README + .gitignore updated
This commit is contained in:
2026-05-20 16:47:42 +09:00
parent d10dae5cb9
commit 4b0d790748
7 changed files with 82 additions and 19 deletions

View File

@@ -8,10 +8,12 @@ from __future__ import annotations
import json
import os
import threading
import time
from pathlib import Path
CONFIG_PATH = Path(os.environ.get("MC_CONFIG_PATH", "/data/config.json"))
LOG_DB = Path(os.environ.get("MC_LOG_DB", "/data/logs.db"))
RESTART_SIGNAL = Path(os.environ.get("MC_RESTART_SIGNAL", "/data/restart.signal"))
DEFAULT_CONFIG = {
"proxy": {"listen_port": 25565, "enabled": True},
@@ -41,3 +43,17 @@ def save_config(cfg: dict) -> None:
with tmp.open("w", encoding="utf-8") as f:
json.dump(cfg, f, ensure_ascii=False, indent=2)
os.replace(tmp, CONFIG_PATH)
def touch_restart_signal() -> float:
"""프록시에 강제 listener restart 를 요청하는 신호 파일 갱신.
config 가 바뀌지 않은 상태에서도 listener 를 stop→start 시키고 싶을 때 사용.
"""
RESTART_SIGNAL.parent.mkdir(parents=True, exist_ok=True)
ts = time.time()
with _lock:
# touch: 파일이 없으면 만들고, 있으면 mtime 만 갱신
RESTART_SIGNAL.touch(exist_ok=True)
os.utime(RESTART_SIGNAL, (ts, ts))
return ts