
데이터를 잃은 뒤에 후회하면 이미 늦습니다
새벽 3시, 갑작스러운 서버 장애로 모든 서비스가 중단되었어요. 당황해서 급하게 도커 컴포즈(Docker Compose)를 재시작했지만, 화면에는 차가운 에러 메시지만 가득해요. 알고 보니 컨테이너 설정 파일에 적어둔 image 옵션은 단순한 설계도일 뿐이었고, 정작 중요한 데이터는 어디에도 저장되어 있지 않았어요.
이런 상황은 서비스 운영자라면 누구나 겪을 수 있는 아주 흔한 실수예요. 이미지(Image)만 잘 관리하면 되겠지라는 안일한 생각이 가장 위험해요. 이미지는 컨테이너를 실행하기 위한 환경일 뿐, 서비스의 핵심인 데이터는 별도의 볼륨이나 저장소에 존재하기 때문이죠. 데이터가 날아간 뒤에 복구 방법을 찾는 것은 사후약방문에 불과해요.
안정적인 컨테이너 운영을 위해서는 단순히 이미지를 내려받는 것을 넘어, 그 이미지가 사용하는 데이터와 상태를 어떻게 보존할지 명확한 전략이 필요해요. 컴포즈 image 옵션 백업은 단순히 파일을 복사하는 작업이 아니라, 서비스의 연속성을 보장하는 생존 전략이에요.
이 글에서는 데이터 손실의 공포에서 벗어나고 싶은 운영자와 개발자들을 위해 다음 내용을 구체적으로 다뤄요.
- 백업 대상이 되는 이미지와 볼륨의 차이점 명확히 구분하기
- 자동화를 위한 백업 스크립트 작성 및 스케줄링 방법
- 실제 장애 상황을 가정한 단계별 복구 실습
- 자주 하는 실수와 이를 방지하는 체크리스트
무엇을 어떻게 백업할 것인가: 사전 준비
무작정 백업을 시작하기 전에 반드시 짚고 넘어가야 할 지점이 있어요. 바로 백업 대상의 정의예요. 도커 컴포즈 환경에서 우리가 보호해야 할 대상은 크게 두 가지로 나뉘어요. 첫째는 컨테이너를 구동하는 소프트웨어 환경인 이미지이고, 둘째는 그 안에서 생성된 유저 데이터나 데이터베이스 파일이 담긴 볼륨(Volume)이에요.
많은 운영자가 범하는 오류 중 하나가 이미지 백업만 하면 모든 것이 해결될 것이라고 믿는 것이에요. 하지만 이미지 백업은 ‘어떤 버전의 소프트웨어를 쓸 것인가’를 결정하는 것이지, ‘그 소프트웨어가 쌓아온 데이터’를 지켜주는 것은 아니에요. 따라서 진정한 의미의 백업은 이미지와 볼륨을 동시에 고려해야 해요.
이미지는 읽기 전용(Read-only) 레이어의 집합이에요. 컨테이너가 실행되면서 변하는 데이터는 이미지에 포함되지 않고, 반드시 외부 저장소인 볼륨에 기록되어야 합니다.
백업 전략을 세울 때는 현재 서비스의 데이터 중요도와 변경 빈도를 기준으로 판단해야 해요. 아래 표를 통해 어떤 대상을 어떤 방식으로 백업해야 할지 기준을 확인해 보세요.
| 백업 대상 | 주요 목적 | 권장 도구 | 난이도 |
|---|---|---|---|
| 도커 이미지 | 소프트웨어 버전 유지 | docker save | 낮음 |
| 도커 볼륨 | 실제 유저 데이터 보존 | tar / rsync | 중간 |
| DB 데이터 | 논리적 데이터 무결성 | mysqldump / pg_dump | 중간 |
| 환경 설정 | 컨테이너 구동 환경 복구 | git / rsync | 낮음 |
백업을 시작하기 전, 반드시 컴포즈 image 옵션이 가리키는 정확한 이미지 이름과 태그를 확인하세요. 태그가 latest로 설정되어 있다면 백업 시점에 따라 버전이 달라질 수 있으므로, 가급적 고정된 버전 번호를 사용하는 것이 안전해요. 또한, 볼륨이 호스트의 특정 경로와 연결된 바인드 마운트(Bind Mount) 방식인지, 도커가 관리하는 명명된 볼륨(Named Volume) 방식인지도 미리 파악해야 백업 경로를 정확히 지정할 수 있어요.
실전! 컴포즈 백업 및 복구 프로세스
이제 이론을 넘어 실제 운영 환경에서 사용할 수 있는 단계별 실행 방법을 알아볼게요. 이 과정은 단순히 명령어를 입력하는 것이 아니라, 자동화된 워크플로우를 구축하는 데 초점을 맞춥니다.
STEP 1. 백업 대상 정밀 분석 및 경로 확보
먼저 현재 운영 중인 도커 컴포즈 파일(docker-compose.yml)을 열어보세요. 우리가 백업해야 할 리스트를 작성해야 합니다. 단순히 image: nginx:latest라고 적힌 줄만 보는 게 아니라, 그 아래에 있는 volumes: 섹션을 꼼꼼히 살펴봐야 해요.
예를 들어, 데이터베이스 서비스가 다음과 같이 설정되어 있다면 주의가 필요해요.
services:
db:
image: postgres:15
volumes:
- ./data:/var/lib/postgresql/data
- db_data:/var/lib/postgresql/data/backup
위 사례에서는 호스트의 현재 디렉토리(`./data`)와 도커 볼륨(`db_data`) 두 가지를 모두 백업해야 해요. 백업 파일을 저장할 디렉토리는 서비스 데이터와 물리적으로 분리된 안전한 곳(예: 별도의 마운트된 HDD 또는 클라우드 스토리지 연결 경로)으로 지정하세요. 절대 서비스 데이터와 같은 디스크 내에 백업 파일을 두지 마세요. 디스크 자체가 고장 나면 백업도 함께 사라집니다.
STEP 2. 자동화 백업 스크립트 작성
매번 수동으로 백업할 수는 없어요. 쉘 스크립트를 사용하여 이미지와 데이터를 한 번에 처리하는 구조를 만듭니다. 아래는 실무에서 바로 응용할 수 있는 기본 스크립트 예시예요.
#!/bin/bash
# 백업 설정
BACKUP_DIR="/mnt/backup/docker"
DATE=$(date +%Y%m%d_%H%M%S)
IMAGE_NAME="my-app-image:v1.2"
VOLUME_PATH="/var/lib/docker/volumes/my_app_data/_data"
# 디렉토리 생성
mkdir -p $BACKUP_DIR/$DATE
# 1. 이미지 백업 (docker save)
echo "이미지 백업 시작..."
docker save -o $BACKUP_DIR/$DATE/image_$DATE.tar $IMAGE_NAME
# 2. 볼륨 백업 (tar 이용)
echo "볼륨 데이터 백업 시작..."
tar -czf $BACKUP_DIR/$DATE/volume_$DATE.tar.gz $VOLUME_PATH
echo "백업 완료: $DATE"
여기서 중요한 점은 데이터 무결성이에요. 데이터베이스처럼 파일이 계속 쓰여지는 서비스는 tar로 그냥 묶어버리면 파일이 깨질 수 있어요. 이럴 때는 반드시 docker exec를 사용해 데이터베이스 자체 명령어로 덤프를 먼저 뜬 후, 그 덤프 파일을 백업해야 합니다.
STEP 3. 크론탭(Crontab)을 이용한 스케줄링
작성한 스크립트를 매일 새벽, 트래픽이 가장 적은 시간에 실행되도록 설정해야 해요. 리눅스의 크론탭(Crontab)을 활용하면 간단해요.
터미널에 crontab -e를 입력하고 아래 내용을 추가하세요.
# 매일 새벽 2시에 백업 스크립트 실행
00 02 * * * /path/to/your/backup_script.sh
이렇게 설정하면 별도의 관리 없이도 매일 규칙적으로 백업 파일이 생성됩니다. 다만, 백업 파일이 계속 쌓이면 디스크 용량이 부족해지므로, 7일 혹은 30일이 지난 오래된 백업은 자동으로 삭제하는 로직을 스크립트에 반드시 추가해야 해요.
STEP 4. 장애 발생 시 복구 절차 실습
백업보다 중요한 것이 복구예요. 실제 상황을 가정해 봅시다. 서버가 완전히 깨졌고, 새 서버에 도커를 설치했습니다. 이제 어떻게 복구할까요?
- 이미지 복구: 백업해둔 tar 파일을 불러옵니다.
docker load -i /mnt/backup/old_date/image_old_date.tar - 데이터 복구: 볼륨 경로를 만들고 압축을 풉니다.
mkdir -p /var/lib/docker/volumes/my_app_data/_datatar -xzf /mnt/backup/old_date/volume_old_date.tar.gz -C /var/lib/docker/volumes/my_app_data/_data --strip-components=1 - 서비스 재시작: 컴포즈 파일을 실행합니다.
docker-compose up -d
복구 후에는 반드시 서비스 로그를 확인하여 데이터베이스가 정상적으로 마운트되었는지, 권한 문제는 없는지 체크해야 해요.
STEP 5. 복구 훈련과 정기 검증
백업 파일이 잘 생성되었다고 해서 안심하지 마세요. 파일이 0바이트이거나, 압축이 깨져 있을 수도 있으니까요. 정기적인 복구 테스트는 선택이 아닌 필수입니다.
한 달에 한 번은 실제 운영 서버가 아닌 별도의 테스트 환경에서 백업 파일을 이용해 서비스를 완전히 재구동하는 연습을 하세요. 이 과정을 통해 백업 스크립트의 오류나 복구 절차의 병목 구간을 미리 발견할 수 있습니다.
복구 테스트를 할 때는 반드시 운영 환경과 동일한 도커 버전을 사용하는 것이 좋습니다. 버전 차이로 인해 데이터 구조가 달라져 복구에 실패하는 경우가 빈번하기 때문입니다.
자주 하는 실수와 해결법
운영 현장에서 가장 많이 발생하는 실수들을 모아 정리했어요. 비슷한 문제를 겪고 있다면 아래 해결법을 즉시 적용해 보세요.
- ❌ 이미지만 백업하고 볼륨을 잊어버림
→ 왜 발생하는가:image옵션에만 집중하여 데이터의 영속성을 간과함.
✅ 해결법: 반드시volumes섹션을 확인하고 별도의 압축 백업을 병행하세요. - ❌ 실행 중인 데이터베이스 파일을 그대로 압축함
→ 왜 발생하는가: 데이터가 쓰여지는 도중에 파일을 읽으면 파일이 깨짐(Corruption).
✅ 해결법:mysqldump같은 도구를 사용해 논리적 덤프를 먼저 수행하세요. - ❌ 백업 파일 저장 공간 부족
→ 왜 발생하는가: 백업 파일이 무한정 쌓여 디스크 용량을 점유함.
✅ 해결법: 스크립트에find명령어를 이용한 자동 삭제 로직을 넣으세요. - ❌ 권한(Permission) 문제로 복구 실패
→ 왜 발생하는가: 복구한 볼륨 파일의 소유권이 루트(root)로 바뀌어 컨테이너가 접근 못 함.
✅ 해결법: 복구 후chown명령어로 적절한 UID/GID를 부여하세요. - ❌ 환경 변수(.env) 백업 누락
→ 왜 발생하는가: 이미지와 데이터는 있지만, 실행 설정값이 없어 구동이 안 됨.
✅ 해결법:.env파일도 반드시 백업 대상에 포함하세요.
자주 묻는 질문
Q. docker commit 명령어로 컨테이너를 이미지로 만들어 백업하면 안 되나요?
A. 권장하지 않아요. docker commit은 컨테이너의 변경 사항을 이미지로 만드는 방식인데, 용량이 비대해지고 관리가 어려워져요. 무엇보다 볼륨에 담긴 데이터는 이미지에 포함되지 않기 때문에 결국 데이터 백업은 따로 해야 해요.
Q. 백업 주기는 어느 정도가 적당할까요?
A. 서비스의 데이터 변경 빈도에 따라 달라요. 결제 정보처럼 실시간으로 변하는 데이터가 중요하다면 매시간 혹은 매일 수행해야 하고, 정적인 설정 파일 위주라면 주 단위로도 충분해요.
Q. 백업 파일을 어디에 보관하는 게 가장 안전한가요?
A. 가장 좋은 방법은 ‘3-2-1 법칙’을 따르는 거예요. 3개의 복사본을, 2가지 다른 매체에 저장하고, 1개는 반드시 물리적으로 떨어진 곳(클라우드 스토리지 등)에 보관하는 것이죠.
Q. 도커 컴포즈 이미지 백업 시 태그를 latest로 써도 괜찮을까요?
A. 운영 환경에서는 매우 위험해요. latest는 언제든 바뀔 수 있기 때문에, 백업 시점의 이미지가 무엇인지 추적하기 어려워져요. 반드시 버전 번호(예: v1.2.3)를 명시하세요.
Q. 볼륨 백업 시 컨테이너를 잠시 멈춰야 하나요?
A. 데이터 무결성을 위해서는 서비스를 일시 정지(docker-compose stop)하거나, 최소한 쓰기 작업이 없는 상태에서 진행하는 것이 가장 안전해요.
안정적인 운영을 위한 마지막 체크리스트
백업은 ‘준비’하는 것이 아니라 ‘실행’하는 것입니다. 아무리 완벽한 스크립트를 짜놓았어도, 실제로 복구가 되지 않는다면 그것은 백업이 아니에요. 오늘 정리한 내용을 바탕으로 지금 당장 여러분의 시스템을 점검해 보세요.
- 이미지는 환경을, 볼륨은 데이터를 담당함을 명심하세요.
- 백업 스크립트는 이미지(save)와 볼륨(tar)을 모두 포함해야 합니다.
- DB 데이터는 반드시 덤프(Dump) 방식을 활용하세요.
- 크론탭을 이용해 자동화하고, 오래된 파일은 자동 삭제하세요.
- 한 달에 한 번은 반드시 별도 환경에서 복구 테스트를 진행하세요.
지금 바로 할 수 있는 일부터 시작해 보세요. 거창한 자동화가 아니더라도, 오늘 밤에는 수동으로라도 이미지와 볼륨을 압축해서 다른 저장소에 옮겨 두는 연습을 해보시는 건 어떨까요? 복구는 실제로 한 번 해봐야 믿을 수 있습니다. 오늘 바로 작은 테스트라도 예약하고 실행해 보세요.
더 깊이 있는 도커 운영 지식이 필요하다면 아래 가이드를 참고해 보세요.
관련 글: 도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드