운영·보안

Astro 블로그는 무엇을 백업해야 할까, 직접 정리한 복구 방법

Astro 소스, Markdown 글, 이미지, package-lock과 배포 결과물을 구분해 백업하고 복구하는 방법을 실제 운영 구조로 설명합니다.

웹페이지를 보관한 차콜 백업 상자와 복구된 사이트를 연결한 3D 클레이 이미지

Ghost를 운영할 때는 글만 백업한다고 끝나지 않았습니다. 데이터베이스와 이미지, 설정 파일, 테마와 웹 서버 구성을 함께 생각해야 했습니다. Astro로 옮기면 데이터베이스가 사라지니 백업도 아주 간단해질 것 같았습니다.

실제로 구조는 단순해졌습니다. 하지만 Markdown 글만 복사해두면 사이트 전체를 복구할 수 있는 것은 아닙니다. 디자인 코드와 이미지, 빌드 설정, 설치할 패키지의 버전을 함께 보관해야 원래 모습으로 다시 만들 수 있습니다.

현재 minml은 소스와 실제 배포 결과물을 나눠 백업하고 있습니다. 이 글에서는 무엇을 보관하고 무엇을 제외했는지, 문제가 생겼을 때 어떻게 복구할 계획인지 정리합니다.

데이터베이스가 없어도 백업은 필요합니다

정적 블로그에 데이터베이스가 필요 없는 이유에서 설명했듯이 현재 글은 데이터베이스가 아니라 Markdown 파일에 저장됩니다. 그렇다고 백업이 필요 없다는 뜻은 아닙니다.

오히려 프로젝트 폴더가 사이트의 원본에 가까워졌습니다. 이 폴더를 잃어버리면 다음 내용도 함께 사라집니다.

  • 작성한 글과 고정 페이지
  • 대표 이미지와 본문 이미지
  • 홈페이지와 글 화면의 디자인
  • 주소와 리디렉션 설정
  • RSS와 사이트맵 구성
  • 빌드와 검사 스크립트
  • 사용 중인 패키지와 버전 정보

서버에 HTML이 남아 있다면 방문자가 사이트를 보는 것은 가능할 수 있습니다. 하지만 HTML만 가지고 원래 Markdown과 Astro 구성 요소를 완전히 되돌리는 일은 어렵습니다. 공개된 결과물과 수정 가능한 원본은 역할이 다릅니다.

소스와 배포 결과물을 따로 보관합니다

minml의 백업은 크게 두 파일로 나뉩니다.

백업 종류 들어 있는 내용 사용하는 상황
소스 백업 글, 이미지, Astro 코드와 설정 수정 가능한 프로젝트 전체 복구
배포 결과물 백업 빌드가 끝난 HTML, CSS와 이미지 직전 사이트를 빠르게 다시 공개

소스 백업이 있으면 프로젝트를 다시 설치하고 빌드할 수 있습니다. 하지만 Node.js와 패키지를 설치하고 빌드 검사를 거쳐야 하므로 시간이 필요합니다.

배포 결과물은 이미 완성된 정적 사이트입니다. 서버에 문제가 생겼거나 새 배포가 잘못됐을 때 압축을 풀어 이전 공개 상태로 빠르게 돌아갈 수 있습니다. 대신 글을 수정하거나 디자인을 계속 개발하기 위한 원본으로 사용하기는 어렵습니다.

둘 중 하나를 선택하기보다 두 종류를 함께 남겨두는 이유입니다.

실제로 소스 백업에 넣은 항목

현재 소스 압축본에는 다음 파일과 폴더가 들어 있습니다.

src/content/posts/
src/content/pages/
src/layouts/
src/pages/
src/styles/
public/
scripts/
astro.config.mjs
src/content.config.ts
package.json
package-lock.json
tsconfig.json

src/content에는 Markdown 글과 각 글의 제목, 주소, 날짜 같은 정보가 있습니다. public에는 대표 이미지, 본문 이미지와 파비콘이 있습니다. 레이아웃과 스타일을 빼면 글은 복구돼도 현재의 화면은 돌아오지 않습니다.

astro.config.mjs도 중요합니다. 사이트의 기본 주소와 URL 형식, 사이트맵과 리디렉션 설정이 들어 있기 때문입니다. 이전 글 주소를 새 글로 보내는 규칙을 잃으면 백업에서 사이트를 되살려도 기존 링크 일부가 깨질 수 있습니다.

package-lock도 함께 보관했습니다

처음에는 package.json만 있으면 필요한 패키지를 다시 설치할 수 있다고 생각했습니다. 하지만 package.json에는 허용하는 버전 범위가 들어갈 수 있고, package-lock.json에는 실제로 결정된 의존성 트리가 기록됩니다.

같은 프로젝트를 나중에 다시 설치할 때 패키지 버전이 달라지면 예전에는 되던 빌드가 실패하거나 출력이 달라질 수 있습니다. npm 공식 문서도 잠금 파일이 동일한 의존성 트리를 다시 설치하기 위한 파일이라고 설명합니다.

그래서 다음 두 파일은 한 묶음으로 취급합니다.

package.json
package-lock.json

복구할 때는 잠금 파일과 package.json이 일치하는지 검사하는 npm ci를 사용할 수 있습니다. 설치된 패키지 폴더를 통째로 백업하는 대신, 설치 기준을 보관하고 필요할 때 다시 만드는 방식입니다.

node_modules는 백업에서 제외했습니다

현재 소스 백업에는 node_modules가 들어 있지 않습니다. 이 폴더는 설치된 패키지의 실제 파일을 모아둔 곳이라 크기가 크고 파일 수도 많습니다. 운영체제나 Node.js 환경에 따라 다시 설치하는 편이 더 안전할 수도 있습니다.

다음 항목도 소스 압축본에서 제외했습니다.

  • node_modules: 잠금 파일을 기준으로 다시 설치 가능
  • .astro: Astro가 다시 만드는 작업 캐시
  • dist: 별도의 배포 결과물 압축본으로 보관
  • 개발 서버 로그: 사이트 원본이 아님
  • 기존 백업 폴더: 백업 안에 백업이 반복되는 것을 방지
  • Ghost 마이그레이션 원본: 일반 배포 백업과 분리해 보관

제외한다는 것이 중요하지 않다는 뜻은 아닙니다. Ghost 마이그레이션 원본과 과거 전체 백업은 별도 보관 중입니다. 매번 만드는 Astro 소스 백업에 반복해서 넣지 않는다는 의미입니다.

dist는 다시 만들 수 있지만 별도로 보관합니다

Astro는 npm run build를 실행하면 기본적으로 dist 폴더에 배포 가능한 결과물을 만듭니다. 원칙적으로는 소스와 패키지 정보가 있으면 dist를 다시 만들 수 있습니다.

그럼에도 minml은 실제 서버에 올린 dist를 별도 압축본으로 남깁니다. “이 소스로 비슷한 사이트를 다시 만들 수 있다”와 “그때 서버에 올라간 파일과 정확히 같은 결과가 있다”는 서로 다른 상태이기 때문입니다.

예를 들어 패키지 설치 환경이 바뀌었거나, 소스 백업 직후 일부 파일을 수정했다면 다시 만든 결과가 실제 배포본과 다를 수 있습니다. 배포본을 보관하면 새 버전에 문제가 생겼을 때 빌드 환경을 복구하기 전에 직전 화면으로 먼저 돌아갈 수 있습니다.

현재 백업 묶음을 직접 확인했습니다

이 글을 작성하면서 로컬에 남은 배포 시점별 백업을 다시 확인했습니다. 총 14개의 백업 묶음이 있었고, 최근 묶음은 약 27.57MB였습니다.

파일 크기 역할
소스 압축본 약 13.82MB 글과 이미지, 코드 및 설정 복구
배포 결과물 압축본 약 13.75MB 직전 공개 사이트 복구
체크섬 기록 매우 작음 파일이 바뀌거나 손상됐는지 확인
서버 설정 백업 매우 작음 사이트 연결 설정 복구에 참고

소스 압축본에는 104개 항목이 있었고 글과 공개 이미지가 포함되어 있었습니다. node_modules, dist, 기존 백업과 마이그레이션 원본은 들어 있지 않았습니다. 배포 결과물에는 93개 항목이 있었고 홈페이지, 사이트맵과 공개 이미지가 포함되어 있었습니다.

체크섬 기록에 등록된 세 파일도 다시 계산해 비교했고 모두 일치했습니다. 다만 체크섬이 맞는다는 것은 파일이 백업 당시와 같다는 뜻이지, 사이트가 반드시 정상적으로 복구된다는 뜻까지 보장하지는 않습니다.

백업 파일 자체는 공개하면 안 됩니다

소스 코드가 공개돼도 괜찮은 프로젝트가 많지만, 운영 중인 사이트의 백업은 별개로 생각하는 편이 안전합니다. 설정 파일이나 과거 자료에 다음 정보가 섞일 수 있기 때문입니다.

  • 서버 내부 경로와 계정 정보
  • 데이터베이스 접속 정보
  • API 키와 환경 변수
  • 웹 서버와 인증서 설정
  • 삭제한 글과 공개하지 않은 초안
  • 방문자나 회원 관련 데이터

현재 minml의 일반 소스 백업에서는 .env를 제외하고 있습니다. 서버 설정은 필요한 경우에만 별도 백업하고 공개 저장소에 올리지 않습니다. Ghost 시절의 데이터베이스와 설정 백업도 Astro 배포 백업과 분리해 비공개로 보관하고 있습니다.

블로그 글에서 백업 구조를 설명할 때도 실제 서버 주소, 내부 경로, 계정명과 체크섬 원문은 공개하지 않았습니다. 백업 방법을 설명하는 데 필요한 정보와 서버에 접근하는 데 도움이 될 수 있는 정보는 구분해야 합니다.

복구 방법은 두 가지로 나눴습니다

문제의 범위에 따라 복구 방식도 달라집니다.

직전 사이트로 빠르게 돌아가는 경우

새로운 글이나 디자인을 배포한 뒤 오류가 발견됐다면, 직전 배포 결과물 백업을 사용합니다.

  1. 이전 배포 압축본의 체크섬을 확인합니다.
  2. 기존 운영 폴더를 직접 덮어쓰지 않고 새 위치에 압축을 풉니다.
  3. 홈페이지와 주요 글, 이미지가 열리는지 확인합니다.
  4. 사이트가 가리키는 대상을 이전 결과물로 전환합니다.
  5. HTTPS, 리디렉션, RSS와 사이트맵을 다시 확인합니다.

새 위치에 먼저 푸는 이유는 복구 도중 파일이 반쯤 섞이는 상태를 피하기 위해서입니다. 검사가 끝난 완성본으로 한 번에 전환하면 현재 버전으로 다시 돌아가는 것도 쉽습니다.

편집 가능한 프로젝트 전체를 복구하는 경우

컴퓨터를 바꾸거나 프로젝트 폴더 전체를 잃었다면 소스 백업을 사용합니다.

  1. 소스 압축본의 체크섬과 내부 목록을 확인합니다.
  2. 새로운 작업 폴더에 압축을 풉니다.
  3. 지원되는 Node.js 환경을 준비합니다.
  4. npm ci로 잠금 파일에 맞는 패키지를 설치합니다.
  5. Astro 검사와 빌드를 실행합니다.
  6. 내부 링크와 이미지 경로를 검사합니다.
  7. 새 배포 결과물을 만들어 서버에 올립니다.

이 방법으로는 Markdown 원문과 디자인 코드를 다시 수정할 수 있습니다. 대신 패키지 설치와 빌드 환경까지 정상이어야 하므로 직전 배포본을 되돌리는 것보다 시간이 더 걸릴 수 있습니다.

백업 성공과 복구 성공은 다릅니다

압축 파일을 만들었다고 백업이 끝난 것은 아닙니다. 최소한 다음 항목을 확인해야 합니다.

  • 압축 파일 내부 목록을 읽을 수 있는가
  • 예상한 글과 이미지가 포함돼 있는가
  • 비밀번호와 환경 변수가 실수로 포함되지 않았는가
  • 체크섬이 백업 직후와 복사 후에 일치하는가
  • 배포 결과물에 홈페이지와 사이트맵이 있는가
  • 소스에서 패키지 설치와 빌드를 다시 수행할 수 있는가

현재 백업은 압축 목록과 체크섬까지 확인했습니다. 다만 최신 백업을 빈 컴퓨터에서 처음부터 복구하는 전체 훈련까지 매번 수행하는 것은 아닙니다. 그래서 중요한 변경 전에는 직전 배포본을 남기고, 새 배포가 실제 서버에서 확인될 때까지 이전 버전을 제거하지 않습니다.

백업을 여러 개 보관하는 이유도 여기에 있습니다. 가장 최근 파일이 이미 잘못된 상태일 수 있으므로 정상 동작을 확인한 이전 시점이 함께 있어야 합니다.

CMS보다 단순하지만 자동으로 안전해지지는 않습니다

Astro로 옮긴 뒤 데이터베이스 덤프와 CMS 프로그램 전체를 매번 백업할 필요는 없어졌습니다. 글과 이미지, 코드가 일반 파일로 보이기 때문에 무엇을 보관하는지도 이해하기 쉬워졌습니다.

하지만 정적 사이트라고 자동으로 안전한 것은 아닙니다. 로컬 프로젝트가 유일한 원본인데 디스크가 고장 나면 글과 디자인을 함께 잃을 수 있습니다. 같은 컴퓨터 안의 다른 폴더에 복사하는 것만으로는 컴퓨터 전체 고장이나 랜섬웨어에 대비하기도 어렵습니다.

현재처럼 시점별 로컬 백업을 만드는 것에 더해, 앞으로는 암호화된 외부 저장소나 비공개 원격 저장소에 한 부를 추가하는 편이 더 안전합니다. 중요한 것은 백업 도구의 이름보다 서로 다른 장소에 복구 가능한 원본이 존재하는지입니다.

지금의 운영 기준은 명확합니다. 글과 이미지를 포함한 소스를 보관하고, 실제 배포한 정적 결과물을 함께 남기고, 두 파일의 무결성을 확인합니다. 데이터베이스는 없어졌지만 백업에서 확인해야 할 일까지 사라진 것은 아닙니다.

참고한 공식 문서