
갑작스러운 서버 장애, 빌드 환경까지 사라졌다면?
어제까지만 해도 아무 문제 없이 돌아가던 서비스가 갑자기 멈춰버린 경험이 있으신가요? 서버를 새로 구축하거나 설정 파일이 꼬여서 급하게 도커 컴포즈(Docker Compose)를 다시 실행하려고 할 때, 예상치 못한 벽에 부딪히곤 해요. 단순히 실행 중인 컨테이너만 살리면 된다고 생각했지만, 정작 빌드에 필요한 파일들이 사라졌거나 빌드 컨텍스트(Build Context) 설정이 엉망이 되어 있다면 서비스 복구는 불가능에 가까워져요.
많은 운영자가 데이터베이스의 데이터만 백업하면 안전하다고 착각하곤 해요. 하지만 컨테이너 환경 자체를 재현할 수 있는 빌드 옵션과 그 바탕이 되는 파일들이 없다면, 똑같은 환경을 다시 만드는 데 수 시간, 혹은 수일이 걸릴 수도 있어요. 빌드 옵션 하나를 잘못 설정해도 의존성 라이브러리가 달라지거나 보안 설정이 풀려버리는 치명적인 사고로 이어지기도 하죠.
이 글은 단순히 파일을 복사하는 법을 알려드리는 것이 아니에요. 서비스의 연속성을 보장하기 위해 컴포즈 build 옵션 백업을 어떻게 체계적으로 수행하고, 실제 사고가 터졌을 때 얼마나 빠르게 정상 상태로 되돌릴 수 있는지에 대한 실무적인 절차를 다뤄요. 안정적인 컨테이너 운영을 꿈꾸는 개발자와 운영자라면 반드시 이 과정을 숙지해야 해요.
이 글을 읽고 나면 다음과 같은 내용을 명확히 알 수 있어요.
- 빌드 컨텍스트와 옵션이 왜 백업 대상에 포함되어야 하는지 이해해요.
- 실무에서 바로 쓸 수 있는 백업 스크립트 구성 방법을 배워요.
- 실패 없는 복구 절차를 실습하고 검증하는 법을 익혀요.
- 데이터 손실 위험을 최소화하는 운영 정책을 수립할 수 있어요.
사전 준비 — 백업 대상 파악과 체크리스트
무작정 백업을 시작하기 전에 우리가 무엇을 보호해야 하는지 정확히 알아야 해요. 컨테이너 운영 환경에서 백업은 크게 두 가지 영역으로 나뉘어요. 하나는 컨테이너 내부의 데이터가 저장되는 볼륨(Volume)이고, 다른 하나는 컨테이너를 만드는 설계도인 빌드 옵션과 컨텍스트예요. 우리는 오늘 후자에 집중할 거예요.
빌드 옵션이란 `docker-compose.yml` 파일 내의 `build:` 섹션에 정의된 설정들을 말해요. 여기에는 `context`(빌드에 사용할 파일 경로), `dockerfile`(사용할 Dockerfile 이름), `args`(빌드 시 전달할 변수) 등이 포함되죠. 이 정보들이 유실되면, 설령 소스 코드가 남아있더라도 기존과 동일한 환경의 이미지를 생성할 수 없게 돼요.
빌드 컨텍스트는 Dockerfile이 실행될 때 참조하는 로컬 디렉토리 전체를 의미해요. 이 디렉토리 안에 있는 `.dockerignore` 파일 설정까지 백업해야 불필요한 파일이 빌드에 포함되는 것을 방지할 수 있어요.
백업 전략을 세우기 위해 먼저 아래 표를 통해 어떤 부분을 중점적으로 관리해야 하는지 비교해 보세요.
| 백업 대상 | 핵심 내용 | 중요도 | 실패 시 결과 |
|---|---|---|---|
| 데이터 볼륨 | DB 데이터, 사용자 업로드 파일 | 매우 높음 | 서비스 데이터 완전 손실 |
| 빌드 컨텍스트 | Dockerfile, 소스 코드, 설정 파일 | 높음 | 이미지 재생성 불가 |
| 컴포즈 파일 | docker-compose.yml, 환경 변수(.env) | 매우 높음 | 인프라 구성 정의 상실 |
백업을 시작하기 전에 반드시 확인해야 할 사항들이 있어요. 첫째, `docker-compose.yml` 파일에 명시된 `context` 경로가 절대 경로인지 상대 경로인지 확인하세요. 상대 경로라면 현재 작업 디렉토리를 기준으로 백업 범위가 결정돼요. 둘째, 빌드 시 사용하는 build args가 외부 환경 변수 파일(`.env`)에 저장되어 있는지 확인하세요. 이 파일이 백업에서 빠지면 빌드 단계부터 오류가 발생해요. 셋째, 빌드에 참여하는 모든 로컬 파일의 권한 설정을 체크하세요. 백업 후 복구했을 때 권한 문제로 빌드가 실패하는 경우가 아주 많거든요.
단계별 실행 — 안전한 백업과 완벽한 복구 절차
이제 본격적으로 컴포즈 build 옵션 백업을 수행하고, 실제 상황에서 이를 어떻게 복구하는지 단계별로 살펴볼게요. 이 과정은 단순히 파일을 복사하는 것을 넘어, 시스템의 상태를 스냅샷처럼 저장하는 과정이라고 생각하시면 돼요.
STEP 1. 빌드 자산 및 컴포즈 설정 분석하기
가장 먼저 해야 할 일은 현재 운영 중인 서비스의 빌드 구조를 파악하는 것이에요. `docker-compose.yml` 파일을 열어 `build:` 섹션을 꼼꼼히 살펴보세요. 만약 `context: ./app`이라고 되어 있다면, `./app` 디렉토리 안에 있는 모든 파일이 백업 대상이 되어야 해요. 이때 주의할 점은 단순히 소스 코드만 챙기는 것이 아니라, 빌드 환경을 구성하는 Dockerfile과 빌드 옵션을 결정짓는 build args 값들을 모두 파악해야 한다는 점이에요.
특히 `.env` 파일은 백업의 핵심이에요. 컴포즈 파일에서 `${VERSION}` 같은 변수를 사용하고 있다면, 그 실제 값이 담긴 `.env` 파일이 없이는 백업본을 가지고도 빌드를 시작할 수 없어요. 따라서 백업 대상 리스트에 반드시 컴포즈 파일, `.env` 파일, 그리고 `context`로 지정된 디렉토리 전체를 포함시켜야 해요.
STEP 2. 통합 백업 스크립트 작성 및 구성하기
매번 수동으로 파일을 압축해서 옮기는 것은 매우 위험해요. 실수가 생길 수밖에 없기 때문이죠. 따라서 쉘 스크립트(Shell Script)를 활용해 자동화된 백업 체계를 갖추는 것이 좋아요. 스크립트는 다음과 같은 흐름으로 구성하는 것을 추천해요.
- 대상 확인: `docker-compose.yml` 파일이 존재하는지 확인해요.
- 경로 추출: 컴포즈 파일 내의 `context` 경로를 찾아내요.
- 압축 수행: `tar` 명령어를 사용하여 컴포즈 파일, `.env`, 그리고 빌드 컨텍스트 디렉토리를 하나의 아카이브 파일로 묶어요.
- 타임스탬프 부여: 파일명에 `backup_20231027_1430.tar.gz`와 같이 날짜와 시간을 포함시켜 관리해요.
- 원격 전송: 생성된 파일을 별도의 백업 서버나 클라우드 스토리지(S3 등)로 즉시 전송해요.
백업 파일의 용량이 너무 크다면, 빌드 과정에서 생성된 불필요한 캐시 파일이나 임시 파일들을 `.dockerignore` 파일에 명시하여 압축 대상에서 제외하는 것이 효율적이에요.
STEP 3. 자동화 스케줄링과 모니터링 설정
백업 스크립트를 만들었다면, 이제 이를 정기적으로 실행하도록 만들어야 해요. 리눅스 환경이라면 cron을 사용하는 것이 가장 일반적이고 안정적이에요. 예를 들어, 매일 새벽 3시에 백업을 수행하도록 설정할 수 있어요.
하지만 스케줄링만 걸어둔다고 끝이 아니에요. 백업이 실제로 성공했는지, 스토리지 용량이 부족해서 백업이 누락되지는 않았는지 확인하는 모니터링이 필수예요. 백업 스크립트의 마지막 단계에 실행 결과(Exit Code)를 체크하여, 실패했을 경우 관리자에게 슬랙(Slack)이나 이메일로 알림을 보내는 로직을 반드시 추가하세요. 알림이 오지 않는다고 해서 백업이 잘 되고 있다고 믿는 것은 매우 위험한 생각이에요.
STEP 4. 실전 복구 시나리오 실습
이제 가장 중요한 복구 단계예요. 백업본이 있다고 해서 안심하지 마세요. 실제 복구 테스트를 해보지 않았다면 그 백업은 무용지물이나 다름없어요. 아래는 서버가 완전히 초기화되었을 때를 가정한 복구 시나리오예요.
- 환경 재구축: 도커(Docker)와 도커 컴포즈가 설치된 새로운 서버를 준비해요.
- 백업본 다운로드: 원격 스토리지에서 가장 최근의 백업 아카이브 파일을 가져와요.
- 압축 해제: `tar -xzvf backup_file.tar.gz` 명령어로 파일을 원래의 디렉토리 구조로 풀어내요.
- 권한 재설정: 복구된 파일들의 소유권과 실행 권한이 기존과 동일한지 확인해요. (예: `chown -R user:group .`)
- 컨테이너 빌드 및 실행: `docker-compose up -d –build` 명령어를 실행하여 이미지를 다시 만들고 서비스를 올려요.
이 과정에서 빌드 오류가 발생한다면, 백업본에 누락된 파일이 있거나 환경 변수 설정이 잘못되었을 가능성이 높아요. 이 문제를 해결하는 과정 자체가 운영자의 실력을 키워주는 소중한 경험이 될 거예요.
STEP 5. 복구 검증과 운영 문서화
컨테이너가 정상적으로 올라왔다고 해서 모든 과정이 끝난 것은 아니에요. 서비스가 실제 요청을 처리할 수 있는지, 데이터 볼륨이 올바르게 마운트되어 기존 데이터를 읽어오는지 반드시 확인해야 해요. 특히 빌드 옵션이 복구 과정에서 미세하게 틀어지면, 애플리케이션의 특정 기능이 작동하지 않을 수 있으니 철저한 테스트가 필요해요.
마지막으로, 이 모든 과정을 문서로 남겨야 해요. 운영 매뉴얼(Runbook)에는 백업 파일의 위치, 복구 시 사용하는 명령어, 그리고 복구 실패 시 연락할 담당자 정보가 명확히 적혀 있어야 해요. 사고는 예고 없이 찾아오고, 당황한 상태에서는 평소 잘 알던 명령어도 기억나지 않기 때문이에요.
[실제 적용 예시 일정표]
| 구분 | 활동 내용 | 소요 시간 |
|---|---|---|
| 1일차 | 현재 빌드 옵션 및 컨텍스트 전수 조사 | 2시간 |
| 2일차 | 자동화 백업 스크립트 작성 및 테스트 | 4시간 |
| 3일차 | 실제 운영 환경 대상 복구 시뮬레이션 | 3시간 |
| 4일차 | 운영 매뉴얼 업데이트 및 팀 공유 | 1시간 |
자주 하는 실수와 해결법
현장에서 운영하다 보면 의외로 사소한 부분 때문에 복구에 실패하곤 해요. 가장 자주 발생하는 실수들을 정리해 드릴게요.
- ❌ 빌드 컨텍스트 디렉토리만 백업했어요
왜 발생하는가: 컴포즈 파일(`docker-compose.yml`) 자체를 백업 대상에서 빠뜨리는 경우가 많아요.
✅ 해결법: 컴포즈 파일과 `.env` 파일, 그리고 빌드 컨텍스트를 하나의 세트로 묶어서 백업하세요. - ❌ .dockerignore 파일을 무시했어요
왜 발생하는가: 백업 시 용량을 줄이려고 무심코 제외했다가, 나중에 빌드 시 필수적인 파일까지 빠지는 상황이 생겨요.
✅ 해결법: 백업 대상에는 `.dockerignore`를 반드시 포함하고, 실제 압축 시에만 이를 참조하도록 구성하세요. - ❌ 환경 변수(.env)의 위치를 잘못 지정했어요
왜 발생하는가: 복구 후 컴포즈 파일을 실행할 때, `.env` 파일이 예상치 못한 경로에 있으면 빌드 옵션이 기본값으로 돌아가 버려요.
✅ 해결법: 백업본을 풀었을 때의 디렉토리 구조가 기존 운영 환경과 100% 일치하도록 복구 프로세스를 설계하세요. - ❌ 파일 권한(Permission) 문제를 간과했어요
왜 발생하는가: 압축을 풀고 나면 파일의 소유자가 `root`로 바뀌거나 실행 권한이 사라져 빌드가 실패해요.
✅ 해결법: 복구 스크립트 마지막 단계에 `chown`과 `chmod` 명령어를 넣어 권한을 자동 복구하도록 만드세요. - ❌ 백업본이 손상되었는지 확인하지 않았어요
왜 발생하는가: 용량 부족으로 백업 파일이 중간에 끊겼는데도 아무런 경고를 받지 못해 나중에 알게 돼요.
✅ 해결법: 백업 후 반드시 파일의 체크섬(Checksum)을 생성하고, 정기적으로 백업 파일의 무결성을 검증하세요.
자주 묻는 질문
Q. 이미 만들어진 도커 이미지만 있으면 백업이 필요 없지 않나요?
아니요, 그렇지 않아요. 이미지는 결과물일 뿐이에요. 만약 이미지에 포함된 보안 취약점이 발견되어 패치를 해야 하거나, 베이스 이미지를 업데이트해야 할 때, 빌드 컨텍스트와 옵션이 없다면 수정된 이미지를 다시 만들 수 없어요. 즉, 유지보수가 불가능해져요.
Q. 컴포즈 build 옵션 백업과 데이터 볼륨 백업은 별개로 해야 하나요?
네, 반드시 별개로 관리해야 해요. 볼륨 백업은 데이터의 보존이 목적이고, 빌드 옵션 백업은 인프라의 재현이 목적이에요. 두 백업의 주기와 보관 방식은 상황에 따라 다를 수 있으므로 각각의 목적에 맞게 독립적인 전략을 세우는 것이 훨씬 안전해요.
Q. Git에 소스 코드를 올리는데, 별도의 백업이 또 필요한가요?
Git은 소스 코드의 버전 관리 도구이지, 인프라의 전체 상태를 백업하는 도구는 아니에요. `.env` 파일이나 빌드 시 필요한 로컬 설정 파일들은 보안상의 이유로 Git에 올리지 않는 경우가 많죠. 이런 파일들이 유실되면 Git만으로는 복구가 안 되기 때문에, 별도의 백업 절차가 꼭 필요해요.
Q. 백업 파일을 어디에 보관하는 것이 가장 좋을까요?
가장 추천하는 방식은 3-2-1 백업 원칙을 따르는 것이에요. 최소 3개의 복사본을 유지하고, 2가지 이상의 매체를 사용하며, 그중 1개는 반드시 물리적으로 떨어진 원격지(클라우드 등)에 보관하세요.
Q. 복구 테스트는 얼마나 자주 해야 하나요?
최소 분기에 한 번은 전체 복구 시뮬레이션을 해보는 것을 권장해요. 서비스의 중요도가 높다면 매달 수행하는 것이 가장 이상적이에요.
안정적인 운영을 위한 마지막 점검
지금까지 컴포즈 build 옵션 백업의 중요성부터 실제적인 실행 방법까지 자세히 살펴보았어요. 컨테이너 환경은 매우 유연하지만, 그만큼 설정 하나가 어긋났을 때 발생하는 리스크도 크답니다. 오늘 배운 내용을 바탕으로 여러분의 서비스가 어떤 상황에서도 즉시 일어설 수 있는 회복 탄력성을 갖추기를 바라요.
- 빌드 컨텍스트는 소스 코드뿐만 아니라 Dockerfile과 설정 파일 전체를 포함해야 해요.
- 컴포즈 파일과 .env 파일은 빌드의 설계도이므로 반드시 세트로 백업하세요.
- 백업은 수동이 아닌 스크립트를 통한 자동화가 원칙이에요.
- 백업 성공 여부를 알리는 모니터링 체계를 반드시 구축하세요.
- 백업본이 있다고 안심하지 말고, 정기적으로 복구 테스트를 수행하세요.
- 모든 절차는 누구나 따라 할 수 있도록 문서로 남겨두어야 해요.
복구는 머리로 아는 것과 실제로 해보는 것이 완전히 달라요. 이론만으로는 실제 장애 상황의 긴박함을 이겨내기 어렵습니다. 복구는 실제로 한 번 해봐야 믿을 수 있습니다. 오늘 바로 작은 테스트 환경에서라도 백업본을 이용한 복구 연습을 예약해 보세요. 작은 실천이 거대한 장애로부터 여러분의 서비스를 지켜줄 거예요.
다음 단계로 넘어가고 싶다면, 컨테이너 운영의 기초를 다질 수 있는 아래 글을 먼저 읽어보시는 것을 추천드려요.
관련 글: 도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드