출시한 앱 160여 개를 혼자서 계속 돌아가게 하고 심사를 통과하게 하려고, 무엇을 공유하고 어떻게 출시하고 무엇을 재는지, 서버에는 무엇이 있는지 정리했습니다.
2026-10-08 갱신 · iOS · macOS · 안드로이드 · 웹
워크스페이스 하나에 여섯 개 도메인이 있고, 앱은 각각 자기 저장소를 씁니다. 공용 코드와 배포 레인, 규약은 특정 앱에 속하지 않고 따로 관리합니다.
App Store에 25개(iOS 20, macOS 5), Google Play에 150개가 올라가 있고, 두 스토어에 다 있는 앱을 한 번씩만 세면 160개 남짓입니다. iOS는 공용 레인 하나로 출시하고, 안드로이드는 Flutter 모노레포에서 빌드합니다.
워크스페이스 안의 프로젝트 디렉터리 기준, 2026-10-08 집계. 실제 스토어에 올라간 수는 이보다 적습니다. 만들어두고 아직 제출하지 않은 것이 있습니다.
결제, 분석, 리뷰 요청, 다국어, 개인정보 처리는 앱마다 새로 만들지 않고 공용 패키지에 둡니다. 안드로이드 쪽 공용 패키지는 10개이고, Flutter 앱 136개가 같은 UI 패키지를, 126개가 같은 결제·광고 패키지를 씁니다. iOS 쪽 공용 Swift 패키지도 10개입니다. 패키지를 고치면 그 패키지를 쓰는 앱 전부에 반영됩니다.
사용자 눈에 보이는 부분은 공유하지 않습니다. 기능, 화면을 만드는 디자인 시스템, 그래픽, 앱 고유의 콘텐츠는 앱마다 따로 만듭니다. 백엔드도 마찬가지로 앱마다 자기 서버를 두고, 공통 부분만 모듈 하나에서 가져옵니다.
전부 아래에 같은 코드가 있습니다.
출시 한 번은 빌드, 스크린샷, 36개 로케일 메타데이터, 제출까지입니다. 전부 브라우저가 아니라 스토어 공식 API로 처리합니다.
앱마다 배포 스크립트를 따로 두지 않습니다. iOS 앱 27개가 Fastfile 하나를 가져다 쓰고, 앱별 값은 다시 적지 않고 그 값이 이미 들어 있는 파일에서 읽습니다. 사람이 직접 하는 일은 실기기 확인과 출시 버튼 두 가지입니다.
키워드 순위는 앱별·국가별로 매일 쌓아 시계열로 봅니다. 사용 이벤트는 자체 수집기로 받아, 같은 제품의 iOS와 안드로이드를 한 줄로 봅니다.
사용 분석은 처음에 GA4로 했습니다. 무료 구성은 Firebase 프로젝트 하나에 앱 30개까지인데 앱 수가 이미 그보다 많았고, 프로젝트를 나누면 같은 제품의 iOS와 안드로이드가 다른 속성에 들어갑니다. 그래서 Cloudflare Worker와 D1로 수집기를 만들고, 클라이언트 패키지는 iOS용과 Flutter용을 하나씩 두었습니다.
사내 서비스 12개는 Go 서버이고, 각각 Docker 이미지 하나로 배포합니다. 키워드 순위 집계, 사용 분석, 광고 지표 수집, 리포트, 에셋을 만드는 GPU 작업, 나머지를 관리하는 콘솔이 모두 그렇습니다. 서비스를 옮기거나 되살릴 때는 이미지 하나를 옮기면 되고, 새 서비스도 같은 방법으로 붙입니다.
예전에는 자체 서버에 경량 쿠버네티스(K3s)를 올려 돌렸습니다. 이 정도 서비스 수에서는 클러스터에 드는 설정과 관리가 얻는 것보다 많아서 모두 Docker로 옮겼습니다.
이미지는 자체 러너에서 CI가 서비스별로 빌드해 레지스트리에 올리고, 서버는 받아 오기만 합니다. 빌드가 끝나면 콘솔이 웹훅을 받아 텔레그램으로 승인을 물은 뒤 컨테이너를 교체합니다.
앞단에는 nginx 리버스 프록시 하나가 있습니다. 예전에는 도메인 하나를 붙이려면 네 군데를 고쳐야 했는데, 지금은 콘솔에서 도메인을 추가하면 DNS 레코드와 HTTP 설정이 만들어집니다. 프록시 컨테이너 안의 감시 프로세스가 새 설정 파일을 보고 Let’s Encrypt 인증서를 받고, 인증서가 생기면 다른 감시 프로세스가 nginx를 다시 읽힙니다. 콘솔은 30초 안에 설정을 HTTPS로 바꾸고, 갱신은 12시간마다 확인합니다.
서버 모니터링도 콘솔이 합니다. 5분마다 서버별 CPU·메모리·디스크와 컨테이너 상태를 기록해 48시간 보관하고, 값이 90%를 넘거나 컨테이너가 실행 중이 아니면 텔레그램으로 알립니다.
GPU 작업 서버는 Ubuntu Server에서 ComfyUI를 Docker로 돌립니다. 런타임과 노드 버전을 이미지에 고정해 두어서, 업데이트로 노드가 깨지면 서버 안에서 고치지 않고 이전 이미지로 돌아갑니다.
반복되는 작업은 에이전트가 합니다. 출시 절차, 36개 로케일 메타데이터 갱신, 정책이 바뀌었을 때 앱 전체를 점검하는 일 같은 것들입니다.
절차는 스킬로 적어 둡니다. 스킬 44개와 에이전트 31개를 대상 코드와 같은 저장소에서 버전 관리하고, 규약 파일 7개(루트 1개, 도메인별 6개)에 영역마다 지킬 규칙을 둡니다. 세션이 끝나도 남아야 할 내용은 메모로 남기는데 지금 376개입니다. 같은 실수가 두 번 나오면 메모에서 규약으로, 규약에서 점검 스크립트나 권한 규칙으로 올립니다.
일의 성격에 따라 모델을 나눕니다. 구조를 정하거나 원인을 모르는 문제를 쫓는 일은 가장 강한 모델이 맡고, 빌드·업로드·콘솔 조작처럼 끝이 정해진 일은 가벼운 모델에 고정한 실행 에이전트가 맡습니다. 이렇게 나눈 근거는 7주 동안의 세션 기록(메인 세션 89개, 서브에이전트 실행 625회)입니다.