Ghost에 이미지 한 장을 올렸는데 파일이 여러 개 생긴 이유
Ghost의 `_o` 원본, 최적화본, size 폴더와 WebP 변환 파일이 어떤 역할을 하는지 실제 백업 구조와 함께 설명합니다.

Ghost 블로그를 백업했을 때 가장 먼저 이상하다고 느낀 것은 이미지 개수였습니다. 글마다 대표 이미지를 한 장씩 올렸다고 생각했는데, 서버에는 비슷한 이름의 파일과 여러 크기 폴더가 훨씬 많이 있었습니다.
처음에는 같은 이미지가 잘못 복제됐거나, 사용하지 않는 파일이 계속 쌓인 것으로 생각했습니다. 그러나 백업 구조와 Ghost 공식 문서를 확인해보니 대부분은 오류가 아니라 이미지 최적화를 위해 만들어진 파일이었습니다.
이 글은 대표 이미지가 화면에서 너무 크게 보였던 문제와는 다릅니다. 이전 글이 CSS로 표시 크기를 조절한 기록이라면, 이번 글은 서버에 저장된 이미지 파일 자체가 왜 늘어나는지 확인한 기록입니다.
실제 백업에는 이미지 파일이 163개 있었습니다
Ghost에서 Astro로 이전할 때 이미지 폴더 전체를 먼저 로컬에 보관했습니다. 당시 백업에서 확인한 결과는 다음과 같았습니다.
| 구분 | 파일 수 | 용량 |
|---|---|---|
| 연·월 기본 폴더 | 44개 | 약 27.65MB |
| 크기·형식 파생 폴더 | 119개 | 약 14.39MB |
| 합계 | 163개 | 약 42.05MB |
기본 폴더의 44개 파일은 _o가 붙은 원본 22개와 이름에 _o가 없는 최적화본 22개로 나뉘었습니다. 이와 별도로 size 폴더 아래에 여러 너비와 WebP 형식으로 만든 파일 119개가 있었습니다.
42MB는 서버 공간을 위협할 정도로 큰 용량은 아니었습니다. 제가 불편하게 느낀 부분은 용량보다 구조였습니다. 관리자 화면에서는 이미지 한 장으로 보였는데, 직접 백업하려고 서버를 열어보니 어떤 파일이 원본이고 어떤 파일이 실제 글에 필요한지 바로 알기 어려웠습니다.
첫 번째는 업로드 당시의 원본입니다
Ghost는 기본 이미지 최적화가 켜져 있으면 업로드한 원본을 _o 접미사가 붙은 파일로 남깁니다. 예를 들어 최적화해서 사용하는 파일이 다음과 같다면,
feature.png
업로드 당시 원본은 다음처럼 함께 있을 수 있습니다.
feature_o.png
Ghost 공식 설정 문서에 따르면 기본 이미지 최적화는 큰 이미지를 최대 너비 2000픽셀로 줄이고, JPEG 품질을 조정하고, 메타데이터를 제거합니다. 이 과정에서도 나중에 다른 크기를 다시 만들 수 있도록 업로드 원본은 _o 파일로 보존합니다.
따라서 _o 파일을 단순한 중복이라고 보고 운영 중인 Ghost 서버에서 바로 지우는 것은 좋지 않습니다. 현재 화면에는 최적화본이 사용되더라도, 다른 크기의 이미지를 다시 만드는 기준은 원본이기 때문입니다.
두 번째는 방문자에게 보여주는 최적화본입니다
_o가 없는 기본 이미지 파일은 Ghost가 일반적인 화면 표시를 위해 처리한 버전입니다. 원본 사진이 매우 크다면 방문자에게 원본을 그대로 전송하는 것보다 크기와 용량을 줄인 파일을 보내는 편이 빠릅니다.
이 두 파일만 봐도 이미지 한 번 업로드에 원본과 최적화본이 함께 남을 수 있습니다.
_o파일: 업로드 당시 원본- 일반 파일: 기본 최적화를 거친 표시용 이미지
이는 백업 관점에서는 파일이 늘어나는 원인이지만, 이미지 품질과 사이트 속도를 함께 관리하기 위한 구조입니다.
세 번째는 화면 크기에 맞춘 반응형 이미지입니다
파일 수가 더 늘어난 이유는 size 폴더였습니다. minml의 Ghost 백업에는 다음 너비의 폴더가 남아 있었습니다.
size/w160/
size/w320/
size/w600/
size/w960/
size/w1200/
size/w2000/
모바일 화면에 폭 2000픽셀짜리 이미지를 그대로 내려보낼 필요는 없습니다. Ghost 테마는 srcset을 이용해 동일한 이미지의 여러 주소를 브라우저에 알려줄 수 있습니다. 그러면 브라우저가 화면 폭과 해상도에 맞는 파일을 선택합니다.
예를 들어 작은 카드에서는 320픽셀 이미지를, 넓은 본문에서는 960픽셀이나 1200픽셀 이미지를 사용할 수 있습니다. 원본 하나를 여러 크기로 준비하는 이유는 같은 이미지를 반복해서 보여주기 위해서가 아니라, 각 방문자에게 지나치게 큰 파일을 보내지 않기 위해서입니다.
Ghost에서 만드는 너비는 모든 사이트가 똑같지 않습니다. 테마의 package.json에 정의한 이미지 크기와 실제 템플릿이 요청한 크기에 따라 달라질 수 있습니다. 공식 문서도 이미지 크기를 너무 많이 정의하면 저장 공간이 과도하게 늘 수 있으므로 10개 이하를 권장합니다.
WebP 폴더인데 파일 확장자는 PNG였습니다
백업에서 특히 헷갈렸던 것은 다음과 같은 경로였습니다.
size/w600/format/webp/2026/07/feature.png
경로에는 format/webp가 있는데 파일 이름은 여전히 .png로 끝났습니다. 처음 보면 변환이 제대로 되지 않은 것처럼 보입니다.
하지만 이것도 Ghost의 의도된 방식입니다. Ghost 공식 이미지 문서에는 PNG나 JPEG를 WebP 또는 AVIF로 변환하더라도 URL의 기존 파일 확장자는 유지된다고 설명되어 있습니다. 즉 확장자가 .png라고 해서 내부 데이터까지 반드시 PNG 형식인 것은 아닙니다.
이 구조에서는 한 이미지에 다음 조합이 생길 수 있습니다.
- 업로드 원본
- 기본 최적화본
- 너비별 이미지
- 너비별 WebP 이미지
모든 조합이 만들어지면 파일 수가 빠르게 늘어납니다.
모든 이미지의 파생 파일 수가 같지는 않았습니다
그렇다면 이미지 한 장마다 160, 320, 600, 960, 1200, 2000픽셀 파일이 전부 만들어질까요? 실제 백업에서는 그렇지 않았습니다. 어떤 너비 폴더에는 파일이 많았고, 어떤 폴더에는 몇 개만 있었습니다.
Ghost의 동적 이미지 크기는 특정 크기의 주소가 처음 요청될 때 생성될 수 있습니다. 테마에서 사용하는 위치와 방문자가 실제로 연 페이지에 따라 만들어진 파생 파일이 달라질 수 있다는 뜻입니다. 테마를 바꾸거나 이미지 크기 설정을 변경하면 필요한 크기도 달라질 수 있습니다.
외부 이미지도 같은 방식으로 저장되는 것은 아닙니다. Ghost 서버에 직접 올린 파일이 아니라 Unsplash나 다른 외부 주소를 사용하는 이미지라면 로컬 이미지 폴더에 동일한 파생 구조가 생기지 않을 수 있습니다.
그래서 이미지 개수만 보고 실제 업로드 횟수를 역산하기는 어렵습니다. 파생 파일 119개가 있었다고 해서 이미지를 119번 올린 것은 아닙니다.
사용 중인 Ghost에서 임의로 지우면 안 됩니다
파일 구조를 알기 전에는 size 폴더와 _o 파일을 모두 지우면 깔끔해질 것 같았습니다. 그러나 운영 중인 Ghost라면 종류를 구분하지 않고 삭제하는 것은 피해야 합니다.
특히 _o 원본은 이후 다른 크기를 만들 때 사용될 수 있습니다. 크기별 파생 파일은 다시 생성 가능한 성격이 있지만, 테마와 설정, 저장 방식에 따라 동작이 달라질 수 있습니다. 디스크 공간을 정리하려면 적어도 다음 순서가 필요합니다.
- 콘텐츠와 이미지 폴더 전체를 먼저 백업합니다.
- 글과 페이지가 실제로 참조하는 이미지 주소를 수집합니다.
_o, 기본 최적화본과 파생 파일을 구분합니다.- 현재 테마가 요청하는 이미지 크기를 확인합니다.
- 일부 파일로 복구와 화면 표시를 시험한 뒤 정리 범위를 결정합니다.
저는 Ghost를 계속 운영하면서 용량을 줄이려던 것이 아니라 Astro로 이전할 예정이었습니다. 그래서 기존 폴더 안에서 파일을 먼저 지우지 않고, 원본 백업에는 163개를 그대로 남겼습니다.
Astro로 옮길 때는 공개 파일을 따로 골랐습니다
백업과 새 사이트의 공개 이미지 폴더는 목적이 다릅니다.
- 백업: 나중에 복원할 수 있도록 기존 구조 전체 보존
- 공개 폴더: 현재 글과 페이지가 실제로 사용하는 파일 제공
마이그레이션할 때 Ghost의 이미지 폴더 전체를 그대로 공개 폴더에 복사하지 않았습니다. 먼저 본문과 대표 이미지가 가리키는 /content/images/... 주소를 수집하고, 해당 주소가 실제 파일과 연결되는지 빌드 결과에서 검사했습니다.
Astro로 옮긴 뒤 새로 만든 대표 이미지는 필요한 크기와 형식으로 직접 준비하고 있습니다. 현재 minml에서는 주로 WebP 파일 한 장을 대표 이미지로 연결합니다. Ghost처럼 실행 중인 애플리케이션이 방문 요청에 맞춰 여러 파생 파일을 계속 만드는 구조는 아닙니다.
이 방식은 파일 구조가 단순한 대신 이미지 준비 책임이 저에게 있습니다. 너무 큰 원본을 그대로 올리면 Astro가 자동으로 모든 문제를 해결해주는 것은 아닙니다. 저장 방식을 직접 통제할 수 있다는 장점과 직접 최적화해야 한다는 책임이 함께 생겼습니다.
파일이 많은 것이 잘못은 아니었습니다
Ghost의 이미지 파일이 많았던 것은 같은 이미지를 실수로 계속 복사해서가 아니었습니다. 원본을 보존하면서 방문자에게는 화면에 맞는 가벼운 파일을 보내기 위한 구조였습니다. 실제로 블로그를 보여주는 입장에서는 합리적인 기능입니다.
다만 직접 서버를 백업하고 다른 플랫폼으로 옮기는 사람에게는 구조가 복잡하게 느껴질 수 있습니다. 저도 파일의 역할을 모를 때는 무엇을 지워도 되는지, 어떤 파일을 새 사이트로 가져가야 하는지 판단하기 어려웠습니다.
지금의 결론은 간단합니다. Ghost를 계속 사용한다면 파생 이미지를 오류 파일로 취급하지 말아야 합니다. 다른 플랫폼으로 옮긴다면 기존 구조를 먼저 통째로 백업하고, 새 사이트가 실제로 참조하는 이미지만 별도로 정리하는 편이 안전합니다.