배달의민족 앱은 네이티브와 웹뷰가 섞인 하이브리드라, 웹 개발자가 수정 한 줄을 앱에서 확인하려면 코드 리뷰·테스트·CI 빌드·배포·캐시 무효화를 매번 다 거쳐야 했다. 이 왕복을 없애려고 사내 환경에 맞춘 터널링 프록시 ITDA(Instant Tunnel for Development Apps)를 만들어, 베타 앱의 특정 요청만 개발자 맥북의 로컬 서버로 흘려보낸다. 트래픽 전환 방식 3안을 비교해 CloudFront Function 의 302 redirect 를 택했다.
핵심 포인트- 브라우저 확장으로 앱 환경을 흉내내던 기존 방식은 앱에 새 기능이 나올 때마다 유지보수가 붙고 사내 업무 환경과 안 맞아 버그가 잦았다.
- 앱에는 여러 팀의 웹뷰가 함께 얹혀 있어 전체 요청을 로컬로 돌릴 수 없고, 사내 VPN 이 동적 IP 정책이라 개발자 컴퓨터를 고정 주소로 지목할 수도 없었다.
- 전환 주체를 엣지·앱·엣지로 달리한 3안을 비교해, CloudFront Function 이 ITDA 요청을 판별한 뒤 프록시로 302 redirect 하는 안을 채택했다.
- 터널은 방향을 뒤집어, 개발자 컴퓨터의 ITDA 클라이언트가 프록시로 웹 소켓을 먼저 열고 유지한다. 그래야 사내망 밖 모바일 기기에서 로컬까지 요청이 닿는다.
- 요청마다 고유 ID 를 붙여 웹 소켓 하나를 공유하고, 라우팅 규칙이 없거나 터널이 끊기면 원래 베타 환경으로 되돌리는 안전장치를 뒀다.
상세 정리- 기존 흐름 파악: 웹뷰가 DNS 조회로 CloudFront 주소를 확인하고 HTML 을 요청하면 CloudFront 가 S3 에서 가져와 응답한다. 이 흐름 위에서 어떤 요청을 로컬로 보낼지 식별할 지점을 먼저 찾았다.
- 제약 1: 앱에는 다른 팀의 웹뷰가 여럿 올라와 있어, 특정 사용자의 특정 요청만 골라내지 않으면 앱 전체가 망가진다.
- 제약 2: 사내 VPN 이 동적 IP 를 쓰기 때문에 목적지 컴퓨터를 IP 로 고정 지정하는 설계가 불가능했다.
- 제약 3: 요청이 출발하는 베타 앱은 사내망 밖이라, 사내망에 들어오기 전 구간의 보안을 따로 설계해야 했다.
- A안 CFF rewrite: 엣지에서 origin 만 ITDA 프록시로 바꾸는 방식. 앱 수정이 없고 웹뷰에 보이는 주소도 그대로지만, 내부 목적지를 직접 교체하는 구성이 보안 요구사항을 충족하지 못해 기각했다.
- B안 앱 내부 호스트 라우팅: 앱 네이티브 계층에서 특정 주소의 요청을 프록시로 보내는 방식. 웹은 원래 주소를 쓸 수 있지만 지원 도메인이 늘 때마다 앱 수정과 배포 일정이 걸리고, 웹 라우팅 정보와 책임이 앱에 쌓여 기각했다.
- C안 CFF redirect 채택: 같은 요청 안에서 목적지만 바꾸는 rewrite 와 달리, 웹뷰에 새 목적지를 알려주고 다시 요청하게 한다. 일반 베타 트래픽과 ITDA 트래픽의 흐름이 명시적으로 갈리고 새 도메인을 지원해도 앱을 안 건드린다.
- C안의 대가: 도메인이 바뀌므로 교차 출처를 제한하는 브라우저 보안 정책과 쿠키·세션 적용 범위를 함께 검토해야 한다. 이를 웹과 인프라에서 관리 가능하다고 판단해 감수했다. A안에서 쓰려던 CloudFront Function 은 origin 교체가 아니라 요청 판별 역할로만 남겼다.
- 판별 기준: 사용자가 베타 앱에서 ITDA 용 프로파일을 선택하면 최초 요청에 리모트 컨피그 프로파일 파라미터가 실린다. CFF 는 이 값만 읽어 ITDA 요청인지 가르고, 일반 요청이면 아무것도 바꾸지 않는다.
- 역할 분리: CFF 는 어느 개발자에게 보낼지까지 정하지 않는다. ITDA 가 처리할 요청인지만 판단하고 최소한의 라우팅 정보를 쿠키에 담아 넘기며, 실제 터널 선택은 프록시가 라우팅 규칙과 대조해 결정한다.
- 라우팅 규칙: 프로파일과 요청 대상, 현재 연결된 개발 터널을 묶는 규칙을 별도 DB 에 보관하고, 살아있는 웹 소켓 연결은 프록시가 직접 관리한다.
- 리소스 다중화: 화면 하나를 그리려면 HTML 외에 JavaScript, CSS, 이미지 요청이 따라붙는다. 요청마다 터널을 새로 만들지 않고 요청 ID 로 응답을 원래 요청과 짝지어, 여러 요청이 웹 소켓 하나를 공유해도 응답이 섞이지 않는다.
- 폴백: 맞는 라우팅 규칙이 없거나 연결된 터널을 못 찾으면 요청을 원래 베타 환경으로 돌려보낸다. ITDA 를 쓰지 않는 요청은 영향받지 않고, 개발 중 연결이 끊겨도 기존 베타 화면을 계속 볼 수 있다.
- 회고: 웹 소켓·프록시·터널링은 새로운 개념이 아니고 비슷한 도구도 이미 존재한다. 다만 사내 제약을 다 만족하지 못해 직접 만든 것이며, 자원과 환경이 달랐다면 다른 선택을 했을 거라고 정리한다.
왜 읽나하이브리드 앱의 웹뷰를 개발하며 확인 한 번에 배포 왕복을 치르는 팀, 그리고 CloudFront Function 과 웹 소켓 터널로 특정 트래픽만 분기하려는 인프라 엔지니어에게 채택안뿐 아니라 기각한 두 안과 그 이유까지 그대로 참고가 된다.