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 만드는 과정이 생각보다 단계가 많습니다.

- Flavor(사양) 선택
- OS 이미지 선택
- 키페어 선택
- 추가 포트포워딩 설정 (선택)
- 생성 요청 → 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 디테일에 자연스럽게 신경 쓰게 됐어요.
학과 클라우드 서비스 치고는 꽤 잘 만들어진 것 같습니다. 자화자찬이지만요.