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
를 실행하여 배포를 자동화했습니다.