CodePush 마이그레이션

AppCenter 서비스 종료 대응

CodePushReactNativeAppCenter
122025-04-03

AppCenter 서비스 종료

CodePush를 서비스하던 AppCenter가 2025년 3월 31일 서비스를 종료했다.

AppCenter Retirement announcement

코드푸시는 스토어 심사를 우회해서 유저에게 배포가 가능하다는 장점으로 널리 사용되어왔다. 긴급히 배포해야 하는 에러가 있을때에도 유용하게 사용할 수 있지만 개발팀 내부에서 qa를 진행할 때도 도움이 되었다. 코드푸시를 도입하기 전에는 수정사항을 공유하기 위해 배포를 하루에 5번씩 했는데 그 당시에는 배포 한번에 30분씩 걸렸었다. 코드푸시는 공유하는데 1분도 걸리지 않는다.


코드푸시 동작 원리

코드푸시는 ReactNative의 iOS와 android를 담당하는 네이티브 코드와 번들 파일이 분리 되어있는 구조 덕분에 가능하다.

Codepush Mechanism

앱을 실행할 때 지금 번들이 최신 버전인지 확인하고 최신버전이 아니라면 번들파일을 다운받아야 한다. 이때 필요한 번들파일을 업로드할 스토리지, 최신 번들인지 확인하는 API, 번들 파일을 다운받는 API등을 AppCenter가 제공해주고 있었다.

AppCenter Mechanism

그런데 이 무료 서비스가 종료된다니 앞날이 캄캄했다.


대응 방법

AppCenter 대체 서비스

번들 파일을 보관하고 사용자의 확인요청 API를 처리하는 유사 서비스는 AppCenter 외에도 많이 있다. Expo 에서도 EAS(Expo Application Services)를 제공하고 있고 AppCenter의 빈자리를 노리는 여러 서비스들이 만들어졌다. 하지만 회사 프로젝트는 어느정도 보수적으로 접근해야 하기 때문에 EAS를 제외하고는 지속가능성 항목에서 제외했다. 아래는 EAS의 가격 정책이다.

EAS pricing

Free plan은 1,000 MAUs 까지 가능하다. 유료는 기각이다.

AppCenter 서버 직접 돌리기

Azure Mechanism

AppCenter가 대신 돌려주던 서버를 내돈내고 서버를 돌리면 되는것이다.

마이크로소프트는 AppCenter 서비스를 종료 하면서 감사하게도 코드푸시 운영이 가능하도록 Visual Studio App Center CodePush Standalone Version 을 공개해서 직접 서버를 운영한다를 선택지를 열어주었다. StandAlone 버전은 마이크로소프트의 Azure를 기준으로 개발되었다. StandAlone 버전을 사용하면 장점이 기존 “개발자” ⇒ AppCenter ⇒ “유저”의 로직을 보존하기 때문에 코드 수정사항이 최소한이라는 점이 가장 크다. 물론 Azure를 사용한다는 전제에서다. 안타깝게도 우리회사는 작년에 Azure에서 AWS로 인프라 전체이관을 했다. 라이브 상태인 서비스 전체를 4달 걸려서 겨우 이관했는데 여기서 코드푸시 때문에 Azure 서버 한대만 돌리자는 말은 꺼낼수 없다. 그렇다고 StandAlone 버전을 AWS에서 사용할수 있게 개조하기에는 자신이 없었다.

제 3의 라이브러리 사용하기

바퀴를 재발명 하지 말라했다. StandAlone 버전을 AWS용으로 개조한 버전을 사용하면 된다. 열심히 찾아본 결과 AppCenter 없이 React Native CodePush 배포하기 라는 숨고의 블로그 포스트를 발견했다. AWS를 사용했고 번들 다운로드 시간이 7초 → 4초 로 줄면서 에러 Rollback 발생율이 4.5% → 0.4% 로 줄었다는 내용이 있었다. AppCenter 사용시 번들 다운로드 속도가 평균 5초정도 걸렸는데 네트워크 상태에 따라 20~30초 걸리는 경우도 있었다(특히 안드로이드에서 그랬다). AppCenter 마이그레이션 하면서 코드푸시 속도도 빨라지고 에러율도 줄인다? 우리 앱에도 적용하고 싶었다.

최종적으로 Soomgo-Mobile/react-native-code-push 를 사용하기로 했는데 물론 AWS S3를 이용하는점, 기존 코드푸시 사용법과 거의 유사한점, 관리가 잘 되고 있다는 점, 속도와 에러율 개선이 기대되는점 등의 이유도 있었지만 가장 큰 이유는 내가 이해가 되서였다. 이전에 코드푸시를 사용할때는 AppCenter와 코드푸시에 대한 이해도 없이 그저 사용법만 숙지하고 사용해왔다. 사실 관심이 별로 없었다. AppCenter의 종료 공지는 1년전부터 알았지만 막상 1달 앞으로 다가와서 급하게 진행했는데 번들 파일을 S3에 적재하기, 버전별 코드푸시 히스토리 관리하기, 앱에서 어떤 로직으로 업데이트 여부를 확인하고 앱을 재시작 하는지 등등 대강은 알게 되었다. 그래서 이 라이브러리가 버려지더라도 내가 이어서 관리 할 수 있겠다는 생각이 들었다. 그래서 선택했다.


마이그레이션

개발자는 S3에 버전 정보를 저장한 history json 파일과 js번들 파일을 업로드한다. 앱은 CloudFront에서 json으로 history파일을 확인한다. 앱은 CloudFront에서 js번들 파일을 다운로드 한다. 간단하게 3단계로 코드푸시 이관이 완료되었다. 정리하고 보니 매우 간단한데 거의 2주에 가까운 시간이 걸렸다. hermes 컴파일도 다시 손보고, 빌드도 안되고 분명히 시키는대로 했는데 코드푸시 에러가 떠서 라이브러리 코드를 분석하기도 했다. 코드를 봐서는 에러인것 같은데 자신이 없었다. ‘다른 숨겨진 로직이 있는것 아닐까?’, ‘의도된건 아닌가?’, 고민을 하루정도 하고 에러가 맞다고 생각하고 이슈를 만들고 풀리퀘를 했다. 개발자로 취업한지 3년이 다되가지만 오픈소스에 기여한것은 처음이었다. 거창한건 아니고 Optional chaning 에러라서 “?” 하나 추가했다. 놀랍게도 1시간만에 승인을 해주셨다 👍

S3 Mechanism

성능 분석

마이그레이션을 완료하고 과연 성능이 얼마나 향상되었는지 확인을 해보았다. 모든 기기 사무실 와이파이를 사용했고 fast.com 속도는 450 Mbps 였고 아이폰 11 pro를 사용했다. hermes 컴파일이 속도에 영향을 미치는지 궁금해서 한버전 안한버전 두번 진행했다. 속도 측정은 5번 측정해서 평균을 냈다. 오차범위를 크게 넘는 특이값은 없었다.

기존 AppCenter CodePush 성능 분석

non hermes version 번들 사이즈 iOS 8.5MB, android 8.2MB 업데이트 체크 API 호출: 1.37s 번들 파일 다운로드: 4.14s

hermes version 번들 사이즈 iOS 8.1MB, android 10.2MB 업데이트 체크 API 호출: 1.81s 번들 파일 다운로드: 4.40s

iOS는 hermes 컴파일 여부가 사이즈와 변화가 적은데 안드로이드는 hermes 컴파일을 했을때 용량이 늘어났다. hermes 컴파일 여부가 코드푸시 속도에 영향을 크게 미칠줄 알았는데 예상과 달랐다. AppCenter에서 번들을 다운받아 .zip 확작자 붙여서 압축 해제해서 봤는데 Source map은 들어있지 않았다. hermes 컴파일 과정에서 텍스트가 늘어나서 그런것으로 생각된다.

S3 코드푸시 성능분석

테스트 조건의 위와 동일한데 hermes 컴파일 버전만 진행했다. 번들 사이즈 iOS 9.2MB, android 9.2MB 업데이트 체크 json 호출: 0.09s (95% 개선) 번들 파일 다운로드: 1.18s (73% 개선)

업데이트 체크 로직이 0.1초도 안걸리는 믿기 힘든 결과가 나왔다. 처음에는 코드에 문제가 있는 줄 알고 한참 고민했다. 어떻게 이런 결과가 가능한지 고민을 해봤다.

기존 AppCenter는 API를 사용해서 유저, 서버, 스토리지가 데이터를 주고받았지만 지금은 유저와 스토리지가 직접 주고받는다. JSON 파일과 번들 파일이 CDN에 의해서 캐싱되어 있다. 마이그레이션 끝.