DCloud Infra 구축하기 -3-

스타일 파악했습니다. 캐주얼하고 자연스럽게, 이미지 넣는 위치도 표시해서 시리즈 이어지는 느낌으로 써드릴게요.


DCloud Infra 구축하기 -3-

저번 포스트에서 FastAPI 확장 서버까지 만들었으니, 이제 학생들이 실제로 누르는 화면을 만들 차례입니다.

근데 솔직히 처음엔 그냥 Skyline 대시보드 쓰면 되지 않나 싶었는데...

​제가 이걸 보고 음 내가 원하는 기능이 없네.. 그냥 만들까 해서 만들었습니다.

왜 Next.js인가

기술 선택할 때 제일 고민한 부분이 토큰 관리였습니다.

Skyline 로그인 하면 keystone_token이라는 걸 받아오는데, 이걸 프론트에서 직접 들고 다니면 브라우저 네트워크 탭 열면 다 보입니다. 그러면 안 되잖아요.

Next.js의 API Route를 BFF(Backend for Frontend)처럼 쓰면 이 문제가 깔끔하게 해결됩니다. 프론트는 /api/v1/instances 같은 Next.js 서버로만 요청하고, 실제 Skyline 호출은 서버 쪽에서만 일어나는 구조입니다.

사용자 브라우저 → Next.js API Route → Skyline API
               (여기서만 토큰 사용)

인증은 NextAuth.js로 처리했습니다. 로그인 성공하면 Skyline에서 받은 토큰을 JWT 세션에 암호화해서 담아두고, 각 API Route에서 getServerSession으로 꺼내 씁니다.

타입 안전하게 API 호출하기

Skyline에는 OpenAPI 스펙이 있어서, 이걸 TypeScript 타입으로 변환해서 썼습니다.

// openapi-typescript로 자동 생성된 타입 기반으로 클라이언트 만들기
export function getSkylineClient(token: string) {
  return createClient<paths>({
    baseUrl: process.env.SKYLINE_API_URL,
    headers: { Authorization: token },
  });
}

이렇게 해두면 존재하지 않는 엔드포인트 호출하거나 응답 필드 이름 틀리면 빌드할 때 바로 에러가 납니다. 런타임에서 undefined 보고 당황하는 일이 확실히 줄었습니다.

VM 생성 플로우

VM 만드는 과정이 생각보다 단계가 많습니다.

  1. Flavor(사양) 선택
  2. OS 이미지 선택
  3. 키페어 선택
  4. 추가 포트포워딩 설정 (선택)
  5. 생성 요청 → 202 Accepted

근데 VM 생성은 빠르면 4분, 느리면 30분도 걸립니다. 그냥 로딩 돌리고 기다리면 사용자 입장에서 뭔 일이 일어나는지 모르잖아요.

그래서 생성 요청 후에는 별도 상태 페이지로 넘어가서 5초마다 폴링으로 상태를 확인합니다.

// 5초마다 인스턴스 상태 확인
const intervalId = setInterval(fetchStatus, 5000);

ACTIVE 되면 그때 목록 페이지로 이동하도록 했습니다.

가장 신경 쓴 UX - 삭제

버튼 하나로 삭제하면 잘못 눌렀을 때 답이 없습니다. 그래서 삭제 플로우를 3단계로 만들었어요.

![삭제 다이얼로그 - confirm 단계] ![삭제 다이얼로그 - deleting 스피너 단계]
![삭제 다이얼로그 - success 단계]

확인 → 삭제 중(스피너) → 완료

VM, 디스크, 포트포워딩 규칙 모두 동일한 패턴 적용했습니다. 귀찮아도 이거 하고 나서 "실수로 지웠어요" 제보가 없어졌습니다.

이메일 인증 회원가입

학교 이메일(@office.deu.ac.kr)이 아니면 가입 자체가 안 됩니다.

그리고 가입 요청한다고 바로 계정이 생기는 게 아니라, 인증 메일 보내고 링크 클릭하면 그때 Skyline에 계정이 만들어지는 방식입니다.

가입 폼 제출 → DB에 임시 저장 + 인증 메일 발송
      ↓
메일 링크 클릭 → 토큰 검증 → Skyline 계정 생성 → 완료

임시 데이터는 24시간 후 자동 삭제됩니다. 이 부분은 로컬 SQLite + Drizzle ORM으로 처리했는데, 규모가 크지 않아서 외부 DB 없이도 충분했습니다.

아직 남은 것들

솔직히 @ts-nocheck 달린 파일이 몇 개 있습니다. openapi-fetch에서 동적으로 path를 조합할 때 타입 추론이 완벽하지 않아서 일단 임시방편으로 처리한 것들인데... 나중에 고쳐야죠.

세션 만료 처리도 아직 거칩니다. 현재는 5분마다 토큰 검증해서 401이면 로그아웃시키는 건데, 만료 직전에 빈 화면 뜨는 이슈가 있어서 개선이 필요합니다.

마치며

코드가 복도 끝 서버실 위에서 진짜로 돌아간다는 게 개발 내내 긴장감을 줬습니다. 장난감 프로젝트가 아니니까 에러 처리나 UX 디테일에 자연스럽게 신경 쓰게 됐어요.

학과 클라우드 서비스 치고는 꽤 잘 만들어진 것 같습니다. 자화자찬이지만요.

GitHub - INMD1/DCloud-Infra-Dashboard