마이그레이션은 새로운 Rails 8 프로젝트를 생성하고 기존 Gemfile을 최신 호환 버전으로 업데이트하는 것부터 시작되었습니다. JuggleBee의 코드베이스가 잘 분리된 비즈니스 로직 컴포넌트로 구성되어 있어 마이그레이션이 비교적 원활했습니다. 특히, 모델과 컨트롤러는 과도하게 비대해지지 않았으며, ‘서비스 객체’와 ‘뷰 데코레이터’ 패턴을 활용하여 로직이 명확하게 분리되어 있었습니다.
모델, 컨트롤러, 서비스 및 뷰 마이그레이션:
- 모델: Ruby 2.2에서 3.4.3으로의 핵심 언어 변경은 미미했지만, Rails 아키텍처의 변화(예: ApplicationRecord
도입)에 대한 대응이 필요했습니다. 데이터베이스는 PostgreSQL 9.6에서 17.5로 업그레이드되었으며, 기존 마이그레이션 파일 대신 pg_dump
를 통해 schema.rb
를 생성하는 방식을 채택했습니다. belongs_to
에 optional: true
를 추가하고, update_attributes
를 update
로, 구식 유효성 검사 메서드를 최신 문법으로 변경하는 등의 작업이 이루어졌습니다. 뷰는 사용된 Haml, Redcarpet, Simple Form, Cocoon 등의 Gem이 활발히 유지보수되어 변경이 거의 필요 없었습니다.
- 컨트롤러: 서비스 객체를 활용한 복잡한 로직 분리 덕분에 마이그레이션은 대부분 순조로웠습니다. Rails 8의 강화된 규칙에 따라 파라미터는 JSON으로 유효해야 했고, before_filter
는 before_action
으로, redirect_to :back
는 redirect_back fallback_location: root_path
로 대체되었습니다. responders
Gem이 더 이상 포함되지 않아 respond_with
호출은 respond_to
블록으로 재작성되었습니다.
JavaScript 현대화:
프론트엔드 자산 관리 방식에 큰 변화가 있었습니다. Sprockets 대신 importmaps를 기본 자산 관리자로 채택하여 Chartkick, Masonry, Bootstrap 등 여러 프론트엔드 기능을 제공하던 Gem들을 importmaps pin 방식으로 대체했습니다. JavaScript 클래스들은 ES 모듈로 로드될 수 있도록 import
및 export
문을 사용하도록 변경되었으며, 파일 위치도 app/assets/javascripts/
에서 app/javascript/
로 이동했습니다. jQuery는 여전히 유지하기로 결정했습니다.
백그라운드 작업 및 스케줄링:
이 영역은 이번 마이그레이션의 가장 큰 성과 중 하나였습니다. 기존의 Sidekiq + Redis + Whenever(cron) 조합은 Rails 8에 내장된 SolidQueue로 대체되었습니다. SolidQueue는 Redis 없이 기존 데이터베이스(PostgreSQL)를 사용하여 작업 큐를 관리함으로써, 별도의 Redis 서비스와 컨테이너를 제거하고 서버 메모리를 확보할 수 있었습니다. whenever
Gem 역시 SolidQueue의 내장 recurring.yml
기능으로 대체되어 백그라운드 작업 관리가 훨씬 간소화되었습니다. 작업 인수는 JSON 직렬화 가능해야 한다는 점이 주요 변경 사항이었습니다.
인프라 및 배포: 오랫동안 작성자가 직접 작성한 쉘 스크립트를 사용하여 배포를 관리해왔습니다. 이 스크립트는 Docker 이미지 빌드, 컨테이너 재시작, 원자적 릴리스, 이전 배포 정리 등을 효율적으로 처리했습니다. 그러나 Rails 앱에 특화된 서버 프로비저닝 및 배포 도구인 Kamal 2의 도입으로 배포 프로세스가 혁신적으로 간소화되었습니다. Kamal은 Docker, Git 설치, Traefik(내장된 프록시 및 SSL 처리), 액세서리 관리(Postgres, Redis), 스케일링 등을 자동화하여 Nginx와 같은 추가적인 의존성을 제거했습니다. 이는 배포를 훨씬 빠르고 효율적으로 만들었으며, 인프라를 더욱 가볍고 유지보수하기 쉽게 만들었습니다.