Clip Show: 웹소켓 인증 개선, Kamal 배포 및 GitHub Actions CI/CD 구축 디버깅

Real Production Ruby on Rails/ReactJS App from scratch (Ep. 6) Kamal Deployment/Github Actions CI/CD

작성자
HackerNews
발행일
2025년 09월 05일

핵심 요약

  • 1 테스트 환경의 복잡한 웹소켓 인증 문제를 `alert_token` 기반으로 리팩토링하고, React `useCallback` 훅을 활용하여 성능 저하 버그를 해결했습니다.
  • 2 Heroku 대안으로 Kamal과 Digital Ocean을 활용한 Rails 애플리케이션 스테이징 배포를 성공적으로 구현하며, `deploy.yaml` 설정을 상세히 다루었습니다.
  • 3 GitHub Actions를 사용하여 CI/CD 워크플로우(Breakman, Rubocop, 테스트, Kamal 배포)를 구축하고, 환경 변수 및 SSH 키 관리의 난제를 해결했습니다.

도입

이번 에피소드에서는 Clip Show 빌드 시리즈의 중요한 전환점을 다룹니다. 개발팀은 테스트 환경에서 발생한 예상치 못한 웹소켓 인증 문제와 성능 저하 버그를 해결하며 애플리케이션의 안정성을 확보했습니다. 특히, 기존 쿠키 기반 인증의 한계를 인지하고 `alert_token`을 활용한 새로운 인증 방식으로 전환하는 과정은 복잡한 디버깅을 통해 이루어졌습니다. 이와 함께, Heroku의 높은 비용에 대한 대안으로 Kamal과 Digital Ocean을 선택하여 Rails 애플리케이션의 스테이징 배포 환경을 성공적으로 구축하고, GitHub Actions를 통한 CI/CD 워크플로우를 완성하는 여정을 상세히 공유합니다.

Clip Show 프로젝트는 여러 기술적 난관을 극복하며 진전을 이루었습니다.

웹소켓 인증 및 성능 문제 해결

  • 웹소켓 인증: 테스트 환경에서 AnyCable과 Rails 서버 간 쿠키 기반 인증이 실패하는 문제를 겪었습니다. Action Cable 엔드포인트 마운트가 AnyCable 인스턴스로 요청을 프록시하지 않는다는 점을 확인하고, alert_token 파라미터를 사용한 인증 방식으로 리팩토링했습니다.
  • 성능 저하: 클립 추가 시 큐잉 시스템이 느려지는 버그는 컴포넌트 리렌더링 시 이벤트 리스너가 중복 추가되는 것이 원인이었습니다. React의 useCallback 훅을 활용하여 안정적인 콜백 참조를 유지함으로써 이 문제를 해결했습니다.

Kamal을 활용한 Digital Ocean 배포

  • 배포 도구 선정: Heroku의 높은 비용을 대체하기 위해 Kamal과 Digital Ocean을 선택, 월 7달러 Droplet에 Rails, PostgreSQL, AnyCable을 호스팅하는 스테이징 환경을 구축했습니다.
  • deploy.yaml 설정: DockerHub 레지스트리 및 Digital Ocean IP를 host로 지정하고, Kamal 프록시를 통해 SSL을 종료하며 Let’s Encrypt를 활용했습니다. kamal_secrets로 민감 정보를 관리하고, PostgreSQL과 AnyCable을 액세서리로 정의, localhost 바인딩으로 외부 노출을 방지했습니다. AnyCable의 RPC 통신을 위해 ANYCABLE_RPC_HOST를 웹 서비스 컨테이너의 네트워크 별칭(clip_show_web)으로 명시하는 것이 중요했습니다. 자산 컴파일은 Dockerfile 내에서 SECRET_KEY_BASE_DUMMY=1 환경 변수 트릭을 사용하여 Vite 기반 자산 빌드 시 Rails 마스터 키 요구 사항을 우회했습니다.

GitHub Actions CI/CD 워크플로우 구축

  • CI (ci.yaml): Breakman 보안 스캔, Rubocop 린팅, 통합 테스트를 포함했습니다. AnyCable 컨테이너에서 호스트(테스트 잡)의 Rails 앱과 통신하기 위해 host.docker.internal을 사용했습니다. action-tmate를 이용한 SSH 디버깅 기능을 추가했습니다.
  • CD (deploy.yaml): master 브랜치로의 PR 병합 시 또는 수동 실행 시 작동합니다. webfactory/ssh-agent로 SSH 키를 설정하고, GitHub Secrets와 kamal_secrets 간 환경 변수 브리징을 통해 Kamal이 필요한 시크릿에 접근하도록 구성했습니다. 최종적으로 bin/kamal deploy를 실행하여 배포를 자동화했습니다.

결론

이번 에피소드는 Clip Show 애플리케이션의 안정성과 배포 효율성을 크게 향상시켰습니다. 복잡한 웹소켓 인증 및 성능 문제를 해결하고, Kamal과 Digital Ocean을 활용하여 Heroku보다 경제적인 스테이징 환경을 성공적으로 구축함으로써 프로덕션 준비를 마쳤습니다. 또한, GitHub Actions를 통한 견고한 CI/CD 파이프라인은 개발 프로세스의 자동화와 신뢰성을 보장합니다. 이러한 경험은 향후 서비스 확장 및 추가 액세서리 통합 시 개발팀에게 귀중한 자산이 될 것입니다. 다음 에피소드에서는 클라이언트 측 인터페이스 개발에 집중하여 시청자들이 직접 클립을 트리거할 수 있는 기능을 구현할 예정입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!