DOCS/journey/troubleshooting/251117_admin_dashboard_standard_deployment_refactoring.md

6.7 KiB

Admin Dashboard 표준 배포 방식 전환 및 구조 리팩토링

날짜: 2025-11-17 작성자: admin 관련 파일:

  • admin-dashboard/docker-compose.yml
  • admin-dashboard/backend/main.py
  • admin-dashboard/frontend/
  • robeing-gateway/app/main.py
  • nginx-infra/server-nginx-default

문제 상황

1. 비표준 배포 방식

  • FastAPI 백엔드가 정적 HTML 파일을 FileResponse로 서빙
  • 표준 방식(nginx 직접 서빙)과 불일치
  • frontend-customer는 이미 표준 방식으로 전환 완료

2. 폴더 구조 혼란

  • frontend-base 폴더명이 역할을 명확히 표현하지 않음
  • admin-ui 폴더명이 frontend보다 덜 직관적

3. Gateway JWT 검증 문제

  • /admin 라우팅에서 JWT 검증을 필수로 하면, JWT가 없는 사용자는 401로 HTML을 받지 못해 로그인 페이지를 볼 수 없음

4. 토큰 불일치

  • frontend-base가 adminToken을 사용하나, Gateway는 표준 JWT(auth_token)를 기대

해결 방안

1. 구조 변경

폴더 리네임:

  • frontend-baseadmin-dashboard
  • admin-uifrontend

최종 구조:

admin-dashboard/
├── backend/          # FastAPI 서버 (API만 처리)
├── frontend/         # React + Tailwind + shadcn + Vite
└── docker-compose.yml

2. 표준 배포 방식 채택

nginx 설정 (nginx-infra/server-nginx-default):

location /admin {
    alias /home/admin/admin-dashboard/frontend/;
    try_files $uri $uri/ /admin/index.html;
    index index.html;
}

권한 설정:

sudo chmod o+x /home
sudo chmod o+x /home/admin

빌드 및 배포:

  • Vite로 npm run build 실행 → dist/ 폴더 생성
  • nginx가 /home/admin/admin-dashboard/frontend/dist/ 직접 서빙
  • FastAPI는 API만 처리 (/admin/api/*)

3. Gateway JWT 검증 수정

robeing-gateway/app/main.py - JWT 검증을 선택적으로 처리:

@app.api_route("/admin/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def admin_proxy(
    path: str,
    request: Request,
    user_uuid: Optional[str] = Depends(get_verified_user_optional)  # 선택적
):
    # JWT가 없어도 HTML 반환, frontend JavaScript가 로그인 페이지 표시

4. 토큰 통일

frontend/index.html - adminTokenauth_token으로 변경:

// Before: localStorage.setItem('adminToken', token)
// After:
localStorage.setItem('auth_token', token)

구현 완료

커밋: 920672a 일시: 2025-11-17 브랜치: main

변경 사항:

  • admin-dashboard/docker-compose.yml: 컨테이너명, 볼륨 경로 수정
  • admin-dashboard/backend/main.py: frontend 경로 수정
  • admin-dashboard/README.md: 구조 설명 업데이트
  • Git 원격 저장소: admin-dashboard.git로 변경
  • admin-dashboard/.gitea/workflows/deploy.yml: 배포 스크립트 경로 수정 및 포트 충돌 방지
  • nginx-infra/server-nginx-default: /admin 404 해결 - rootalias 변경 및 try_files 경로 수정

교훈

표준 방식의 중요성

  • nginx가 정적 파일을 직접 서빙하는 것이 성능과 보안 측면에서 최적
  • FastAPI는 API 처리에 집중, 정적 파일 서빙은 웹서버가 담당
  • 참고: 250717_happybell80_auth서버구축및정적빌드배포전환.md

폴더 구조 명확성

  • 프로젝트명은 역할을 명확히 표현해야 함 (admin-dashboard)
  • frontendadmin-ui보다 직관적이고 표준적

JWT 검증 전략

  • HTML은 공개되어도 되고, 실제 데이터 API는 별도로 JWT 검증
  • Gateway는 HTML 요청은 통과시키고, API 요청만 검증하는 선택적 검증 필요

토큰 통일

  • 프로젝트 전체에서 표준 JWT 키(auth_token) 사용으로 일관성 확보
  • Gateway와 frontend 간 토큰 키 불일치 방지

CI/CD 배포 스크립트 수정

문제: 배포 스크립트가 이전 폴더명(frontend-base)을 참조하여 배포 실패

해결:

  1. 배포 경로 수정 (admin-dashboard/.gitea/workflows/deploy.yml):

    • /home/admin/frontend-base/home/admin/admin-dashboard
    • 백업 경로: frontend-base.backup.*admin-dashboard.backup.*
  2. 포트 충돌 방지:

    • 기존 frontend-base 컨테이너 강제 제거
    • 포트 8000을 사용하는 모든 컨테이너 중지 및 제거
    # 강제로 컨테이너 제거 (포트 충돌 방지)
    sudo docker ps -a --filter "name=admin-dashboard" --format "{{.ID}}" | xargs -r sudo docker rm -f || true
    # frontend-base 컨테이너도 정리 (이전 이름)
    sudo docker ps -a --filter "name=frontend-base" --format "{{.ID}}" | xargs -r sudo docker rm -f || true
    # 포트 8000을 사용하는 컨테이너 확인 및 제거
    sudo docker ps --filter "publish=8000" --format "{{.ID}}" | xargs -r sudo docker stop || true
    sudo docker ps --filter "publish=8000" --format "{{.ID}}" | xargs -r sudo docker rm -f || true
    

교훈:

  • 폴더명 변경 시 CI/CD 스크립트도 함께 업데이트 필요
  • 배포 전 기존 컨테이너 완전 정리로 포트 충돌 방지
  • 이전 이름의 컨테이너도 정리하여 혼란 방지

nginx 설정 적용 및 404 해결

문제: /admin 경로에서 404 에러 발생

원인:

  • nginx 설정 파일(server-nginx-default)은 수정했으나 실제 적용된 설정(/etc/nginx/sites-enabled/default)은 이전 설정 유지
  • root 방식과 alias 방식의 차이로 인한 경로 불일치

해결:

  1. 설정 파일 동기화:

    sudo cp /home/admin/nginx-infra/server-nginx-default /etc/nginx/sites-enabled/default
    sudo nginx -t
    sudo systemctl reload nginx
    
  2. 최종 nginx 설정:

    location /admin {
        alias /home/admin/admin-dashboard/frontend/;
        try_files $uri $uri/ /admin/index.html;
        index index.html;
    }
    

검증:

curl -I http://localhost/admin/  # HTTP/1.1 200 OK

교훈:

  • 설정 파일 수정 후 반드시 실제 nginx 설정에 적용 필요
  • root vs alias 차이 이해: root는 경로를 합치고, alias는 경로를 대체
  • try_files의 fallback 경로도 alias 사용 시 /admin/index.html로 명시 필요

터미널 bash 문제 해결

문제: Cursor IDE 터미널에서 명령어 실행 시 오류 발생

증상:

  • cd 명령어 실행 실패
  • Git 명령어 실행 시 오류

해결:

  • Cursor IDE 재시작: 터미널 설정이 다시 로드되어 문제 해결됨
  • 또는 Ctrl+Shift+P → "Developer: Reload Window"

교훈:

  • IDE 터미널 문제 발생 시 가장 먼저 IDE 재시작 시도
  • 재시작으로 해결되지 않으면 shell 경로 확인 (/bin/bash)