StudyDad Loop 제품을 만들며 배운 운영과 설계를 기록합니다.

FamBlend를 중심으로 실제 구현, 운영 메모, GitHub 포트폴리오를 연결해 쌓아가는 StudyDad의 작업 기록입니다.

성장과 기술/시스템 설계

작은 운영 콘솔을 안정적으로 굴리기 위한 아키텍처 결정들

박세식 2026. 7. 6. 12:00

운영 콘솔 아키텍처 시리즈 1/9

관리자 페이지는 겉으로 보기에는 단순해 보인다. 목록을 보여주고, 상태를 바꾸고, 파일을 내려받고, 내부 사용자가 필요한 데이터를 확인한다.

하지만 실제로 운영되는 콘솔을 만들다 보면 생각보다 많은 질문을 만나게 된다.

  • React로 만든 관리자 페이지는 어디에 배포하는 것이 좋을까?
  • 모든 데이터를 RDB에 넣어야 할까?
  • Lambda만으로 백엔드를 구성해도 괜찮을까?
  • API Gateway는 꼭 필요한가?
  • 오래 걸리는 리포트 생성은 어떻게 처리해야 할까?
  • CORS와 쿠키 인증은 왜 자꾸 문제를 일으킬까?
  • 이런 결정들은 어떻게 문서로 남겨야 할까?

이 시리즈는 그런 질문에 답하기 위해 작성했다.

이 시리즈에서 다루는 것

이 시리즈는 특정 기술 조합을 자랑하기 위한 구축기가 아니다. 운영 콘솔을 만들며 반복해서 마주치는 의사결정, 경계 나누기, 트레이드오프를 실무 설계 관점에서 정리한다.

다루는 주제는 다음과 같다.

  • 운영 콘솔을 도메인별로 분리한 이유
  • React SPA를 S3와 CloudFront에 배포한 이유
  • RDB 없이 S3 JSON 스냅샷으로 충분했던 조건
  • Lambda 앞에 API Gateway를 둔 이유
  • Lambda와 상주 API 서버를 함께 쓴 하이브리드 백엔드
  • 오래 걸리는 파일 생성 작업을 비동기로 처리하는 패턴
  • 브라우저 기반 콘솔에서 CORS와 쿠키 인증을 다루는 법
  • 아키텍처 의사결정 기록을 남기는 방법

왜 운영 콘솔인가

운영 콘솔은 서비스의 전면에 보이는 제품은 아닐 수 있다. 하지만 실제 조직이 매일 일을 처리하는 도구다. 그래서 작은 불편도 반복되면 큰 비용이 되고, 작은 장애도 운영 업무 전체를 멈출 수 있다.

운영 콘솔에는 몇 가지 특징이 있다.

첫째, 사용자는 적지만 업무 중요도는 높다. 대중 서비스처럼 트래픽이 크지 않아도, 내부 운영자가 매일 사용하는 핵심 흐름이면 안정성이 중요하다.

둘째, 요구사항이 자주 바뀐다. 운영 방식, 리포트 형식, 입력 데이터, 권한 정책이 계속 바뀐다. 처음부터 과하게 복잡한 구조를 만들면 변경 속도가 느려진다.

셋째, 프론트엔드, 백엔드, 인프라의 경계가 자주 만난다. React SPA, API, 인증, CORS, 캐시, 파일 생성, 데이터 저장소가 함께 움직인다.

그래서 운영 콘솔은 시스템 설계를 연습하기 좋은 주제다. 거대한 분산 시스템은 아니지만, 실무적인 트레이드오프가 매우 선명하게 드러난다.

이 시리즈의 관점

이 시리즈는 "이 기술을 쓰면 정답이다"라고 말하지 않는다.

대신 다음 질문을 반복한다.

  • 이 선택이 당시 조건에서 왜 합리적이었는가?
  • 선택하지 않은 대안은 무엇이었는가?
  • 이 결정으로 얻은 것은 무엇인가?
  • 대신 포기한 것은 무엇인가?
  • 어떤 조건이 되면 다시 검토해야 하는가?

아키텍처는 멋진 기술 조합이 아니라 제약 조건의 결과다. 트래픽 규모, 운영 인력, 데이터 변경 빈도, 보안 요구사항, 사용자의 업무 방식이 모두 설계에 영향을 준다.

시리즈 목차

1. 같은 관리자 페이지처럼 보여도, 도메인이 다르면 콘솔을 나눠야 한다

하나의 거대한 관리자 페이지로 합치지 않고, 신청 관리 콘솔과 운영 리포트 콘솔을 분리한 이유를 다룬다. 사용자, 데이터 원천, 배포 주기, 장애 영향 범위가 어떻게 분리 기준이 되는지 정리한다.

2. 관리자 페이지 배포에 서버가 꼭 필요할까?

React SPA를 EC2와 Nginx 대신 S3와 CloudFront에 배포한 이유를 다룬다. 정적 자산, CDN, HTTPS, SPA 라우팅 fallback, 캐시 무효화까지 함께 설명한다.

3. 데이터베이스를 쓰지 않기로 한 아키텍처 결정

모든 운영 도구에 RDB가 필요한 것은 아니다. 데이터 원천이 이미 외부에 있고, 변경 빈도가 낮고, 읽기 패턴이 단순한 경우 S3 JSON 스냅샷으로 충분했던 이유를 정리한다.

4. Lambda Function URL 대신 API Gateway를 선택한 이유

Lambda를 HTTP로 호출하는 가장 단순한 방법은 Function URL이다. 그럼에도 API Gateway를 앞단에 둔 이유를 CORS, 라우팅, 로깅, 스로틀링, 백엔드 교체 가능성 관점에서 설명한다.

5. 서버리스만으로 부족했던 운영 콘솔 백엔드 설계

모든 API를 Lambda로 만들지도, 모든 API를 상주 서버로 만들지도 않은 이유를 다룬다. 짧고 잦은 조회는 상주 API 서버로, 드물고 무거운 작업은 Lambda로 분리한 기준을 정리한다.

6. API timeout을 피하는 잡 큐와 비동기 워커 패턴

수 초에서 수십 초 걸리는 리포트 생성을 동기 API로 처리하지 않고 job과 worker로 분리한 이유를 다룬다. job table, worker, object storage, polling 흐름을 설명한다.

7. 관리자 페이지에서 CORS는 왜 항상 터질까?

SPA와 API 도메인이 분리되었을 때 발생하는 CORS와 preflight를 정리한다. 쿠키 인증을 함께 사용할 때 Access-Control-Allow-Credentials, concrete origin, withCredentials가 왜 중요한지도 설명한다.

8. "무엇을 썼는가"보다 "왜 선택했는가"를 기록하기

아키텍처 문서는 기술 목록이 아니라 의사결정의 기록이어야 한다. 문제 상황, 선택지, 결정, 포기한 것, 다시 검토할 조건을 남기는 ADR 방식을 정리한다.

이런 상황에서 읽기 좋다

이 시리즈는 다음과 같은 상황에 특히 잘 맞다.

  • 사내 관리자 페이지나 운영 콘솔을 만들고 있는 개발자
  • React SPA를 AWS 위에 배포하려는 개발자
  • Lambda, API Gateway, S3, CloudFront를 실무적으로 조합해보고 싶은 개발자
  • 오래 걸리는 리포트 생성이나 파일 다운로드 기능을 설계해야 하는 개발자
  • 아키텍처 의사결정을 문서로 남기고 싶은 개발자
  • 포트폴리오나 면접에서 실무 설계 경험을 설명하고 싶은 개발자

시리즈를 읽는 방법

처음부터 순서대로 읽는 것이 가장 좋다. 1편에서 전체 경계를 나누고, 25편에서 배포와 백엔드 구조를 설명한 뒤, 67편에서 운영 중 자주 만나는 문제를 다룬다. 마지막 8편은 이런 결정을 문서로 남기는 방법을 정리한다.

이미 비슷한 운영 콘솔을 만들고 있다면 필요한 글부터 읽어도 된다.

  • 배포가 고민이라면 2편
  • 데이터베이스를 꼭 써야 하는지 고민이라면 3편
  • Lambda와 API Gateway 구성이 고민이라면 4편
  • 서버리스와 상주 서버 중 선택이 어렵다면 5편
  • 오래 걸리는 파일 생성이 고민이라면 6편
  • CORS와 쿠키 인증 때문에 막혔다면 7편
  • 설계 문서를 어떻게 써야 할지 고민이라면 8편

마무리

운영 콘솔은 화려한 제품은 아닐 수 있다. 하지만 실제 조직의 일이 흘러가는 곳이고, 기술 선택의 결과가 매일 드러나는 곳이다.

이 시리즈에서는 운영 콘솔을 만들며 마주친 선택들을 하나씩 꺼내본다. 중요한 것은 어떤 서비스를 썼는지가 아니다. 왜 그 선택을 했고, 무엇을 얻었고, 무엇을 포기했는지다.

그 기록이 쌓이면 단순한 개발 경험이 아니라, 시스템을 설계하고 운영하는 관점이 된다.

함께 볼 GitHub 저장소

Next Step 이 글은 StudyDad 작업 루프의 한 조각입니다.

글에서 정리한 생각은 GitHub의 코드와 포트폴리오로 이어지고, 일부는 FamBlend 같은 제품 실험으로 확장됩니다.