Docker WordPress 백업과 복구를 PowerShell로 자동화한 방법

Docker로 WordPress를 운영하면서 가장 불안했던 순간은 업데이트 자체보다 “문제가 생겼을 때 정말 이전 상태로 돌아갈 수 있는가”였다. 이 사이트는 WordPress 파일과 MariaDB 데이터가 서로 다른 named volume에 들어 있으므로 한쪽만 복사해서는 온전한 백업이 되지 않는다. 그래서 데이터베이스 덤프와 WordPress 파일 묶음을 한 번에 만들고, 복원 전에는 다시 안전 백업을 남기는 PowerShell 절차를 직접 구성했다.

현재 저장 구조부터 구분했다

게시물 본문, 설정과 사용자 정보는 MariaDB에 있고, 업로드 이미지·플러그인·워드프레스 파일은 hongzi_blog_app_data 볼륨에 있다. Compose 파일과 환경변수만 보관해도 실제 게시물과 이미지는 돌아오지 않는다.

MariaDB volume  ── mariadb.sql
WordPress volume ── wordpress-files.tar.gz
Compose·image 정보 ── compose.yml, image-digests.txt

Docker 공식 문서도 volume의 내용은 컨테이너 생명주기와 분리되어 유지되고, 별도의 컨테이너에 volume과 백업 디렉터리를 함께 마운트해 보관할 수 있다고 설명한다. 이 구조를 그대로 Windows PowerShell 스크립트에 적용했다.

데이터베이스는 실행 중에도 일관성을 우선했다

백업 스크립트는 먼저 WordPress와 MariaDB 컨테이너가 실제로 존재하는지 확인한다. 그다음 DB 컨테이너 안에서 다음 옵션으로 덤프한다.

mariadb-dump \
  --single-transaction \
  --quick \
  --routines \
  --events \
  -u"$MARIADB_USER" \
  -p"$MARIADB_PASSWORD" \
  "$MARIADB_DATABASE"

--single-transaction은 InnoDB 테이블을 덤프하는 동안 긴 쓰기 잠금을 피하기 위해 사용했고, --quick은 큰 결과를 한꺼번에 메모리에 올리지 않도록 넣었다. 덤프가 끝나면 파일 크기가 0보다 큰지 확인한다. 명령이 종료됐다는 사실만으로 정상 백업이라고 판단하지 않기 위해서다.

WordPress volume은 읽기 전용으로 묶었다

파일 백업에는 임시 Alpine 컨테이너를 사용한다. 원본 volume은 :ro로 연결해 백업 과정이 원본 파일을 변경하지 못하게 했다.

docker run --rm `
  -v hongzi_blog_app_data:/data:ro `
  -v "백업폴더:/backup" `
  alpine:3.20 `
  tar -czf /backup/wordpress-files.tar.gz -C /data .

생성된 압축 파일도 존재 여부와 크기를 검사한다. 실제 비밀번호가 든 .env는 묶음에 넣지 않고, 변수 이름만 있는 .env.example을 저장한다. 대신 사용한 WordPress·MariaDB 이미지의 ID와 digest를 함께 기록해 나중에 어떤 실행 환경에서 만든 백업인지 확인할 수 있게 했다.

백업 폴더에 manifest를 남긴 이유

시간이 지난 뒤 파일만 보면 어느 사이트의 어떤 방식으로 만든 백업인지 헷갈린다. 그래서 각 백업 폴더에는 생성 시각, 프로젝트 이름, DB 덤프 파일명, WordPress 파일명, 환경변수 포함 여부를 적은 manifest.txt를 만든다.

created_at=2026-08-24T...
project=hongzi_blog
database_dump=mariadb.sql
wordpress_files=wordpress-files.tar.gz
env_included=false

-Keep 값보다 오래된 묶음은 백업 디렉터리 안에서만 정리한다. 보관 개수를 0으로 지정하면 자동 삭제를 하지 않도록 구성했다.

복원은 일부러 쉽게 실행되지 않게 했다

복원은 현재 volume과 DB를 덮어쓰므로 -ConfirmOverwrite를 명시하지 않으면 중단된다. 대상 경로에 mariadb.sqlwordpress-files.tar.gz가 모두 있는지도 먼저 확인한다.

  1. 현재 상태를 새 백업으로 한 번 더 저장한다.
  2. 지정한 WordPress volume만 비우고 압축 파일을 푼다.
  3. MariaDB 덤프를 원래 데이터베이스에 입력한다.
  4. WordPress 컨테이너를 재시작한다.
  5. 컨테이너와 공개 URL 상태 검사를 실행한다.

복원 전에 다시 백업하는 단계가 중요하다. 잘못된 날짜의 백업을 선택했더라도 복원 직전 상태로 되돌아갈 마지막 선택지를 남겨주기 때문이다.

아직 남아 있는 한계

파일이 생성되고 크기가 정상이라는 것은 “백업 명령이 끝났다”는 증거일 뿐 완전한 복원 가능성을 보장하지 않는다. 정기적으로 별도 테스트 환경에 복원해 로그인, 이미지, 고정 링크와 주요 글을 확인해야 한다. 또한 이 백업은 같은 Docker host에 먼저 저장되므로, 디스크 고장에 대비하려면 NAS나 다른 저장소로 추가 복사해야 한다.

운영 체크리스트

  • DB와 WordPress 파일을 같은 시점의 한 묶음으로 관리한다.
  • 백업에 실제 .env를 무심코 포함하지 않는다.
  • 원본 volume은 백업할 때 읽기 전용으로 연결한다.
  • 복원 전에 현재 상태를 다시 백업한다.
  • 생성 확인과 복원 테스트를 서로 다른 단계로 운영한다.

이 백업 구조는 Docker WordPress 캐시와 이미지 최적화 작업 전후에도 동일하게 사용하고 있다.

참고한 공식 문서