From 1eabd7183c7e3170d92a8a0e1fb594bf76989c10 Mon Sep 17 00:00:00 2001 From: king Date: Sun, 24 May 2026 14:05:32 +0900 Subject: [PATCH] =?UTF-8?q?fix(routing):=20FastAPI(root=5Fpath=3D)=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=E2=80=94=20Mount/Route=20=EB=B9=84?= =?UTF-8?q?=EB=8C=80=EC=B9=AD=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starlette Mount 가 FastAPI(root_path=...) 의 값을 mount 경로에 흡수해버려서 @app.get 라우트(/health/db)는 그대로지만 mount(/static)는 /orderlist/static 으로 등록되는 비대칭이 발생했다. NPM 이 /orderlist prefix 를 잘라서 백엔드로 보내면 /health/db 는 200 이지만 /static/css/style.css 는 404 가 났다. 해결: FastAPI 생성자에서 root_path 인자 제거. 대신 Dockerfile 의 uvicorn 명령에 --root-path "${APP_ROOT_PATH:-}" 를 추가해 ASGI scope 레벨에서만 root_path 가 세팅되도록 한다. 이러면 모든 라우트/마운트가 prefix 없이 등록되고 URL 생성 시에만 prefix 가 붙는다. APP_ROOT_PATH 환경변수와 main.py 의 HTML 경로 치환 로직은 그대로 유지. --- Dockerfile | 4 +++- app/main.py | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a0f6a81..163eaee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,4 +23,6 @@ EXPOSE 8000 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD curl -fsS http://localhost:8000/health/db || exit 1 -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--proxy-headers"] +# APP_ROOT_PATH 를 uvicorn --root-path 로 넘긴다. (shell form 필요 — 환경변수 확장) +# 비어 있으면 빈 문자열이 그대로 전달되어 root_path 없이 동작한다. +CMD uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers --root-path "${APP_ROOT_PATH:-}" diff --git a/app/main.py b/app/main.py index 4284239..c9bafe3 100644 --- a/app/main.py +++ b/app/main.py @@ -22,7 +22,15 @@ log_db_startup_status() Base.metadata.create_all(bind=engine) ensure_search_optimizations(engine) -app = FastAPI(title="Order Management System", root_path=APP_ROOT_PATH) +# root_path 는 FastAPI 생성자에 넘기지 않는다. +# Starlette 의 Mount 가 root_path 를 흡수해 mount 경로에 prefix 가 붙어버려서 +# @app.get 라우트와 mount 가 비대칭으로 등록되는 문제 때문이다. +# (예: /health/db 는 그대로지만 /static/* 는 /orderlist/static/* 로 등록됨) +# +# 대신 uvicorn --root-path 로 ASGI scope.root_path 만 세팅한다. +# 그러면 모든 라우트/마운트가 prefix 없이 등록되고, URL 생성 시에만 prefix 가 붙는다. +# Dockerfile 의 CMD 가 ${APP_ROOT_PATH} 를 --root-path 로 넘긴다. +app = FastAPI(title="Order Management System") @app.get("/health/db")