헤르메스 가이드
Cloudflare R2로 이미지 서버 만들기
헤르메스 가이드

Cloudflare R2로 이미지 서버 만들기

핵심 판단

Cloudflare R2는 AWS S3와 비슷한 객체 스토리지이면서 인터넷 egress 비용이 없는 것이 강점입니다.

  • 아래 목차에서 필요한 절차만 골라 읽으면 됩니다.

Cloudflare R2를 헤르메스 홈페이지의 이미지 서버, 첨부 파일 서버, AI 산출물 저장소로 쓰는 방법 — 가격, 무료 한도, egress 무료의 의미, 커스텀 도메인, 캐시, presigned URL, 보안, Hermes 자동화 운영까지 상세 정리

이 글의 결론부터 — R2는 헤르메스 홈페이지 파일 서버로 좋은가

결론부터 말하면, Cloudflare R2는 헤르메스 홈페이지의 이미지 서버, 첨부 파일 서버, 다운로드 파일 저장소로 매우 좋은 선택지입니다. 특히 블로그형 사이트, AI 에이전트 운영 문서, 튜토리얼 이미지, 스크린샷, 생성 이미지, PDF, 음성 파일, 작은 동영상 파일처럼 읽기 트래픽이 많고 파일 자체는 정적인 경우에 잘 맞습니다.

다만 표현을 정확히 해야 합니다. R2는 흔히 "무제한 트래픽"이라고 불리지만, 이것은 인터넷 egress 요금이 무료라는 뜻에 가깝습니다. 저장 용량, 요청 수, Infrequent Access 검색 처리비 같은 비용은 여전히 존재합니다. 그러므로 "트래픽 비용 때문에 갑자기 수십만 원이 나오는 구조를 피하고 싶다"에는 강하지만, "아무 사용량이나 전부 무료"는 아닙니다.

헤르메스 홈페이지 기준으로 추천하는 구조는 다음과 같습니다.

용도추천 방식이유
공개 이미지R2 + Custom Domain + Cloudflare Cache이미지 트래픽 egress 부담이 작고 CDN 캐시를 활용하기 좋음
공개 다운로드 파일R2 + Custom DomainPDF, zip, 자료 파일 배포에 적합
비공개 첨부 파일R2 private bucket + Worker 또는 presigned URL원본 버킷을 숨기고 권한을 통제 가능
사용자가 올리는 이미지서버에서 presigned URL 발급 후 브라우저가 직접 업로드Next.js 서버 부하와 업로드 병목 감소
AI가 생성하는 결과물Hermes가 파일 생성 후 R2 업로드, URL만 사이트에 기록24시간 자동 콘텐츠 운영에 적합

즉 헤르메스 홈페이지를 장기 운영한다면, Vercel이나 앱 서버에는 코드와 페이지 렌더링만 맡기고, 이미지와 파일은 R2로 분리하는 것이 안전합니다. 이렇게 하면 사이트가 커져도 서버 디스크, 배포 용량, 이미지 트래픽, 백업 정책을 훨씬 단순하게 관리할 수 있습니다.


Cloudflare R2를 한 문장으로 이해하기

Cloudflare R2는 AWS S3와 비슷한 객체 스토리지인데, Cloudflare 네트워크와 붙어 있고 인터넷 egress 비용이 없는 파일 저장소입니다.

객체 스토리지는 폴더처럼 보이지만 실제로는 key와 object의 조합입니다. 예를 들어 다음과 같은 주소를 생각하면 됩니다.

개념예시
버킷hermes-assets
객체 keyimages/posts/r2-guide/hero.webp
공개 URLhttps://assets.example.com/images/posts/r2-guide/hero.webp
원본 API endpointhttps://ACCOUNT_ID.r2.cloudflarestorage.com

일반 웹 서버의 파일 시스템과 다른 점은, 디렉터리에 파일을 저장하는 느낌이 아니라 이름표가 붙은 파일 덩어리를 저장하고 HTTP 또는 S3 API로 꺼내 쓰는 구조라는 점입니다. 그래서 이미지, 문서, 백업 파일, 동영상 조각, 데이터셋, AI 결과물처럼 "한 번 저장한 뒤 여러 번 읽는 파일"에 적합합니다.

R2의 핵심 포인트는 네 가지입니다.

핵심설명
S3 호환boto3, AWS SDK, rclone, s3cmd 같은 기존 도구를 상당 부분 그대로 사용 가능
egress 무료인터넷으로 나가는 데이터 전송 자체에 별도 egress 비용을 붙이지 않음
Cloudflare CDN 결합커스텀 도메인을 붙이면 캐시, WAF, Access, Bot Management 같은 Cloudflare 기능과 조합 가능
Workers 통합Cloudflare Workers에서 R2 버킷을 binding으로 연결해 인증, 리사이징, 프록시, API 서버를 만들 수 있음

헤르메스 홈페이지처럼 공개 글과 이미지가 계속 늘어나는 사이트에서는 이 네 가지가 모두 중요합니다. 글은 Next.js가 렌더링하고, 이미지는 R2가 들고 있고, Cloudflare가 전 세계 엣지에서 캐시해 주면 구조가 깔끔해집니다.


무제한 트래픽이라는 말의 정확한 의미

R2를 설명할 때 가장 많이 나오는 말이 "egress fee 없음"입니다. 이것을 한국어로 쉽게 말하면 파일을 밖으로 내보내는 데이터 전송량에 대해 별도 요금을 받지 않는다는 뜻입니다.

예를 들어 2MB짜리 이미지를 100만 번 다운로드하면 단순 계산으로 약 2TB의 트래픽이 생깁니다. AWS S3나 다른 클라우드에서는 이 egress가 비용의 핵심이 될 수 있습니다. R2는 이 부분을 무료로 내세웁니다. 그래서 이미지 서버, 파일 배포 서버, 정적 자산 서버에서 매력적입니다.

하지만 다음 비용은 남아 있습니다.

비용 항목남아 있는가설명
저장 용량있음GB-month 기준으로 과금
요청 수있음PUT, LIST 같은 Class A와 GET, HEAD 같은 Class B 요청 과금
Infrequent Access 검색 처리비있음낮은 저장 단가 대신 읽을 때 검색 처리비 발생
Workers, Images, Stream 등 다른 Cloudflare 제품별도R2와 같이 쓰면 해당 제품의 과금은 별도로 계산
도메인, WAF, Rate Limiting 등 유료 기능플랜별Free/Pro/Business/Enterprise 플랜에 따라 기능 차이 존재

그러므로 실전 표현은 이렇게 잡는 것이 정확합니다.

흔한 표현더 정확한 표현
R2는 무제한 트래픽 무료다R2는 인터넷 egress 요금이 무료이며, 저장 용량과 요청 수는 과금된다
이미지 서버 비용이 0원이다무료 한도 안에서는 0원일 수 있지만, 요청 수와 저장량이 늘면 비용이 생긴다
r2.dev로 바로 서비스하면 된다r2.dev는 개발용이고, 프로덕션은 커스텀 도메인이 권장된다
S3와 완전히 같다S3 API 호환이지만 ACL, Object Lock, 일부 SSE/KMS, tagging 등 미지원 기능이 있다

헤르메스 홈페이지 운영 관점에서 중요한 것은 "트래픽이 터져도 egress 폭탄을 피할 수 있다"는 점입니다. AI 글이 갑자기 공유되어 이미지 조회가 늘어도 저장소 egress 때문에 큰 비용이 튀는 구조를 피할 수 있습니다.


가격 구조와 무료 한도

2026년 4월 기준 공식 문서의 R2 가격 구조는 다음과 같이 이해하면 됩니다. 실제 과금은 Cloudflare의 최신 가격표와 계정 플랜에 따라 달라질 수 있으므로 운영 전 반드시 대시보드에서 다시 확인해야 합니다.

항목StandardInfrequent Access
저장 용량GB-month당 0.015달러GB-month당 0.01달러
Class A 요청100만 건당 4.50달러100만 건당 9.00달러
Class B 요청100만 건당 0.36달러100만 건당 0.90달러
데이터 검색 처리비없음GB당 0.01달러
인터넷 egress무료무료, 단 읽을 때 검색 처리비는 별도
무료 한도10GB-month, Class A 100만, Class B 1000만무료 한도 적용 안 됨

Class A와 Class B는 요청 종류입니다. 아주 단순하게 보면 다음처럼 이해하면 됩니다.

요청 분류대표 작업느낌
Class A객체 업로드, 목록 조회, 멀티파트 생성, 복사, lifecycle transition쓰기와 관리 작업
Class B객체 다운로드, head 조회읽기 작업

이미지 서버에서는 보통 GET 요청이 많으므로 Class B가 중요합니다. 다만 커스텀 도메인과 Cloudflare Cache를 잘 쓰면 같은 이미지를 매번 R2 원본에서 읽지 않고 엣지 캐시에서 처리할 수 있습니다. 그러면 R2 요청 수와 원본 부하도 줄어듭니다.

무료 한도는 작은 개인 사이트에는 꽤 넉넉합니다. 예를 들어 헤르메스 홈페이지에 글 이미지와 작은 첨부 파일을 올리는 정도라면 처음에는 무료 한도 안에서 시작할 가능성이 큽니다. 하지만 다음 상황에서는 비용을 다시 계산해야 합니다.

상황주의점
이미지가 수만 장 이상으로 늘어남저장 용량 비용 증가
캐시가 잘 안 먹는 동적 URL 사용원본 GET 요청 수 증가
사용자 업로드가 많음PUT 요청, 저장 용량, 검수 비용 증가
대용량 동영상 배포egress는 무료라도 저장 용량, 요청 수, 동영상 서비스 방식 검토 필요
Infrequent Access를 잘못 사용읽을 때 검색 처리비와 30일 최소 저장 기간 때문에 오히려 비쌀 수 있음

운영 팁은 단순합니다. 처음에는 Standard로 시작하고, 정말 오래 보관하지만 거의 읽지 않는 백업성 파일만 Infrequent Access를 검토하는 것이 좋습니다. 홈페이지 이미지처럼 언제든 읽힐 수 있는 자산은 Standard가 더 안전합니다.


헤르메스 홈페이지에 R2가 잘 맞는 이유

헤르메스 홈페이지는 일반 블로그보다 파일 서버 분리가 더 중요합니다. 이유는 글만 올라가는 사이트가 아니라, AI 에이전트가 계속 이미지, 스크린샷, 로그, 리포트, 음성, PDF 같은 결과물을 만들 수 있기 때문입니다.

상황별로 보면 더 명확합니다.

상황R2가 필요한 이유
Hermes가 자동으로 글 초안을 만들고 이미지까지 생성생성 이미지를 앱 repo에 넣으면 배포 용량과 Git 이력이 무거워짐
OpenClaw나 Hermes가 브라우저 QA 스크린샷을 남김스크린샷을 R2에 올리고 URL만 보고서에 남기는 편이 깔끔함
사용자가 Q&A에 이미지를 첨부앱 서버가 파일을 오래 들고 있지 않고 R2에 보관하는 구조가 안전함
포스트에 대형 비교표 이미지나 인포그래픽 사용CDN 캐시와 egress 무료 조합이 유리함
나중에 뉴스레터, 자료실, 앱 다운로드 제공파일 배포 서버를 미리 분리해 두면 확장 쉬움

특히 Next.js 프로젝트를 Vercel에 배포할 때는 이미지와 파일을 Git 저장소에 계속 넣는 방식이 장기적으로 좋지 않습니다. 파일이 늘수록 repository가 무거워지고, 빌드 시간이 늘고, 롤백과 캐시 관리도 복잡해집니다. R2를 쓰면 사이트 코드는 Git/Vercel에, 파일은 R2/Cloudflare에 분리됩니다.

권장 사고방식은 다음과 같습니다.

자산 종류보관 위치
소스 코드, 글 데이터, 컴포넌트Git repository
공개 이미지, 첨부 PDF, 다운로드 파일R2 public custom domain
비공개 원본 파일, 임시 업로드R2 private bucket
생성 로그, AI 작업 산출물R2 또는 DB, 목적에 따라 분리
작은 아이콘과 핵심 로고프로젝트 public 폴더 또는 R2, 변경 빈도에 따라 선택

헤르메스 AI 에이전트와도 궁합이 좋습니다. Hermes가 글을 만들고, 이미지 파일을 압축하고, R2에 올리고, URL을 포스트 markdown에 삽입하는 운영 루프를 만들 수 있습니다. 사람은 최종 검수와 승인만 맡으면 됩니다.


처음 설정 순서 — 계정, 버킷, 토큰, 도메인

초기 설정은 크게 네 단계입니다.

R2 활성화

Cloudflare 대시보드에서 Storage & databases 메뉴의 R2로 들어가 활성화합니다. 무료로 시작할 수 있지만, 계정과 지역에 따라 결제수단 등록이 필요할 수 있습니다. 무료 한도 안에서는 보통 실제 청구가 발생하지 않지만, 결제수단 등록은 Cloudflare가 사용량 초과 과금을 처리하기 위해 요구할 수 있습니다.

운영 전 확인할 것:

확인 항목이유
결제수단 등록 여부R2 활성화와 사용량 초과 대비
계정 IDS3 endpoint와 API 설정에 필요
현재 플랜WAF, Rate Limiting, Access 같은 부가 기능 제한 확인
팀 접근 권한혼자 운영이 아니라면 토큰과 권한 분리 필요

버킷 생성

버킷 이름은 나중에 바꾸기 어렵다고 생각하고 정하는 것이 좋습니다. 헤르메스 홈페이지라면 다음처럼 분리할 수 있습니다.

버킷용도공개 여부
hermes-public-assets공개 이미지, 공개 다운로드 파일공개
hermes-private-uploads사용자 원본 업로드, 검수 전 파일비공개
hermes-agent-artifactsAI 작업 산출물, QA 스크린샷, 리포트보통 비공개 또는 제한 공개
hermes-backups백업성 파일비공개

처음에는 하나의 public assets 버킷으로 시작해도 됩니다. 하지만 사용자 업로드나 비공개 자료가 생기는 순간 공개 버킷과 비공개 버킷은 분리해야 합니다.

API 토큰 발급

R2 Overview에서 Manage R2 API Tokens로 들어가 토큰을 발급합니다. 중요한 원칙은 권한을 최소화하는 것입니다.

토큰 종류권한사용 위치
배포/운영 토큰특정 public assets 버킷 Object Read & WriteCI, Hermes 운영 서버
업로드 전용 토큰특정 버킷 쓰기 중심업로드 서버 또는 Worker
읽기 전용 토큰Object Read only백오피스, 검수 도구
전체 계정 토큰가능하면 피함긴급 운영 외에는 비추천

Access Key ID와 Secret Access Key는 생성 직후 한 번만 제대로 볼 수 있다고 생각하고 안전하게 보관해야 합니다. Git, 클라이언트 코드, 공개 문서, 이미지에 절대 넣으면 안 됩니다.

S3 endpoint 확인

R2의 S3 호환 endpoint는 다음 형태입니다.

항목
Endpointhttps://ACCOUNT_ID.r2.cloudflarestorage.com
Regionauto
Bucket생성한 버킷 이름
Access Key IDR2 토큰 발급 시 표시된 값
Secret Access KeyR2 토큰 발급 시 표시된 값

AWS SDK를 사용할 때 region을 auto로 넣는 것이 기본입니다. 일부 호환 도구에서는 us-east-1 또는 빈 값도 동작할 수 있지만, 새 설정은 auto로 통일하는 것이 이해하기 쉽습니다.


이미지 서버로 공개하는 방법 — r2.dev와 커스텀 도메인

R2 버킷은 기본적으로 비공개입니다. 웹사이트 이미지로 쓰려면 공개 접근 방식을 정해야 합니다.

r2.dev 개발 URL

r2.dev는 Cloudflare가 제공하는 개발용 공개 URL입니다. 대시보드에서 Public Development URL을 켜면 https://pub-xxxx.r2.dev/... 형태로 접근할 수 있습니다.

장점은 간단합니다.

장점설명
설정이 빠름도메인 없이 바로 테스트 가능
개발 확인에 충분업로드된 이미지가 잘 보이는지 빠르게 확인 가능
별도 DNS 작업 없음Cloudflare zone 연결 전에도 테스트 가능

하지만 프로덕션에는 권장하지 않습니다.

한계설명
rate limit초당 수백 요청 수준에서 429 Too Many Requests가 발생할 수 있음
캐시·WAF 활용 제한Cloudflare Cache Rules, WAF, Access, Bot Management 같은 기능을 제대로 쓰기 어려움
도메인 브랜딩 부적합pub-xxxx.r2.dev 주소는 사이트 자산 주소로 보기 좋지 않음
CNAME 연결 불가r2.dev 서브도메인을 CNAME으로 붙이는 방식은 지원되지 않음

따라서 r2.dev는 "업로드 테스트용"으로만 쓰고, 실제 헤르메스 홈페이지에는 커스텀 도메인을 붙이는 것이 좋습니다.

커스텀 도메인

프로덕션 추천 방식은 assets.vibecoding365days.com 같은 서브도메인을 R2 버킷에 연결하는 것입니다. 조건은 해당 도메인의 DNS가 Cloudflare에서 관리되고 있어야 한다는 점입니다.

설정 순서:

단계설명
1R2 버킷 Settings로 이동
2Custom Domains에서 Add custom domain 선택
3assets.example.com 같은 서브도메인 입력
4Cloudflare가 DNS 레코드를 자동 생성하거나 안내
5상태가 Active가 될 때까지 대기
6https://assets.example.com/path/to/file.jpg 형태로 접근 확인

커스텀 도메인을 쓰면 Cloudflare의 장점이 살아납니다.

기능효과
CDN Cache자주 보는 이미지를 엣지에서 제공해 R2 원본 요청 감소
Cache Rules파일 확장자별 TTL, Cache Everything 같은 정책 가능
WAF비정상 요청, 봇, 공격성 트래픽 차단 가능
Access특정 파일 영역을 로그인 뒤에만 보이게 구성 가능
Bot Management봇 트래픽 제어 가능, 플랜별 차이 있음
깔끔한 URL브랜드 도메인으로 이미지 주소 관리

헤르메스 홈페이지 추천 도메인은 다음 중 하나입니다.

후보추천도설명
assets.vibecoding365days.com매우 추천이미지, CSS성 자산, 다운로드 파일을 포괄
files.vibecoding365days.com추천다운로드와 첨부 파일 느낌이 강함
images.vibecoding365days.com조건부이미지 전용이면 좋지만 나중에 PDF, audio까지 담기 애매할 수 있음
cdn.vibecoding365days.com가능CDN 느낌은 좋지만 실제 원본이 R2라는 의미는 덜 명확

개인적으로는 assets.vibecoding365days.com을 추천합니다. 이미지뿐 아니라 PDF, 썸네일, 음성, 작은 다운로드 파일까지 자연스럽게 포괄할 수 있기 때문입니다.


업로드 방법 5가지 — 대시보드, Wrangler, Python, JavaScript, rclone

R2 업로드 방법은 운영 단계에 따라 달라집니다.

방법적합한 상황
대시보드 UI한두 개 파일을 사람이 직접 올릴 때
Wrangler CLI개발자 로컬, Cloudflare Workers와 함께 운영할 때
Python boto3Hermes Agent, 배치 스크립트, 이미지 자동 업로드
JavaScript AWS SDKNext.js API route, Node.js 서버, 업로드 서비스
rclone기존 파일 대량 이전, 백업, 동기화

대시보드 UI

버킷에 들어가 Upload를 누르고 파일을 드래그하면 됩니다. 가장 쉽지만 반복 운영에는 적합하지 않습니다. 글 하나 작성하면서 대표 이미지 하나를 올리는 정도는 괜찮습니다.

실전 팁:

상황
파일명이 한글가능하면 영문 소문자와 하이픈으로 바꾸기
이미지가 큼업로드 전 webp 또는 avif로 압축
나중에 교체 예정파일명을 그대로 덮어쓰기보다 버전 파일명 사용 권장

Wrangler CLI

Cloudflare 개발 환경을 이미 쓰고 있다면 Wrangler가 편합니다.

명령 예시:

wrangler r2 bucket create hermes-public-assets

wrangler r2 object put hermes-public-assets/images/posts/r2-guide/hero.webp --file=hero.webp --content-type=image/webp

wrangler r2 object get hermes-public-assets/images/posts/r2-guide/hero.webp --file=downloaded-hero.webp

Wrangler는 사람이 직접 관리하는 개발자 작업에 좋습니다. 다만 대량 파일 동기화는 rclone이 더 편할 때가 많습니다.

Python boto3

Hermes Agent와 가장 잘 맞는 방식은 Python입니다. Hermes가 파일을 만들고, 압축하고, R2에 올리고, URL을 포스트에 삽입하는 자동화를 만들기 쉽습니다.

개념 예시:

설정
service_names3
endpoint_urlhttps://ACCOUNT_ID.r2.cloudflarestorage.com
region_nameauto
buckethermes-public-assets
keyimages/posts/r2-guide/hero.webp
content typeimage/webp
cache controlpublic, max-age=31536000, immutable

Python에서 boto3 client를 만들고 upload_file 또는 put_object를 호출하면 됩니다. 대용량 파일은 upload_file이 내부적으로 멀티파트 업로드를 처리할 수 있어 편합니다.

Hermes 자동화에 넣을 때는 다음 규칙을 권장합니다.

규칙이유
환경변수로 키 주입Secret을 파일과 Git에 남기지 않기 위해
업로드 후 HEAD 요청으로 검증Content-Type, Content-Length 확인
업로드 결과 URL을 JSON으로 출력다음 에이전트 단계에서 사용하기 쉬움
실패 시 재시도네트워크 오류 대비
업로드 로그에 Secret 미출력운영 보안

JavaScript AWS SDK

Next.js API route나 Node.js 서버에서 R2에 파일을 올릴 때는 @aws-sdk/client-s3를 사용하면 됩니다.

개념 예시:

항목
패키지@aws-sdk/client-s3
clientS3Client
upload commandPutObjectCommand
endpointR2 S3 endpoint
regionauto
credentials서버 환경변수에서만 읽기

브라우저에서 직접 R2 Secret을 사용하면 절대 안 됩니다. 프론트엔드가 업로드해야 한다면 서버가 presigned URL을 만들어 주고, 브라우저는 그 URL로 PUT만 해야 합니다.

rclone

이미지 폴더가 수천 개 있거나 기존 서버에서 R2로 옮길 때는 rclone이 강합니다.

명령 예시:

rclone copy ./public/images r2:hermes-public-assets/images --transfers=16 --checkers=32

rclone sync ./public/downloads r2:hermes-public-assets/downloads --transfers=8 --checkers=16

주의할 점은 sync입니다. sync는 대상에만 있는 파일을 지울 수 있습니다. 처음에는 copy로 이전하고, 운영이 안정된 뒤에 sync를 쓰는 것이 안전합니다.


대용량 파일과 멀티파트 업로드

R2는 큰 파일도 다룰 수 있습니다. 공식 제한 기준으로 객체 최대 크기는 약 5TiB이고, 단일 업로드 파트는 5GiB 제한이 있습니다. 멀티파트 업로드를 사용하면 큰 파일을 여러 조각으로 나누어 병렬 업로드하고 실패한 부분만 다시 시도할 수 있습니다.

항목단일 PUT멀티파트 업로드
적합한 파일작은 이미지, 작은 PDF큰 zip, 영상, 백업 파일, 데이터셋
최대 크기 감각단일 요청은 5GiB 수준 제한전체 객체는 5TiB 수준까지 가능
실패 시 복구처음부터 다시 올릴 수 있음실패한 파트만 재시도 가능
병렬 처리어려움가능
SDK 자동 처리도구에 따라 다름boto3 upload_file 등은 자동 전환 가능

헤르메스 홈페이지에서는 대용량 파일이 아주 많지는 않겠지만, 다음 경우 멀티파트가 유용합니다.

상황예시
AI 강의 자료 배포1GB 이상의 zip 자료
녹화 영상 백업원본 mp4 보관
데이터셋 공유실습용 샘플 데이터 압축 파일
브라우저 QA 결과 보관긴 테스트 실행의 스크린샷/영상 묶음

주의점도 있습니다. 멀티파트 업로드가 중간에 실패하고 완료되지 않으면 미완료 업로드 상태가 남을 수 있습니다. R2에는 기본적으로 생성 후 7일 뒤 미완료 멀티파트 업로드를 정리하는 lifecycle 규칙이 있지만, 대량 업로드를 자주 한다면 직접 모니터링하는 것이 좋습니다.


Presigned URL — 서버를 거치지 않는 직접 업로드

사용자 업로드를 구현할 때 가장 피해야 할 구조는 브라우저가 큰 파일을 Next.js 서버로 올리고, Next.js 서버가 다시 R2로 올리는 방식입니다. 이렇게 하면 서버가 중간에서 파일을 두 번 처리해야 하고, timeout과 메모리 문제가 생기기 쉽습니다.

더 좋은 구조는 presigned URL입니다.

흐름:

단계설명
1브라우저가 업로드하고 싶은 파일 이름, 크기, MIME 타입을 서버에 전달
2서버가 로그인, 권한, 파일 크기, 확장자를 검증
3서버가 R2용 presigned PUT URL을 생성
4브라우저가 그 URL로 R2에 직접 PUT 업로드
5업로드 완료 후 서버에 key를 알려 DB에 기록
6서버 또는 Hermes가 이미지 검수, 리사이징, 공개 전환 처리

presigned URL의 장점:

장점설명
서버 부하 감소파일 본문이 앱 서버를 통과하지 않음
Secret 보호클라이언트는 R2 Secret을 모름
시간 제한URL 만료 시간을 1초부터 7일 범위에서 설정 가능
권한 최소화특정 객체 key와 특정 method만 허용 가능

주의점:

주의설명
URL은 bearer token처럼 취급URL을 가진 사람은 만료 전 해당 작업 가능
custom domain에서 직접 사용 불가presigned URL은 S3 API 도메인에서 작동
만료 전 재사용 가능한 번만 쓰이는 토큰이라고 착각하면 안 됨
POST form 방식은 미지원S3 POST multipart form 기반 업로드는 현재 지원되지 않음
업로드 후 검수 필요악성 파일, MIME 속임, 과도한 크기 검사를 해야 함

헤르메스 홈페이지에 Q&A 이미지 첨부나 사용자 자료 업로드를 넣는다면, presigned URL + private bucket + 검수 후 public bucket 복사 구조를 추천합니다.


캐시 전략 — 이미지 서버 성능을 제대로 뽑는 법

R2를 이미지 서버로 쓴다고 해서 자동으로 모든 것이 최적화되는 것은 아닙니다. 커스텀 도메인을 붙이고 Cloudflare Cache 정책을 잘 잡아야 합니다.

기본 원칙

이미지 서버의 캐시 전략은 두 가지 중 하나입니다.

전략설명적합한 파일명
긴 캐시 + 파일명 버전 관리한 번 올린 파일은 바꾸지 않고 새 파일명으로 교체hero-v1.webp, hero-20260426.webp, hash.webp
짧은 캐시 + 같은 파일명 교체같은 URL의 파일을 자주 바꿈운영은 쉽지만 캐시 무효화 필요

추천은 첫 번째입니다. 파일명에 날짜, 버전, 해시를 넣고 Cache-Control을 길게 잡습니다.

권장 예시:

파일Cache-Control
포스트 대표 이미지public, max-age=31536000, immutable
본문 이미지public, max-age=31536000, immutable
자주 바뀌는 JSONpublic, max-age=60 또는 별도 API 사용
다운로드 PDFpublic, max-age=86400 또는 버전 파일명 사용 시 1년

Cloudflare Cache Rules

커스텀 도메인을 쓰면 Cloudflare Cache Rules를 사용할 수 있습니다. 기본적으로 Cloudflare는 특정 확장자 중심으로 캐시합니다. 모든 파일을 캐시하고 싶다면 Cache Everything 규칙이나 확장자별 규칙을 검토해야 합니다.

헤르메스 assets 도메인 추천 규칙:

경로정책
/images/*Edge TTL 1개월~1년, Browser TTL 1개월~1년
/downloads/*파일 성격에 따라 1일~1년
/private/*공개 도메인에 두지 않음
/tmp/*짧은 TTL, 또는 비공개 버킷 사용

중요한 것은 바뀌는 파일과 안 바뀌는 파일을 URL 레벨에서 분리하는 것입니다. 글 이미지처럼 한 번 발행 후 거의 안 바뀌는 파일은 긴 캐시가 좋고, 매일 바뀌는 통계 JSON은 같은 방식으로 캐시하면 안 됩니다.

이미지 최적화와 R2의 역할 구분

R2는 객체 스토리지이지 이미지 변환 서비스가 아닙니다. 이미지 리사이징, 포맷 변환, 썸네일 생성은 별도 단계가 필요합니다.

선택지는 다음과 같습니다.

방식설명
빌드 전 변환업로드 전에 sharp 등으로 webp/avif 썸네일 생성
Hermes 자동 변환Hermes가 원본 이미지를 받아 여러 크기로 변환 후 R2 업로드
Cloudflare Images 사용별도 Cloudflare Images 제품 사용, 과금 구조 별도
Worker 변환Worker와 이미지 도구를 조합, 복잡도 증가
Next.js Image remotePatternsR2 커스텀 도메인을 원격 이미지 소스로 허용

헤르메스 홈페이지는 글 중심 사이트이므로 처음에는 업로드 전 변환 + R2 정적 서빙이 가장 단순합니다. 즉 원본 이미지를 1600px webp, 800px webp, 400px webp로 만들어 R2에 올리고, 페이지에서는 필요한 크기를 직접 참조합니다.


권장 폴더 구조와 파일 이름 규칙

R2에는 실제 폴더가 있는 것은 아니지만 key에 슬래시를 넣으면 폴더처럼 관리할 수 있습니다. 처음부터 규칙을 잡아야 나중에 수천 개 파일이 생겨도 관리가 됩니다.

헤르메스 홈페이지 추천 구조:

prefix용도
images/posts/YYYY/MM/slug/포스트 본문 이미지
images/hero/대표 이미지와 랜딩 이미지
images/thumbnails/목록 카드 썸네일
downloads/guides/공개 PDF, zip 자료
audio/posts/음성 요약, TTS 파일
video/clips/짧은 영상 클립
artifacts/hermes/YYYY/MM/DD/AI 에이전트 작업 결과물
tmp/uploads/업로드 직후 임시 파일, 가능하면 private bucket 권장

파일 이름 규칙:

규칙예시이유
소문자 영문cloudflare-r2-guide.webpURL 안정성
공백 대신 하이픈hero-image.webp복사와 공유가 쉬움
날짜 또는 버전 포함hero-20260426-v1.webp캐시 무효화 없이 교체 가능
원본과 파생본 분리hero-original.png, hero-1600.webp최적화 파일 추적 가능
한글 파일명 지양r2-이미지.webp 대신 r2-image.webp인코딩 문제 감소

추천 예시:

용도key
이 글 대표 이미지images/posts/2026/04/cloudflare-r2-hermes-file-server/hero-1600.webp
본문 다이어그램images/posts/2026/04/cloudflare-r2-hermes-file-server/architecture-v1.webp
다운로드 PDFdownloads/guides/cloudflare-r2-hermes-checklist-20260426.pdf
Hermes QA 스크린샷artifacts/hermes/2026/04/26/qna-preview-001.webp

이렇게 하면 나중에 Hermes에게 "2026년 4월 R2 글에 들어간 이미지 목록 정리해줘"라고 지시했을 때도 규칙적으로 찾을 수 있습니다.


Next.js 홈페이지에서 쓰는 실전 구조

헤르메스 홈페이지가 Next.js 기반이라면 R2는 다음 세 지점과 연결됩니다.

위치역할
포스트 markdown이미지 URL을 직접 삽입
next.configR2 커스텀 도메인을 remote image host로 허용
API route 또는 Server Actionpresigned URL 생성, 업로드 완료 기록

공개 이미지 참조

가장 단순한 방식은 markdown 또는 TS 포스트 데이터에 R2 URL을 직접 넣는 것입니다.

예시 URL:

https://assets.vibecoding365days.com/images/posts/2026/04/cloudflare-r2-hermes-file-server/hero-1600.webp

이 방식은 빠르고 단순합니다. 단, 파일이 삭제되면 글 이미지도 깨집니다. 그래서 발행된 글에 쓰인 이미지는 lifecycle로 자동 삭제하지 않는 것이 좋습니다.

Next Image와 remotePatterns

Next.js의 Image 컴포넌트를 쓴다면 R2 커스텀 도메인을 허용해야 합니다. 프로젝트 버전에 따라 next.config 작성 방식이 달라질 수 있으므로 현재 프로젝트의 Next.js 문서를 확인하고 설정해야 합니다.

개념은 다음과 같습니다.

항목
protocolhttps
hostnameassets.vibecoding365days.com
pathname/images/**

다만 R2 + Cloudflare Cache에서 이미 최적화된 webp/avif를 제공한다면, 모든 이미지를 Next Image 최적화 파이프라인에 다시 태울 필요는 없습니다. 정적 글 이미지는 일반 img 태그나 커스텀 렌더러로 충분할 수 있습니다.

업로드 API route

사용자 업로드가 필요하다면 API route는 파일 본문을 받기보다 presigned URL을 발급하는 역할만 맡기는 것이 좋습니다.

권장 흐름:

API역할
POST /api/uploads/presign파일명, 크기, 타입 검증 후 presigned URL 반환
PUT presigned URL브라우저가 R2에 직접 업로드
POST /api/uploads/complete업로드 완료 신고, DB 기록, 검수 상태 저장
background worker이미지 리사이징, 바이러스 검사, 공개 버킷 복사

이 구조를 쓰면 서버리스 환경에서도 큰 파일 업로드를 안정적으로 처리할 수 있습니다.


Hermes Agent로 R2 운영 자동화하기

R2의 진짜 장점은 Hermes Agent와 결합할 때 커집니다. 파일 서버를 사람이 수동으로 관리하는 대신, Hermes가 규칙에 따라 업로드, 검증, URL 삽입, 캐시 정책 점검, 오래된 임시 파일 정리를 처리할 수 있습니다.

가능한 자동화 예시는 다음과 같습니다.

자동화Hermes가 하는 일사람이 확인할 것
포스트 이미지 업로드로컬 이미지 압축, 파일명 생성, R2 업로드, URL 삽입이미지 품질, 저작권, 최종 배치
QA 스크린샷 보관브라우저 테스트 후 스크린샷을 artifacts 경로에 업로드공개 여부, 민감정보 포함 여부
자료실 파일 발행PDF/zip을 checksums와 함께 업로드파일 내용, 배포 승인
링크 깨짐 점검R2 URL 목록을 HEAD 요청으로 검사삭제 여부 결정
비용 리포트객체 수, 큰 파일, 오래된 tmp prefix 요약삭제/보관 정책 승인
캐시 무효화 요청교체된 파일의 URL purge 목록 생성purge 범위 승인

Hermes에게 줄 수 있는 운영 지시 예시:

상황지시 예시
새 글 이미지 올리기이 글에 들어갈 이미지 3장을 webp로 압축하고, images/posts/2026/04/r2-guide/ 아래에 올린 뒤 URL 목록을 만들어줘
깨진 이미지 찾기Hermes 포스트 전체에서 assets 도메인 이미지를 찾아 HEAD 요청으로 404 여부를 검사해줘
파일명 정리public/images 폴더의 한글 파일명을 영문 하이픈 규칙으로 바꾸고 R2 업로드 계획을 만들어줘
비용 점검R2 버킷의 큰 객체 상위 50개와 tmp prefix의 30일 이상 파일 목록을 요약해줘
배포 전 확인새 R2 이미지 URL이 라이브 페이지에서 정상 로드되는지 브라우저로 확인해줘

중요한 운영 원칙은 Hermes에게 Secret을 출력하게 하지 않는 것입니다. R2 Access Key와 Secret은 환경변수로만 주입하고, 로그에는 endpoint, bucket, key, public URL 정도만 남깁니다. 실패 로그에도 Secret이 찍히면 안 됩니다.


보안 설정 — 절대 공개하면 안 되는 것

R2는 파일 서버로 쓰기 쉽지만, 공개 범위를 잘못 잡으면 사고가 납니다. 특히 사용자 업로드와 내부 산출물을 다룰 때 조심해야 합니다.

공개 버킷과 비공개 버킷 분리

가장 중요한 원칙은 공개와 비공개를 버킷 단위로 분리하는 것입니다.

버킷공개 여부설명
hermes-public-assets공개이미 검수된 이미지, 공개 자료
hermes-private-uploads비공개사용자가 올린 원본, 검수 전 파일
hermes-agent-artifacts기본 비공개AI 작업 결과, 로그, 스크린샷
hermes-backups비공개DB 백업, 설정 백업, export 파일

"나중에 경로로 막으면 되겠지"보다 버킷 자체를 분리하는 편이 안전합니다. 공개 버킷에는 공개되어도 되는 파일만 들어가야 합니다.

Secret 관리

절대 하면 안 되는 것:

금지이유
Access Key를 Git에 커밋유출되면 파일 삭제/변조 위험
Secret을 브라우저 JS에 넣기사용자에게 그대로 노출
토큰을 스크린샷에 포함블로그나 문서에서 유출 가능
전체 계정 권한 토큰을 장기 사용한 토큰 유출 시 피해 범위가 큼
로그에 Authorization 헤더 출력운영 로그를 통해 유출 가능

권장 방식:

위치저장 방식
로컬 개발로컬 전용 환경 설정 파일, Git ignore 확인
VercelProject Environment Variables
Cloudflare Workerswrangler secret 또는 대시보드 Secret
Hermes 서버OS 환경변수 또는 안전한 secret store
문서환경변수 이름만 기록, 값은 절대 기록하지 않음

업로드 검수

사용자 업로드를 받는다면 R2에 올렸다고 끝이 아닙니다. 최소한 다음 검사가 필요합니다.

검사이유
파일 크기 제한비용 폭주와 DoS 방지
MIME 타입 확인이미지인 척하는 스크립트 차단
확장자 제한실행 파일 업로드 차단
이미지 재인코딩숨겨진 payload와 메타데이터 제거에 도움
공개 전 검수 상태부적절한 이미지 공개 방지
악성 파일 검사다운로드 파일 제공 시 필수에 가까움

홈페이지에 단순 운영자 업로드만 있다면 복잡한 검수는 줄일 수 있습니다. 하지만 공개 사용자 업로드가 들어오는 순간 private bucket, presigned URL, 검수 queue, public 복사 구조를 갖추는 것이 좋습니다.


운영 모니터링과 비용 폭주 방지

R2는 egress가 무료라서 안심할 수 있지만, 요청 수와 저장 용량은 계속 쌓입니다. 운영자는 월 1회 이상 다음 항목을 확인해야 합니다.

점검 항목확인 이유
총 저장 용량이미지와 백업 파일 증가 추세 확인
객체 수너무 작은 파일이 과도하게 많으면 목록 관리 복잡
Class A 요청업로드, LIST, lifecycle, copy가 과도한지 확인
Class B 요청캐시 미스가 많아 원본 GET이 과도한지 확인
r2.dev 사용 여부개발 URL이 실서비스에 남아 있지 않은지 확인
tmp prefix임시 파일이 정리되고 있는지 확인
큰 객체 상위 목록실수로 원본 영상, 대형 zip을 공개 버킷에 넣지 않았는지 확인

비용 폭주를 줄이는 규칙:

규칙효과
공개 이미지 파일명에 버전/해시 사용긴 캐시 가능, 원본 요청 감소
tmp prefix lifecycle 삭제임시 파일 누적 방지
업로드 크기 제한큰 파일 남용 방지
사용자별 업로드 quota악성 사용자의 저장 공간 남용 방지
Cloudflare Cache Rules 적용반복 조회를 엣지 캐시로 처리
r2.dev 프로덕션 사용 금지rate limit과 예측 불가 문제 방지

Hermes 자동 리포트 예시:

주기내용
매일새로 업로드된 파일 수, 실패 업로드, 404 이미지 요약
매주큰 파일 상위 30개, tmp 7일 초과 파일, 깨진 링크
매월저장 용량 추세, 요청 수 추세, 비용 추정, lifecycle 후보

이런 리포트는 Hermes의 cron 기능과 잘 맞습니다. 월요일 오전에 R2 점검 요약을 텔레그램으로 받게 하면, 파일 서버가 조용히 망가지는 일을 줄일 수 있습니다.


S3, Supabase Storage, Vercel Blob, Backblaze B2와 비교

R2가 항상 정답은 아닙니다. 선택은 사이트의 구조와 운영 방식에 따라 달라집니다.

서비스장점단점헤르메스 홈페이지 판단
Cloudflare R2egress 무료, S3 호환, Cloudflare CDN/Workers 결합S3 100% 호환 아님, r2.dev 프로덕션 부적합, 요청 수 과금공개 이미지/파일 서버로 강력 추천
AWS S3표준에 가까운 생태계, 기능 풍부, IAM 강력egress 비용과 설정 복잡도이미 AWS 중심이면 좋지만 개인 사이트에는 과할 수 있음
Supabase StorageDB/Auth와 통합 쉬움, 앱 개발 편함대규모 공개 트래픽 파일 서버로는 비용 구조 검토 필요Supabase 앱이면 편함, 순수 assets CDN이면 R2 선호
Vercel BlobVercel/Next.js와 개발 경험 좋음Vercel 종속, 트래픽/저장 비용 구조 확인 필요빠른 구현은 좋지만 장기 파일 서버는 R2 검토
Backblaze B2저렴한 저장 비용, S3 호환CDN 결합은 별도 설계 필요백업/저장소로 좋고, Cloudflare 결합 운영도 가능
Git LFSGit 워크플로우와 결합공개 이미지 서버나 대량 트래픽에는 부적합사이트 assets 서버로는 비추천

헤르메스 홈페이지의 추천 결론:

목적추천
공개 이미지, 글 첨부 파일Cloudflare R2
앱 내부 사용자 파일과 DB 연동Supabase Storage도 검토 가능
AWS 기반 기업 시스템S3
Vercel에서 아주 빠르게 MVPVercel Blob
장기 백업과 archiveR2 Infrequent Access 또는 Backblaze B2

R2가 특히 빛나는 지점은 트래픽 예측이 어렵고, 공개 파일 조회가 많고, Cloudflare 도메인을 이미 쓰는 사이트입니다. 이 조건이면 R2는 운영 난이도와 비용 사이의 균형이 좋습니다.


장점, 단점, 실제 평판을 균형 있게 보기

공식 문서와 커뮤니티 반응을 종합하면 R2의 평판은 대체로 "egress 비용을 없애고 S3 호환으로 쉽게 붙일 수 있는 매우 매력적인 객체 스토리지"에 가깝습니다. 특히 개인 개발자, 스타트업, 정적 사이트 운영자, 파일 다운로드가 많은 서비스에서 좋은 평가를 받습니다.

장점:

장점설명
egress 비용 부담이 작음이미지나 다운로드 트래픽이 갑자기 늘어도 egress 과금 공포가 줄어듦
S3 호환기존 SDK, rclone, boto3, AWS SDK 사용 가능
Cloudflare와 결합커스텀 도메인, CDN, WAF, Workers와 자연스럽게 연결
무료 한도작은 사이트는 무료 또는 매우 낮은 비용으로 시작 가능
확장성버킷당 저장량과 객체 수가 문서상 unlimited로 안내됨
에이전트 자동화 친화적CLI/API 기반 운영이 쉬워 Hermes 자동화와 잘 맞음

단점과 주의점:

단점설명
모든 비용이 무료는 아님저장 용량과 요청 수 과금은 존재
S3 완전 복제는 아님ACL, Object Lock, 일부 KMS/SSE, tagging 등 필요한 기능이 없을 수 있음
r2.dev는 개발용프로덕션 트래픽에는 커스텀 도메인 필수에 가까움
Presigned URL 제약custom domain이 아니라 S3 API domain에서 동작
Infrequent Access 주의무료 한도 제외, 검색 처리비, 30일 최소 보관 과금
이미지 변환은 별도R2 자체가 이미지 리사이징 서비스는 아님

운영자가 특히 조심해야 할 오해:

오해실제
R2는 CDN이다R2는 객체 스토리지이고, CDN 캐시는 커스텀 도메인과 Cloudflare Cache로 구성
R2에 올리면 자동 이미지 최적화된다이미지 최적화는 별도 도구나 Cloudflare Images 등이 필요
r2.dev URL로 서비스해도 된다개발 테스트용이며 프로덕션에는 커스텀 도메인 권장
Secret을 프론트에 넣어도 presigned니까 안전하다Secret은 절대 프론트에 넣으면 안 되고 서버가 presigned URL을 만들어야 함
Infrequent Access가 항상 싸다자주 읽히면 검색 처리비와 최소 보관 기간 때문에 손해일 수 있음

헤르메스 홈페이지 운영 관점에서 R2는 "강력 추천하지만, 공개/비공개 분리와 캐시 정책을 같이 설계해야 하는 도구"입니다. 그냥 버킷 하나 만들고 모든 파일을 넣는 방식보다, 운영 규칙을 먼저 정하고 시작해야 오래 갑니다.


헤르메스 홈페이지 추천 아키텍처

최종 추천 구조는 다음과 같습니다.

구성요소추천
공개 assets 도메인assets.vibecoding365days.com
공개 버킷hermes-public-assets
비공개 업로드 버킷hermes-private-uploads
AI 산출물 버킷hermes-agent-artifacts
공개 이미지 prefiximages/posts/YYYY/MM/slug/
다운로드 prefixdownloads/guides/
임시 prefixtmp/ with lifecycle
업로드 방식운영자 파일은 Hermes/rclone, 사용자 파일은 presigned URL
캐시이미지 파일은 긴 TTL + 버전 파일명
보안Secret은 환경변수, 버킷 권한 최소화, 공개/비공개 분리

가장 단순한 1단계 구조

처음에는 이렇게 시작합니다.

항목
버킷hermes-public-assets
도메인assets.vibecoding365days.com
파일글 이미지와 공개 다운로드만 저장
업로드대시보드 또는 Wrangler
캐시이미지 prefix에 긴 TTL

이 단계는 설정이 쉽고 사고 가능성이 낮습니다. 공개되어도 되는 파일만 넣는 것이 핵심입니다.

운영 자동화 2단계 구조

글과 이미지가 늘어나면 Hermes 자동화를 붙입니다.

항목
업로드 스크립트이미지 압축 후 R2 업로드
URL 생성key 규칙에 따라 public URL 자동 생성
검증HEAD 요청으로 Content-Type, 크기, 200 응답 확인
포스트 반영markdown에 이미지 URL 삽입
보고업로드 목록과 최종 URL을 텔레그램으로 전송

이 단계부터는 사람이 파일을 직접 올리는 일이 줄어듭니다.

사용자 업로드 3단계 구조

나중에 Q&A 이미지 첨부, 자료 제출, 커뮤니티 기능이 들어가면 다음처럼 확장합니다.

항목
원본 업로드hermes-private-uploads
업로드 방식presigned URL
검수서버/worker/Hermes가 크기, 타입, 내용 확인
공개 전환검수 통과 파일만 hermes-public-assets로 복사
DB 기록원본 key, 공개 key, 상태, 사용자 ID 저장
삭제 정책rejected/tmp 파일 lifecycle 삭제

이 구조는 조금 복잡하지만 공개 사이트에서는 안전합니다. 특히 AI 에이전트가 자동으로 파일을 다루는 경우, 비공개 원본과 공개 결과물을 분리하는 습관이 중요합니다.


Cache-Control, CORS, Smart Tiered Cache 실전 설정

R2를 파일 저장소로만 쓰면 절반만 쓰는 것입니다. 이미지 서버로 제대로 쓰려면 업로드 시 HTTP 메타데이터를 넣고, Cloudflare Cache Rules를 만들고, 브라우저 직접 업로드가 필요하면 CORS까지 설정해야 합니다.

업로드 시 Cache-Control 헤더 설정

이미지처럼 한 번 발행하면 거의 바뀌지 않는 파일은 업로드 순간부터 긴 캐시를 붙이는 것이 좋습니다. 핵심은 파일명에 날짜, 버전, 해시를 넣고 Cache-Control을 길게 주는 것입니다.

Python boto3 개념 예시:

항목
Bucketmy-bucket
Keyimages/photo.jpg
ContentTypeimage/jpeg
CacheControlpublic, max-age=31536000, immutable

실제 코드 형태로 쓰면 다음 의미입니다.

s3.put_object에 Bucket, Key, Body, ContentType, CacheControl을 함께 전달합니다. CacheControl 값은 public, max-age=31536000, immutable처럼 둡니다. 31536000초는 약 1년이고, immutable은 이 URL의 파일이 바뀌지 않는다는 신호입니다.

주의할 점은 같은 URL로 파일을 자주 덮어쓰면 1년 캐시가 오히려 문제가 된다는 것입니다. 그래서 대표 이미지를 바꿀 가능성이 있으면 hero.webp를 덮어쓰기보다 hero-20260426-v1.webp, hero-20260426-v2.webp처럼 새 key를 쓰는 방식이 좋습니다.

파일 유형권장 Cache-Control파일명 전략
발행된 글 이미지public, max-age=31536000, immutable날짜/버전/해시 포함
로고와 공통 아이콘public, max-age=604800 또는 버전 파일명 사용 시 1년교체 가능성에 따라 결정
PDF 다운로드public, max-age=86400 또는 버전 파일명 사용 시 1년문서 버전 포함 권장
자주 바뀌는 JSONpublic, max-age=60 또는 no-cache같은 URL 가능
검수 전 임시 파일public 캐시 금지, 가능하면 비공개private bucket 권장

Cloudflare Cache Rules 설정

커스텀 도메인을 붙인 뒤에는 Cloudflare 대시보드에서 Cache Rules를 설정합니다. 대표적인 흐름은 다음과 같습니다.

단계설정
1Cloudflare 대시보드에서 Caching 메뉴로 이동
2Cache Rules 선택 후 Create Rule
3조건은 Hostname equals assets.example.com 형태로 지정
4Eligible for cache 활성화
5Edge Cache TTL을 1일, 1개월, 1년 등 파일 성격에 맞게 설정
6필요하면 Browser TTL도 함께 지정

헤르메스 홈페이지라면 다음 규칙이 현실적입니다.

조건권장 동작
Hostname equals assets.vibecoding365days.com and URI Path starts with /images/Eligible for cache, Edge TTL 1개월~1년
URI Path starts with /downloads/파일 성격에 따라 1일~1개월
URI Path starts with /tmp/공개 도메인에 두지 않거나 짧은 TTL
확장자 webp, avif, jpg, png, svg캐시 허용
확장자 html, json명확한 목적 없으면 긴 캐시 금지

캐시가 잘 작동하면 R2까지 도달하는 GET 요청, 즉 Class B operation을 크게 줄일 수 있습니다. 커뮤니티에서는 매우 높은 캐시 히트율을 구성해 수억 요청 중 R2 원본까지 도달하는 요청을 극히 낮게 만든 사례가 공유됩니다. 다만 이런 수치는 사이트 구조, 파일명 전략, 캐시 규칙, 사용자 지역, Cloudflare 플랜에 따라 달라지므로 그대로 보장되는 값은 아닙니다.

Smart Tiered Cache 활성화

Smart Tiered Cache는 Cloudflare가 R2 오리진에 가까운 상위 데이터센터를 경유하게 해 원본 히트를 줄이는 방식입니다. 대시보드에서는 Caching 메뉴의 Tiered Cache에서 Smart Tiered Cache를 활성화할 수 있습니다.

효과는 다음과 같습니다.

효과설명
원본 접근 감소여러 엣지가 같은 R2 원본을 직접 때리는 상황을 줄임
캐시 효율 개선상위 tier가 중간 캐시 역할을 함
R2 Class B 감소 가능캐시 hit가 늘면 R2 GET/HEAD 원본 요청이 줄어듦
글로벌 지연 안정화사용자 근처 엣지와 상위 캐시 조합으로 편차를 줄일 수 있음

이미지 서버가 커질수록 Smart Tiered Cache는 켜두는 편이 좋습니다. 특히 assets 도메인이 전 세계에서 조회되는 구조라면 R2 원본을 보호하는 완충층 역할을 합니다.

CORS 설정 — 브라우저 접근 허용

브라우저가 R2 파일을 직접 읽거나 presigned URL로 업로드하려면 CORS 정책이 필요합니다. 단순히 img 태그로 공개 이미지를 보여 주는 것만으로는 CORS가 항상 필요한 것은 아니지만, JavaScript fetch, canvas 처리, presigned PUT 업로드에는 필요해지는 경우가 많습니다.

권장 CORS 정책 개념:

항목예시
AllowedOriginshttps://vibecoding365days.com, http://localhost:3000
AllowedMethodsGET, PUT, HEAD
AllowedHeadersContent-Type, Cache-Control
ExposeHeadersETag
MaxAgeSeconds3600

중요한 실수는 AllowedOrigins에 경로를 넣는 것입니다. Origin은 스킴, 호스트, 포트까지만 포함합니다.

잘못된 예올바른 예
https://example.com/uploadshttps://example.com
https://vibecoding365days.com/qnahttps://vibecoding365days.com
localhost:3000http://localhost:3000

운영 팁은 개발 origin과 운영 origin을 분리해 명시하는 것입니다. 모든 origin을 허용하는 별표는 공개 다운로드에는 편할 수 있지만, 사용자 업로드나 인증 흐름에는 신중해야 합니다.


Lifecycle Rules와 Infrequent Access 운영법

R2에는 객체를 일정 기간 뒤 자동 삭제하거나 Standard에서 Infrequent Access로 전환하는 lifecycle rule이 있습니다. 파일 서버를 오래 운영하면 임시 업로드, 로그, AI 산출물, 오래된 백업이 계속 쌓이므로 lifecycle이 중요합니다.

자동 삭제 규칙

예를 들어 logs/ 아래 파일은 90일 뒤 삭제하도록 만들 수 있습니다. 대시보드에서는 버킷 Settings의 Object Lifecycle Rules에서 Add rule을 선택하고 prefix와 만료 기간을 지정합니다.

권장 삭제 규칙:

prefix권장 보관 기간이유
tmp/uploads/1~7일업로드 실패와 검수 전 임시 파일 누적 방지
artifacts/hermes/browser-snapshots/30~90일QA 스크린샷은 오래 보관할 필요가 적음
logs/30~180일운영 로그 보존 정책에 따라 결정
rejected/7~30일거절된 업로드는 짧게 보관
published images자동 삭제 비추천글 이미지가 깨질 수 있음

가장 중요한 원칙은 공개 글에 이미 연결된 이미지는 lifecycle로 삭제하지 않는 것입니다. 발행된 포스트 이미지가 사라지면 SEO, 사용자 경험, 아카이브 품질이 모두 나빠집니다.

Infrequent Access 전환

Infrequent Access는 저장 단가가 낮지만 읽을 때 retrieval 비용이 있고 30일 최소 보관 기간이 있습니다. 그래서 무조건 싸지 않습니다.

적합한 파일부적합한 파일
오래된 백업자주 읽히는 대표 이미지
거의 열지 않는 원본 이미지홈페이지 썸네일
장기 보관용 zip인기 글 본문 이미지
30일 이상 확실히 보관할 파일며칠 뒤 삭제할 임시 파일

30일 전에 삭제해도 30일분 비용이 청구될 수 있으므로, 임시 파일을 Infrequent Access로 보내는 것은 보통 좋지 않습니다. 임시 파일은 짧게 삭제하고, 장기 보관 파일만 IA 전환을 검토합니다.

버킷당 rule 수와 운영 원칙

공식 제한 기준으로 lifecycle rule은 버킷당 최대 1,000개까지 가능합니다. 하지만 rule이 많다고 좋은 것은 아닙니다. prefix 설계를 잘해서 적은 rule로 넓게 관리하는 편이 낫습니다.

좋은 설계:

prefixrule
tmp/7일 삭제
logs/90일 삭제
artifacts/180일 삭제 또는 IA 전환
backups/monthly/30일 후 IA 전환

나쁜 설계는 글 slug마다 lifecycle rule을 따로 만드는 것입니다. 나중에 rule 관리가 어려워집니다. 처음부터 prefix 정책을 크게 잡는 것이 운영에 유리합니다.


Event Notifications와 Workers Binding 자동화

R2는 단순 파일 저장소를 넘어 이벤트 기반 자동화를 만들 수 있습니다. 오브젝트가 생성되거나 삭제될 때 Cloudflare Queues로 이벤트를 보내고, Consumer Worker가 후속 작업을 처리하는 구조입니다.

Event Notifications

업로드 이벤트를 Queue로 보내면 다음 작업을 자동화할 수 있습니다.

이벤트자동화 예시
object-create이미지 썸네일 생성, DB metadata 기록, 감사 로그 저장
object-deleteDB에서 공개 URL 제거, 검색 인덱스 정리
특정 suffix .jpgjpg 업로드만 리사이징 queue로 전달
특정 prefix uploads/사용자 업로드만 검수 pipeline으로 전달

이 구조는 AWS의 S3 Event Notification과 SNS/SQS/Lambda 조합에 가깝게 이해하면 됩니다. Cloudflare에서는 R2 이벤트가 Queue로 들어가고, Worker가 메시지를 소비합니다.

이벤트 메시지에는 보통 계정, action, bucket, object key, object size, eTag, eventTime 같은 정보가 들어갑니다. 이 정보로 어떤 파일이 올라왔는지 파악하고 후속 처리를 시작할 수 있습니다.

헤르메스 홈페이지에서 유용한 활용:

상황처리
사용자가 이미지를 업로드Queue 이벤트로 검수 작업 시작
운영자가 글 이미지를 올림자동으로 썸네일 생성 후보 등록
AI가 QA 스크린샷 업로드artifacts DB에 key와 URL 기록
다운로드 파일 교체checksum 생성 및 문서 갱신 알림

Workers Binding

Cloudflare Workers에서는 R2 버킷을 binding으로 연결해 S3 API 없이 직접 접근할 수 있습니다. wrangler 설정의 r2_buckets에 binding 이름과 bucket_name을 지정한 뒤, Worker 코드에서 env.MY_BUCKET.get, env.MY_BUCKET.put 같은 API를 쓰는 방식입니다.

개념 구조:

구성역할
Worker route브라우저 요청을 받는 서버리스 endpoint
R2 bindingWorker에서 버킷에 직접 접근하는 연결
get객체 읽기
put객체 쓰기
headmetadata 확인
delete객체 삭제
listprefix 목록 조회

Workers Binding의 장점은 Cloudflare 네트워크 내부에서 R2에 접근한다는 점입니다. 인증 프록시, private 파일 다운로드, 이미지 접근 제어, 간단한 리다이렉트, signed cookie 검증 같은 일을 Worker에서 처리하고 R2를 원본 저장소로 둘 수 있습니다.

예를 들어 비공개 파일 다운로드는 이렇게 설계할 수 있습니다.

단계설명
1사용자가 /download/file-id로 접근
2Worker가 쿠키나 토큰을 확인
3권한이 있으면 R2 private bucket에서 객체 get
4Content-Type과 Cache-Control을 붙여 응답
5권한이 없으면 403 반환

이 구조를 쓰면 private bucket을 공개하지 않고도 필요한 사람에게만 파일을 제공할 수 있습니다.

R2 이벤트와 Hermes Agent 조합

Event Notifications와 Hermes를 조합하면 파일 서버가 자동 운영 체계가 됩니다.

흐름설명
업로드 발생R2 object-create 이벤트가 Queue로 들어감
Worker 처리파일 크기, 타입, prefix를 검사하고 작업 요청 생성
Hermes 실행썸네일 생성, 메타데이터 정리, 문서 업데이트 초안 작성
사람 승인공개 페이지 반영 전 최종 확인
배포Git commit/push 또는 DB 업데이트

이렇게 하면 파일 업로드가 단순 저장으로 끝나지 않고, 사이트 운영 작업으로 이어집니다. 특히 헤르메스 홈페이지처럼 AI 에이전트가 콘텐츠와 이미지 자산을 계속 생성하는 사이트에서는 이 이벤트 기반 구조가 장기적으로 유리합니다.


커뮤니티 후기와 레딧 평판 종합

공식 문서만 보면 R2는 거의 완벽해 보입니다. 하지만 실제 운영에서는 커뮤니티 후기가 중요합니다. 공개 커뮤니티와 레딧 후기를 종합하면 평가는 대체로 긍정적이지만, 결제와 고객지원에 대한 불만은 반복적으로 보입니다. 아래 내용은 특정 개인 사례를 그대로 보장된 사실로 받아들이기보다, 운영자가 참고할 리스크 신호로 보는 것이 좋습니다.

긍정적 평가

긍정적 후기는 주로 비용 절감과 안정성에 집중됩니다.

긍정 포인트커뮤니티에서 자주 나오는 이야기
S3 대비 비용 절감비용의 대부분이 egress였던 서비스는 R2 이전 후 비용이 크게 줄었다는 사례가 많음
이미지 많은 사이트에 적합뉴스 사이트, 블로그, 다운로드 서비스에서 사진/정적 파일 서빙 비용 절감 사례가 공유됨
캐시와 결합 시 원본 요청 감소인기 파일은 Cloudflare 캐시가 처리해 R2 Class B 요청도 낮게 유지 가능하다는 후기
로그와 모니터링 저장Loki, Prometheus, 백업성 데이터 저장소로 쓰는 사례가 있음
확장성 체감대규모 동시 요청에서 병목은 R2보다 앱 레이어나 캐시 설정인 경우가 많다는 의견

이미지 서버 관점에서는 이 후기가 중요합니다. 헤르메스 홈페이지의 글 이미지, 스크린샷, 다운로드 자료처럼 "저장량보다 읽기 트래픽이 더 걱정되는" 워크로드라면 R2의 장점이 크게 살아납니다.

부정적 평가와 가장 큰 리스크

가장 반복적으로 언급되는 불만은 고객지원과 결제 문제입니다. 일부 사용자는 결제 실패, 카드 문제, 청구 상태 오류가 생겼을 때 R2나 다른 Cloudflare 서비스 접근이 빠르게 제한됐고 지원 응답이 늦었다고 보고합니다.

운영자가 받아들여야 할 교훈은 다음입니다.

리스크대응
카드 만료 또는 결제 실패주 결제수단과 예비 결제수단 관리, 만료일 알림 설정
무료 플랜 지원 한계중요한 서비스라면 유료 플랜과 지원 수준 검토
갑작스러운 접근 제한백업과 exit 전략 유지
Cloudflare 계정 단일 장애점도메인, DNS, R2, Workers가 모두 한 계정에 묶이는 리스크 인식
청구 분쟁 장기화핵심 파일은 다른 스토리지에도 복제 가능하게 유지

AWS와 비교할 때 일부 커뮤니티 사용자는 "AWS는 결제 문제가 있어도 경고와 유예가 긴 편인데, Cloudflare는 더 빠르게 제한될 수 있다"고 느낍니다. 이 평가는 개인 경험에 따라 다르지만, 운영자는 최악의 상황을 가정해야 합니다.

R2 평판 종합 점수

항목평가이유
안정성/신뢰성높음일반적인 객체 저장과 공개 파일 서빙 후기는 대체로 좋음
이그레스 많은 워크로드 비용 효율매우 높음S3 대비 비용 절감 사례 다수
순수 저장 비용보통Backblaze B2, Wasabi보다 저장 단가는 높을 수 있음
S3 호환성높음주요 SDK와 도구는 잘 맞지만 일부 S3 기능은 없음
성능높음커스텀 도메인과 Cloudflare Cache 결합 시 강함
고객 지원낮음~보통무료/저가 플랜에서는 기대치를 낮춰야 함
결제 장애 대응주의 필요커뮤니티에서 반복적으로 리스크가 언급됨
확장성높음이미지/정적 파일 대규모 서빙에 적합

결론은 단순합니다. R2는 기술적으로 훌륭하지만, 결제수단 관리와 백업 전략 없이 핵심 파일을 단독 보관하는 것은 좋지 않습니다. egress가 무료이므로 다른 스토리지로 백업을 빼는 비용 부담이 작다는 점을 적극 활용해야 합니다.


경쟁사 비교 상세 — 비용, egress, 기능

R2의 경쟁력은 저장 단가 하나가 아니라 저장 비용, 요청 비용, egress, CDN 결합, 운영 난이도를 합친 결과입니다.

저장 비용 비교

서비스Standard 저장 단가 감각저빈도 접근아카이브
Cloudflare R2GB-month당 0.015달러IA 0.01달러딥 아카이브 없음
AWS S3대략 0.023달러 수준S3-IA 제공Glacier/Deep Archive 제공
Backblaze B2대략 0.006달러 수준단순 구조별도 딥 아카이브보다는 저가 저장 중심
Wasabi대략 0.005~0.006달러 수준단순 구조최소 보관/egress 정책 확인 필요
Azure BlobHot/Cool/Archive 구분Cool 제공Archive 제공
Google Cloud StorageStandard/Nearline/Coldline/Archive다양Archive 제공

순수 백업 저장만 보면 R2가 항상 가장 싸지는 않습니다. Backblaze B2나 Wasabi가 더 저렴할 수 있습니다. 하지만 공개 파일을 많이 읽는 순간 egress 비용이 결정적인 차이를 만듭니다.

10TB 전송 시 egress 비용 감각

서비스10TB 인터넷 전송 비용 감각
Cloudflare R20달러
Backblaze B2무료 제공 범위 이후 GB당 과금 가능
Wasabi정책상 저장량 대비 egress 제한과 fair use 확인 필요
AWS S3수백 달러~약 900달러 수준 가능
Azure Blob수백 달러 이상 가능
Google Cloud Storage수백~천 달러 이상 가능

정확한 금액은 리전, 플랜, 할인, CDN 조합에 따라 달라집니다. 중요한 것은 이미지 서버처럼 트래픽 예측이 어려운 서비스에서 R2가 egress 비용 리스크를 크게 줄인다는 점입니다.

기능 비교

기능R2S3Backblaze B2
S3 API 호환높음네이티브높음
Object Lock/WORM미지원 또는 제한적강력지원 여부 플랜/설정 확인
스토리지 클래스Standard, Infrequent Access매우 다양단순
자동 티어링제한적Intelligent-Tiering제한적
딥 아카이브없음Glacier 계열별도 구조
CDN 결합Cloudflare와 자연스럽게 결합CloudFront 별도 설계별도 CDN 설계
커스텀 도메인R2 public bucket에서 지원S3/CloudFront 조합 필요별도 프록시/CDN 필요
이벤트 알림Queues 연동SNS/SQS/Lambda/EventBridgewebhook 등 방식 확인
서버리스 연동Workers BindingLambda직접 결합은 약함

규정 준수, Object Lock, 딥 아카이브가 중요하면 S3가 더 맞을 수 있습니다. 반대로 공개 이미지와 다운로드 파일이 많고 Cloudflare를 이미 쓰고 있다면 R2가 단순하고 경제적입니다.


현재 프로젝트 적용 비용 시나리오

헤르메스 홈페이지가 이미지 자동 생성, 글 발행, 스크린샷 저장, 다운로드 자료 배포를 한다고 가정하면 R2는 매우 적합합니다.

대략적인 저장량별 감각은 다음과 같습니다. 무료 10GB를 제외한 단순 저장 비용 감각이며, 실제 비용은 요청 수, 캐시 hit, IA 사용 여부에 따라 달라집니다.

규모예상 저장량R2 저장 비용 감각S3 계열에서 주의할 점
현재 소규모20GB 안팎무료 한도 초과분 기준 매우 낮음트래픽이 붙으면 egress가 비용 핵심
이미지 2,000장30~60GB월 1달러 미만~소액 가능이미지 조회가 많으면 전송 비용 증가
이미지 10,000장100~300GB월 몇 달러 수준 가능인기 글이 터지면 egress 비용 급증 가능
자료실 운영PDF/zip 수십~수백GB저장 비용은 예측 쉬움다운로드 트래픽이 핵심 변수
영상 원본 저장수백GB~TB저장 비용 증가R2가 영상 플랫폼은 아니므로 Stream 등 검토

R2의 가치는 "한 번 저장하고 많이 읽는" 워크로드에서 큽니다. 헤르메스 홈페이지의 글 이미지와 AI 산출물은 이 패턴에 가깝습니다.

추천 운영 결론

항목추천
공개 이미지R2 Standard + custom domain + 긴 캐시
오래된 백업R2 IA 또는 Backblaze B2 비교 후 결정
사용자 업로드 원본R2 private bucket + presigned URL
공개 전환검수 후 public bucket으로 copy
AI 산출물artifacts prefix에 저장, 민감정보 확인 후 공개
결제 리스크카드 만료 알림, 예비 결제수단, 월 1회 청구 확인
Exit 전략rclone copy로 다른 스토리지에 정기 백업

가장 중요한 운영 원칙은 세 가지입니다.

  1. 공개 파일과 비공개 파일을 버킷 단위로 분리합니다.
  2. 이미지 URL은 버전 파일명과 긴 캐시를 전제로 설계합니다.
  3. Cloudflare 계정/결제 문제가 생겨도 복구할 수 있도록 정기 백업과 대체 경로를 둡니다.

최종 체크리스트

R2를 헤르메스 홈페이지 파일 및 이미지 서버로 도입하기 전 체크리스트입니다.

계정과 버킷

체크내용
Cloudflare R2 활성화 완료
결제수단과 무료 한도 확인
public assets 버킷 생성
private uploads 버킷 필요 여부 결정
agent artifacts 버킷 필요 여부 결정

도메인과 공개 설정

체크내용
r2.dev는 개발 테스트용으로만 사용
assets.vibecoding365days.com 같은 커스텀 도메인 연결
공개 버킷에는 공개 가능 파일만 저장
Cache Rules 적용 여부 확인
WAF 또는 Rate Limiting 필요 여부 확인

업로드와 파일 규칙

체크내용
파일명은 영문 소문자, 하이픈, 날짜/버전 규칙 사용
이미지 업로드 전 webp/avif 압축
Cache-Control 헤더 설정
업로드 후 HEAD 요청으로 검증
public URL 목록을 문서 또는 DB에 기록

보안

체크내용
R2 Secret을 Git에 저장하지 않음
Secret은 환경변수 또는 secret store에만 저장
토큰 권한은 특정 버킷으로 제한
브라우저에는 Secret을 절대 전달하지 않음
사용자 업로드는 private bucket + presigned URL + 검수 구조 사용

운영

체크내용
매월 저장 용량과 요청 수 확인
tmp prefix lifecycle 설정
깨진 이미지 URL 점검 자동화
큰 파일 상위 목록 정기 점검
Hermes cron으로 R2 운영 리포트 받기

최종 판단은 간단합니다.

헤르메스 홈페이지가 글, 이미지, 자료실, AI 산출물을 계속 쌓아갈 계획이라면 R2는 지금 붙여도 좋은 파일 서버입니다. 처음에는 public assets 버킷 하나와 커스텀 도메인으로 시작하고, 사용자 업로드가 생기면 private bucket과 presigned URL 구조로 확장하면 됩니다.


참고한 공식 문서

이 글은 2026년 4월 기준 Cloudflare 공식 문서와 공개 자료를 바탕으로 정리했습니다. Cloudflare의 가격, 제한, 기능은 변경될 수 있으므로 실제 도입 전에는 최신 문서를 다시 확인해야 합니다.

주제문서
R2 개요https://developers.cloudflare.com/r2/
가격과 무료 한도https://developers.cloudflare.com/r2/pricing/
Public buckets, custom domains, r2.devhttps://developers.cloudflare.com/r2/buckets/public-buckets/
S3 API 호환성https://developers.cloudflare.com/r2/api/s3/api/
Presigned URLshttps://developers.cloudflare.com/r2/api/s3/presigned-urls/
Workers APIhttps://developers.cloudflare.com/r2/api/workers/workers-api-reference/
플랫폼 제한https://developers.cloudflare.com/r2/platform/limits/
Lifecycle ruleshttps://developers.cloudflare.com/r2/buckets/object-lifecycles/
Storage classeshttps://developers.cloudflare.com/r2/buckets/storage-classes/