최근에 가장 만족하며 사용한 SaaS 프로덕트 중 하나여서 사용기를 공유해보려 한다.
코드앤버터란?
코드앤버터는 노코드 팝업 솔루션이다. 퍼플아이오에서 만들었는데, 이쪽은 이커머스 관련 스타트업이다. 아마 이커머스쪽 서비스를 만들면서 사용된 컴포넌트와 기술을 활용해 완전관리형 팝업 서비스를 런칭한 걸로 보인다.
원래도 퍼플아이오를 들어보긴 했었다. Purple Admin UI라고 Next와 Tailwind 기반으로 만든 어드민 템플릿이다. 이게 한 때 깃허브에서 유행했었는데, 나도 한 때 PHP로 백오피스 작업들을 많이 해봤기도 하고, 노드 기반으로 기술 스택을 옮긴 후에는 백오피스 작업이 없었는데, 나중에 백오피스 작업을 할 때가 오면 써봐야겠다 생각했었다. 아직 깔아서 시도는 못 해봤는데 나중에 해보면 되게 재밌을 것 같다.
왜 코드앤버터를 도입했는가?
원래 사이드 프로젝트로 진행하던 서비스가 있었다. 비록 사이드지만 나름 MAU 3~4만은 나오던 작지 않은 서비스였는데, 이걸 회사 안으로 들고 들어올 수 있는 기회가 생겼다. 그러다 회사의 지원을 받아 Product Owner를 겸하면서 제품의 방향성을 정하고, 실제 개발 과정을 거쳐서 제품 출시까지 경험해볼 수 있었다.
PO를 경험해보니까 한정된 시간 내에 어떤 작업을 해야 ROI를 높일 수 있을지 자연스럽게 고민하게 되었다. 사실 아무리 작은 서비스라도 서비스가 운영되기 위해 필요한 기능들이 적지 않다. 공지사항부터 업데이트 로그, 백오피스도 있으면 좋고, 팝업이나 알림 기능 등 자잘한 게 되게 많은데... 그걸 다 포함해서 개발하기는 리소스와 일정 모두가 부족했다. 특히 MVP 출시를 위해 스프린트를 진행하고 있었는데 그런 자잘한 기능 말고도 쳐내야 할 핵심 피쳐들이 많이 쌓여 있었다.
기존 팝업 시스템의 문제점
가장 고민했던 부분 중 하나가 바로 팝업 시스템이다. MVP로 출시하면 초반에 자잘한 기능 업데이트들이 이어서 런칭될꺼고, 장애나 크리티컬 버그가 발생하면 이를 알릴 수도 있어야 한다. 프로모션 이벤트를 태운다면 그걸 홍보할 수도 있어야 한다. 그래서 사실 팝업 시스템은 '필수 기능'은 아니지만 그래도 일정을 쪼개서 넣어야만 하는 기능 중 하나였다.
그런데 전통적인 방식의 팝업 시스템으로 만들려면 작업공수가 예상보다 너무 많이 들어간다.
일단 팝업의 종류가 늘어나면, 종류가 늘어날 때마다 개발공수가 들어간다. 예를 들어 인시던트 상황 전파를 위한 페이지 상단 한줄공지 같은거나, 메인 페이지 중앙 팝업 등 각 종류별로 스타일도 잡아줘야 하고, 코드도 다 작성해야 하고...
그럼 만약에 종류를 줄여서 2가지 정도 타입의 팝업 시스템을 만든다고 가정하자. 일단 최소한의 리소스를 써야하니 디자인은 UI 라이브러리들에서 제공하는 템플릿을 그대로 써보자. 그래도 내부 코드는 다 짜야하고 스타일도 다 잡아줘야 한다. "n일동안 보지 않기" 같은 기능이 들어가면 로컬스토리지같은 걸 써서 일일이 관리해줘야 한다. 이렇게 요구사항을 줄였는데도 최소 1~2일은 걸릴 것이다. 10일~15일짜리 스프린트에 1~2일이면 결코 짧은 기간이 아니다.
어떤 팝업을 띄워줄지 관리하는 것도 골칫거리다. 회사로 들어오기 전 사이드 프로젝트 단계에서는 이런 종류의 데이터를 S3+CF로 관리했다. 깃헙에 정적 파일 전용 레포를 만들고, Github Actions로 커밋이 있을 때 해당 레포와 S3 버킷을 동기화하도록 처리해줬다. 그러면 자연스럽게 히스토리 관리도 되고, 정적 파일로 서빙하기 때문에 안정성도 높아진다. 그런데 이렇게 하면 개발자만 팝업 정보를 관리할 수 있게 된다. 프로덕트가 어느 정도 궤도로 올라가면 아마 회사에 계신 다른 전문 PM/PO 분이 가져가실건데, 개발자가 아니기 때문에 깃헙에서 그렇게 팝업을 관리하는게 상당히 어려울 것이다. 뭐 한 분은 문서를 잘 써서 방법을 가르쳐드린다고 해도, 긴급한 공지같은 건 CS 팀에서도 칠 수 있을건데 그러면 전혀 대응이 안 될 것이다.
그러면 이제 자연스럽게 지옥으로 빠져든다. 백오피스를 만들어야하거나, DB에서 팝업 정보를 관리해야하거나, 백엔드에서 파일을 구워서 올려주도록 api도 만들어줘야하고, 적절히 권한 관리도 해줘야하고... 개발서버랑 실서버랑 분리해서 먼저 테스트해볼 수도 있어야 하고... 이렇게 되면 팝업에만 1~2주를 쓰게 된다. 정말 충격과 공포의 상황이 아닐 수 없다.
코드앤버터 도입하기
일단 도입 당시(23년 2월)에는 베타 기간으로 무료였다. 당시에는 23년 7월까지 베타를 진행했다고 봤던 것 같은데, 오랜만에 랜딩 페이지를 들어가봤더니 23년까지 베타를 진행한다고 변경되었다. 아무튼 무료 서비스여서 초기에 도입하는데 크게 어려움은 없었다.
Next.js 환경이었는데 개발자 문서를 보고 간단하게 스크립트만 추가하니 잘 동작했다.
// pages/_document.tsx
<script
src="https://buttr.dev/butter.js"
data-site-id={NEXT_PUBLIC_BUTTER_SITE_ID}
async
></script>
이렇게 짧은 코드를 넣어주기만 하면, 그 다음부터는 모든 작업이 NO CODE로 이뤄진다. 일반적으로 노코드 서비스에 대해 기능이 부족하지 않을까 많이 우려하는데, 코드앤버터는 필요한 기능들은 어느 정도 다 들어가 있게 느껴졌다.
정말 다루기 쉬운 WYSIWYG 에디터
팝업을 만들기 위해서 WYSIWYG 에디터를 사용한다. 이게 가끔 예상대로 잘 배치가 안 되기도 하는데, 전반적으로 원하는 모양을 잘 잡아서 배치할 수 있다. 아무리 숙련된 프론트엔드 개발자라도 대충 퍼블리싱 치고 기능 씌우고 하면 시간이 좀 걸리는데, 이건 비교도 안 되게 편하다. 차후에도 팝업 쪽은 개발 리소스를 전혀 투입하지 않으려면 이거 도입하는거밖에 방법이 없겠구나 싶었다.
특히 "n일동안 보지 않기" 등 기능도 설정으로 넣을 수 있어서 이 부분은 되게 만족스러웠다. 이런 세심한 기능들이 마음에 들었다. 참고로 개발자도구를 까보니 구현은 localStorage를 사용했다.
다양한 설정 옵션들
코드앤버터를 채택하게 된 큰 이유 중 하나가 바로 디테일한 설정이 가능하다는 점이다. 팝업을 보여줄 대상에 따라 페이지를 다르게 설정할 수도 있고, 기간 설정도 유연하게 되는 점이 참 좋은 것 같다. 이게 사실 일반적으로 팝업 시스템을 자체 구축한다고 하면 다 만들어야하는 부분인데... 정말 프로젝트 초기에 많은 시간을 아낄 수 있었다.
뒤에서 언급할건데 "제외 조건" 부분은 문의로 피드백을 보냈는데 2주만에 기능으로 반영되어 돌아왔다. 지금도 정말 유용하게 잘 사용하고 있다.
프로덕션 환경에서 팝업 관리하기
오늘 글에서 가장 핵심적으로 얘기하려고 했던 부분이다. 프로덕션 환경에서의 팝업 관리.
일반적으로 개발환경 구성은 회사나 제품별로 매우 상이한데, 현재 프로젝트는 '개발 - 스테이징 - 프로덕션' 의 3개 환경으로 구성되어 있다. 따라서 환경별로 다른 팝업을 테스트해보고, 검증이 완료되면 프로덕션으로 옮겨야 한다. 만약 이게 자체 구축이었다면 구조적으로 되게 고민이 많아질 수 있다. 왜냐하면 일반적으로 DB가 분리되어 있고, 각 환경은 서로 독립적으로 동작해야하기 때문에, 특정 환경에서 다른 환경으로 데이터를 옮기는게 불가능하다. 물론 가능하게 만들려면 만들 수 있겠지만 대부분 선호되지 않는 방식이다.
이걸 코드앤버터는 단순히 '복제' 기능을 만듦으로써 해결했다.
구조적으로 봤을 때 가장 먼저 떠오른 것은 쿠버네티스 환경에서 2개 이상의 환경을 관리하기 위해 따로 Management Cluster를 둔다는 컨셉이다. 실제 어플리케이션 레벨은 각 환경별 클러스터에서 구동되지만, CI/CD와 모니터링 등 공통으로 처리되어도 되는 부분들은 공통 관리 클러스터로 뺀다는 내용이다. 이걸 그대로 가져와서 살펴보면 3개의 Dev, Staging, Production 환경을 코드앤버터가 중앙에서 각각 컨트롤할 수 있기 때문에 특정 환경의 설정 정보를 다른 환경에 쉽게 이식이 가능하고, 이는 프로덕션 레벨에서 활용하기 좋다는 의미가 된다. 코드앤버터가 Management Cluster로의 역할을 한다는 얘기다.
다른 환경에서 만든 팝업을 아래와 같이 모달창을 통해 다른 환경으로 복제할 수 있다.
복제 버튼을 누르면 일단 비공개 상태로 복제가 되고, 복제된 환경에서 공개 설정을 만져서 공개로 바꿀 수 있다.
피드백을 보냈는데 2주만에 반영되었다
그렇게 프로덕션 레벨에서 코드앤버터를 사용하다 이슈를 하나 발견했다.
현재 프로젝트가 영상 관련 서비스라서 영상을 외부로 공유 (embed) 하는 경우가 있는데, 이 때 외부에서 iframe으로 임베드할 때도 공지 팝업이 떠버려서 불편을 겪는 유저가 있었다. 그래서 특정 주소만 노출을 안 할 수 있도록 가능한지 문의했다.
그렇게 문의한 지 얼마 지나지 않아 3월 31일에 첫 답변을 받았다!
친절하게 js sdk로 특정 주소 노출 제어가 가능하다는 설명과 함께 기능 반영도 해보겠다는 답변을 받았다! 아쉽게도 이 때 js sdk를 바로 도입하지는 못 했는데, 개발 우선순위상 밀려서 다른 작업들을 먼저 치고 있었고, Next.js 환경에서 어떻게 적용할지가 좀 애매했다. 아무튼 그렇게 기능 추가를 기다리고 있었는데...
4월 13일, 그러니까 정확히 2주만에 기능이 추가되었다고 연락을 받았다. 사실 깜짝 놀랐다. 이렇게 바로 기능이 추가될꺼라 크게 기대 안 하고, 그냥 내부 코드로 개선하려고 백로그에 넣어두고 있었는데 빠르게 반영되다니!
그렇게 지금은 임베드 페이지에 한해서 공지를 노출하지 않게 해서 아주 잘 사용하고 있다.
안정적인 운영이 가능한 이유
처음에는 과연 이 서비스가 많은 트래픽이 발생했을 때 장애가 발생하지는 않을까? 또는 장애가 발생해서 우리 프로덕트에 영향을 끼치지는 않을까? 하는 고민을 했다. 그 때 트윗을 하나 보게 되었다.
이번 코드앤버터 구성의 핵심은 팝업 설정을 json 파일로 만들어 CDN으로 제공하는 거
— subicura (@subicura) July 26, 2022
동접 100만도 문제없다! 파일시스템 최고! ㅎㅎ
이제 많은 것들이 이해되기 시작했다. 어떻게 저 서비스를 저렇게 저렴한 가격으로 운영하려 하지? 아 S3+CF 구성으로 정적 서빙하면 충분히 가능하겠구나! 이러면 CF를 쓰기 때문에 (CDN을 타기 때문에) 안정적으로 전세계에 서빙이 가능하고, 트래픽 비용도 적게 들어 운영도 괜찮겠구나 싶었다. 그래서 '아 장애 걱정은 안해도 되겠다'는 생각에 마음 편하게 도입할 수 있었던 것 같다.
오늘 글을 작성하려고 개발자 문서를 열어봤는데 '동작방식 소개'라는 글이 추가되어 있었다.
개인적으로 참 좋아하는 구조인데, 내용이 많아서 핵심적인 부분만 간단하게 정리하자면 다음과 같다.
- MSA 구조로 되어 있고 웹 관련 코드 조각들은 Monorepo 안에 구성되어 있다.
- 랜딩페이지와 Docs는 각각 Vercel, GitHub Pages 등 관리형 서비스로 배포되고, 나머지 앱들은 EKS로 배포된다.
- CI/CD는 Jenkins - ArgoCD로 일반적인 GitOps Flow를 따라간다. (values.yaml 을 변경한다는 걸로 보아 Helm을 사용하는 듯 하다) 정적 파일은 Jenkins에서 바로 구워서 S3로 올리는 듯 하다.
- 테스트코드도 잘 작성되어 있다. 테스트도 Jenkins에서 실행되는 듯 하다.
구조적으로도 2023년답게 잘 설계되어 있고, 성능과 비용 측면을 고려하여 정적 파일을 최대한 활용한 부분도 인상 깊었다.
정리 및 총평
실제 프로덕션 환경에서 아주 유용하게 사용했고, 지금도 계속 사용 중인 만큼, 프로덕션 환경에서 충분히 활용할 수 있다고 검증된 것 같다. 특히 서비스가 아키텍쳐 면에서도 잘 짜여져있고, 저렴한 비용으로 안정적인 운영도 가능할 것으로 보인다. 그나마 가장 아쉽다고 할만 한 부분이 에디터였는데, 이것도 점점 개선되는 것 같다.
그간 5~6개월가량 사용해봤는데 초기 스타트업이거나, 제품 초기에 MVP를 만들어가는 단계의 프로덕트에 매우 추천하고 싶다. 기본적으로 노코드이기 때문에 대부분의 케이스에 적합하긴 하지만, 개발 리소스가 충분한 일정 규모 이상의 프로덕트에서는 오히려 자체 개발하는게 장기적으로는 요구사항 맞추기에 더 적합할 수 있을 것 같다.
앞으로가 더 기대되는 프로덕트인 것 같다. 코드앤버터의 성장과 성공을 기원한다!