Pika 이미지 성능 개선: Rails, CloudFront CDN 및 Imgproxy 통합 경험

Rails, CloundFront CDN, and Imgproxy

작성자
HackerNews
발행일
2025년 10월 14일

핵심 요약

  • 1 Pika 프로젝트의 이미지 성능 개선을 위해 AWS CloudFront, S3, 그리고 Imgproxy를 활용한 CDN 스택을 성공적으로 구축했습니다.
  • 2 Imgproxy는 이미지 리사이징, Exif 데이터 제거, 압축 등 복잡한 이미지 처리 작업을 효율적으로 수행하며, S3로부터 이미지를 직접 로드하도록 설정되었습니다.
  • 3 Rails 애플리케이션에서는 imgproxy Gem을 사용하여 이미지 URL을 생성하고, 캐시 워밍업을 위한 백그라운드 작업 및 이미지 폭탄 방지를 위한 해상도 유효성 검사를 구현했습니다.

도입

이 글은 Pika 프로젝트의 이미지 성능 개선을 위한 CDN 구축 경험을 공유합니다. 25년간의 웹 프로그래밍 경력에도 불구하고 CDN을 직접 설정해본 경험이 없었던 저자는, 이번 기회에 Pika의 이미지 처리 스택을 최적화하기로 결정했습니다. 온라인 자료와 동료들의 도움을 받아 AWS CloudFront와 S3를 기반으로 하는 CDN을 구축하고, 이미지 처리에는 Imgproxy를 도입하여 효율적인 이미지 전송 시스템을 마련했습니다.

도구 선택 및 아키텍처

Pika는 기존 AWS 크레딧을 활용하여 CloudFront를 CDN으로, S3를 스토리지로 사용했습니다. 이미지 처리 파이프라인의 핵심은 John Nunemaker의 추천을 받은 Imgproxy입니다. Imgproxy는 이미지 리사이징, Exif 데이터 제거, 압축 등의 작업을 담당합니다. 전체적인 이미지 요청 흐름은 다음과 같습니다:

  • 사용자 요청: 브라우저가 캐시되지 않은 이미지를 요청합니다.

  • CloudFront: 리전 노드에서 요청을 받아 캐시 여부를 확인합니다.

  • CloudFront Origin Shield: 캐시 미스 시 Origin Shield를 통해 Imgproxy로 요청을 전달합니다.

  • Imgproxy: S3에서 원본 이미지를 가져와 필요한 처리(Exif 제거, 크기 조정, 압축)를 수행합니다.

  • S3: 원본 이미지를 저장하는 역할을 합니다.

Imgproxy 설정

Imgproxy는 Render.com에 Docker 컨테이너로 배포되며, 환경 변수를 통해 광범위하게 설정됩니다. 주요 설정은 다음과 같습니다:

  • IMGPROXY_TTL: 1년 (30758400초)으로 설정하여 캐시 효율을 극대화합니다.

  • IMGPROXY_FALLBACK_IMAGE_DATA: 1x1 투명 GIF를 대체 이미지로 사용합니다.

  • IMGPROXY_FORMAT_QUALITY: JPEG=90, PNG=90, WebP=79 등으로 압축 품질을 설정하여 과도한 압축을 방지합니다.

  • IMGPROXY_STRIP_COLOR_PROFILE: false로 설정하여 색상 정확도를 유지합니다.

  • IMGPROXY_MAX_SRC_RESOLUTION: 이미지 폭탄 공격을 방지하기 위해 최대 원본 해상도를 제한합니다.

  • IMGPROXY_USE_S3: true로 설정하여 Imgproxy가 S3에서 이미지를 직접 가져오도록 합니다. 이는 Rails 서버를 거치지 않아 효율적이지만, URL에 확장자가 없는 문제가 발생할 수 있습니다.

  • IMGPROXY_KEY, IMGPROXY_SALT: 보안을 위한 필수 설정입니다.

CloudFront 및 DNS 설정

CloudFront는 cdn.u.pika.page 도메인으로 설정되었으며, 사용자 지정 SSL 인증서가 적용되었습니다. Origin은 u.pika.page로 설정된 Imgproxy 인스턴스를 가리키며, Origin Shield는 활성화되어 캐시 효율을 높입니다. 동작(Behaviors) 설정에서는 객체 자동 압축을 비활성화하고, GET, HEAD, OPTIONS 메서드를 허용하며, 레거시 캐시 설정을 사용합니다. DNS는 cdn.u.pika.page를 CloudFront 배포 도메인으로, u.pika.page를 Imgproxy Origin으로 연결합니다.

Rails 애플리케이션 통합

Pika는 이미지를 S3에 업로드하도록 설정되어 있습니다. 이미지 URL 생성에는 imgproxy Gem이 사용됩니다. imgproxy.yml 설정 파일에서 IMGPROXY_FREE_CDN 환경 변수를 CloudFront CDN URL로 지정하고, 프로덕션 환경에서는 use_s3_urls: true를 설정하여 Imgproxy가 S3에서 직접 이미지를 가져오도록 합니다.

  • 아바타 URL 예시: User 모델에서 avatar.imgproxy_url을 사용하여 다양한 크기의 아바타 URL을 쉽게 생성합니다.

  • 리치 텍스트 이미지 처리: _blob.html.erb 파일에서 GIF 파일은 Imgproxy를 거치지 않고 직접 서빙하며, 다른 이미지는 imgproxy? 헬퍼 메서드를 통해 Imgproxy URL을 생성합니다.

  • 백그라운드 작업: 이미지 과부하를 방지하기 위해 새로운 게시물이 생성되거나 이미지가 편집될 때, 백그라운드 작업을 통해 CDN URL을 미리 쿼리하여 캐시를 워밍업합니다.

  • 이미지 해상도 검증: 이미지 폭탄을 서버 단에서 방지하기 위해 Active Storage 첨부 파일의 해상도를 검증하는 유효성 검사 로직을 구현했습니다.

로컬 개발 환경

로컬 개발을 위해 Docker와 Procfile_imgproxy.dev를 사용하여 Imgproxy 인스턴스를 http://localhost:7777에서 실행할 수 있도록 설정했습니다. 이는 개발 환경에서 Imgproxy의 동작을 쉽게 테스트할 수 있게 합니다.

결론

이번 CDN 및 Imgproxy 통합을 통해 Pika의 이미지 성능을 크게 향상시킬 수 있었습니다. 향후 GIF 파일 튜닝, WebP 및 AVIF 포맷 도입 등 추가적인 최적화 작업을 고려하고 있습니다. CDN 구현에 대한 초보적인 경험이었지만, 이 글이 다른 개발자들에게 도움이 되기를 바라며, 더 나은 설정 방법에 대한 피드백도 환영합니다. 이 과정에서 Ruby on Rails 애플리케이션의 이미지 처리 효율성을 극대화하는 방법을 모색하고 성공적으로 적용한 것이 핵심적인 성과입니다.

댓글 0

댓글 작성

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

아직 댓글이 없습니다

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