3편. Docker 볼륨, PostgreSQL 백업과 복구 실습
컨테이너를 재생성한 뒤 데이터가 남는지 확인하고, 백업 파일을 만들어 별도 데이터베이스에 복원합니다. 운영을 시작하기 전에 꼭 연습해야 할 절차입니다.
1. 데이터 영속성 확인
Docker 볼륨은 컨테이너와 데이터 파일의 수명을 분리합니다. 먼저 보존 여부를 확인할 데이터를 등록합니다.
Set-Location D:\Dev\DockerCourse\TaskApi
$t=Invoke-RestMethod -Uri http://localhost:5080/api/tasks -Method Post -ContentType application/json -Body (@{title='볼륨 영속성 확인'} | ConvertTo-Json -Compress)
docker compose exec db psql -U taskuser -d taskdb -c 'SELECT "Id","Title" FROM tasks ORDER BY "Id";'Compose 서비스를 내렸다가 다시 올립니다.
docker compose down
docker compose up -d
docker compose exec db pg_isready -U taskuser -d taskdb
docker compose exec db psql -U taskuser -d taskdb -c 'SELECT "Id","Title" FROM tasks ORDER BY "Id";'docker compose down -v를 실행하지 않습니다. -v는 Compose가 관리하는 명명된 볼륨을 삭제할 수 있습니다. 볼륨은 컨테이너 재생성에는 데이터를 보존하지만, 서버 장애나 볼륨 손실에 대비하려면 별도 백업이 필요합니다.2. PostgreSQL 백업 만들기
pg_dump -Fc는 pg_restore로 복구할 수 있는 커스텀 아카이브를 만듭니다. 컨테이너 안에 백업한 뒤 Windows의 backups 폴더로 복사합니다.
New-Item -ItemType Directory -Force .\backups | Out-Null
$db=(docker compose ps -q db).Trim()
docker compose exec -T db pg_dump -U taskuser -d taskdb -Fc -f /tmp/taskdb.dump
$file=Join-Path (Get-Location) ("backups\taskdb-{0}.dump" -f (Get-Date -Format yyyyMMdd-HHmmss))
docker cp "${db}:/tmp/taskdb.dump" "$file"
Get-Item $file | Select-Object FullName,Length,LastWriteTime파일 크기가 0보다 큰지 확인하고, 백업은 Git 저장소와 분리된 안전한 위치에도 보관합니다.
3. 별도 DB로 복원하기
원본 taskdb를 덮어쓰지 않고 새 데이터베이스 taskdb_restore로 복구합니다. 대상 이름이 이미 존재한다면 삭제하지 말고 다른 이름을 정해 아래 명령 전체에서 동일하게 사용하세요.
docker compose exec db createdb -U taskuser taskdb_restore
docker cp "$file" "${db}:/tmp/taskdb-restore.dump"
docker compose exec -T db pg_restore --verbose --no-owner --no-privileges -U taskuser -d taskdb_restore /tmp/taskdb-restore.dump복원이 끝나면 원본과 복원본의 행 수를 비교합니다.
docker compose exec db psql -U taskuser -d taskdb -c 'SELECT COUNT(*) AS source_count FROM tasks;'
docker compose exec db psql -U taskuser -d taskdb_restore -c 'SELECT COUNT(*) AS restored_count FROM tasks;'
docker compose exec db psql -U taskuser -d taskdb_restore -c 'SELECT "Id","Title","IsCompleted" FROM tasks ORDER BY "Id";'행 수뿐 아니라 제목과 완료 여부도 원본과 일치하는지 확인합니다. 백업 파일을 만들었다는 메시지만으로 복구가 보장되는 것은 아니므로, 별도 DB 복원까지 성공해야 검증이 끝납니다.
4. 자주 발생하는 오류
| 증상 | 확인·해결 |
|---|---|
| Docker Server를 찾을 수 없음 | Docker Desktop 실행 후 docker version 재확인 |
| 8080에서 Nginx 페이지가 표시됨 | API 테스트 주소를 http://localhost:5080으로 사용 |
| Linux 빌드에서 Windows NuGet 경로 오류 | .dockerignore에서 bin과 obj 제외 후 docker compose build --no-cache api |
| DB 연결 실패 | 컨테이너 간 연결은 db:5432, Windows 마이그레이션은 localhost:5433 |
| 복원 DB가 이미 존재함 | 기존 DB를 삭제하지 말고 새로운 복원 DB 이름을 사용 |
공식 문서
마무리: 이 시리즈에서는 Docker 설치부터 .NET API 빌드, PostgreSQL CRUD, 데이터 영속성, 백업과 복원까지 다뤘습니다. 다음 과정은 이미지를 GHCR에 올리고 AWS EC2 Ubuntu에 배포하는 단계입니다. 운영 서버에서는 DB 포트를 공개하지 말고, 비밀 정보 관리와 HTTPS, 외부 백업 보관까지 별도로 구성하세요.
댓글
댓글 쓰기