Fizzy 애플리케이션 배포 및 관리 전략
1. 배포 환경 설정 및 브랜치 전략
Fizzy 애플리케이션은 GitHub에서 소스 코드를 복제(clone)하여 시작합니다. deploy.yml 파일을 수정하여 웹 서버 IP 주소, SSH 사용자, SSL 설정(Cloudflare 프록시 사용 시 false 권장), 그리고 완전한 도메인 이름(FQDN)을 구성합니다. 이때, 메인(main) 브랜치에 직접 변경 사항을 적용하는 것은 향후 충돌 위험을 높이므로, git stash를 사용하여 변경 사항을 임시 저장하고 production과 같은 별도의 브랜치를 생성하여 개인적인 변경 사항을 관리하는 것이 중요합니다. 메인 브랜치는 원본 Basecamp 코드를 유지하고, 주기적으로 git pull을 통해 최신 상태를 유지한 후, git rebase를 사용하여 production 브랜치에 병합함으로써 변경 사항을 통합하고 유지보수성을 확보합니다.
2. Kamal을 활용한 배포 및 비밀 키 관리
Kamal을 이용한 배포를 위해 kamal init 명령어를 실행하여 kamal/secrets.yml 파일을 생성합니다. 애플리케이션 운영에 필수적인 secret_key_base, vapid_public_key, vapid_private_key는 bin/rails credentials:edit 명령어를 통해 Rails Credentials 파일에 안전하게 저장합니다. Rails.application.credentials.vapid.public_key와 같이 접근할 수 있도록 네임스페이스를 설정하고, Rails 콘솔에서 직접 키를 생성하여 적용합니다. 이 과정을 통해 민감한 정보가 코드 저장소에 노출되지 않도록 관리합니다. kamal setup 명령을 실행하면 Docker 설치를 포함하여 서버 환경 설정 및 애플리케이션 배포가 진행됩니다.
Fizzy 코드베이스의 주요 아키텍처 패턴
1. Gemfile 및 데이터베이스 구성
Gemfile을 살펴보면 Rails를 GitHub의 main 브랜치에서 직접 사용하며, SQLite3와 Trilogy(MySQL용)를 모두 포함하여 개발자가 데이터베이스 선택의 유연성을 가질 수 있도록 합니다. 배포 시에는 database.sqlite.yml 파일이 기본적으로 활용됩니다.
2. 멀티테넌시 구현
Fizzy는 Account 모델의 slug를 활용하여 독특한 멀티테넌시를 구현합니다. URL에서 slug를 추출하여 해당 계정을 찾고, 이를 요청 수명 주기 초기에 전역적으로 설정하는 미들웨어 방식을 사용합니다. 이는 서브도메인, 별도 데이터베이스 또는 복잡한 라우팅 로직 없이 멀티테넌시를 효율적으로 해결하는 방법입니다.
3. 엔트로피 기반 자동 연기(Auto-postpone) 로직
Account Settings에 설정된 entropy 값(3일, 7일, 30일, 90일, 1년, 그리고 재미있는 내부 농담인 11일)에 따라 Card 모델의 entropic 모듈에서 관련 로직을 처리합니다. 매시간 실행되는 백그라운드 작업을 통해 특정 조건의 카드를 “나중에(not now)” 컬럼으로 자동으로 이동시키는 기능을 제공합니다.
4. Active Job 확장
멀티테넌트 환경에서 백그라운드 작업 시 current_account 컨텍스트가 손실되는 문제를 해결하기 위해 Active Job을 확장합니다. 작업이 직렬화될 때 현재 계정의 글로벌 ID를 저장하고, 작업 실행 시 이를 조회하여 current_attribute로 설정함으로써 백그라운드 작업에서도 올바른 계정 컨텍스트를 유지합니다.
5. 모델 중심의 비즈니스 로직 및 컨트롤러 구조
Fizzy는 services 폴더 없이 모든 비즈니스 로직을 모델 폴더 내에 포함하는 ‘풍부한 도메인 모델(Rich Domain Model)’을 채택합니다. concerns 대신 특정 모델에 종속된 모듈은 해당 모델의 네임스페이스 폴더(예: Card 모델의 assignable 모듈은 card/assignable.rb)에 위치시킵니다. 컨트롤러는 표준 CRUD 액션 외에 특정 작업을 위한 네임스페이스 컨트롤러(예: 카드 닫기를 위한 ClosuresController)를 사용하여 역할을 명확히 분리합니다.
6. Rails 내부 확장
멀티테넌시 지원을 위해 Action Text, Active Storage, Active Storage Variants와 같은 Rails 내부 컴포넌트에도 account_id 컬럼을 추가하여 확장합니다. 이는 Rails의 내부 구조를 깔끔하게 확장하는 모범 사례를 보여줍니다.