Ch 05. 장애 대응 체크리스트
배포하면 이상한 일이 생깁니다. 로컬에서는 잘 됐는데 서버에서 안 된다, 어제까지 됐는데 오늘 갑자기 안 된다. 당황하지 않는 것이 먼저입니다. 순서대로 확인하면 대부분 원인을 찾을 수 있습니다.
사이트 접속 불가 시 진단 순서
1단계: 컨테이너 상태 확인
# 컨테이너가 실행 중인지 확인ssh ibetter "docker compose ps"# 예상 출력# NAME STATUS PORTS# my-blog-app Up 0.0.0.0:3000->3000/tcp# my-blog-db Up 5432/tcp```text컨테이너가 `Exited` 상태라면 재시작합니다.```bashssh server "cd /app && docker compose up -d"```text#### 2단계: 로그 확인```bash# 최근 100줄 로그 확인ssh server "docker logs my-blog-app --tail 100"# 실시간 로그 스트리밍ssh server "docker logs my-blog-app -f"```text에러 메시지를 찾습니다. 일반적인 에러들입니다.
데이터베이스 연결 실패
Error: Can't reach database server at 'db:5432'
환경변수 누락
Error: Environment variable not found: AUTH_SECRET
포트 충돌
Error: address already in use
#### 3단계: next_cache 볼륨 삭제캐시 볼륨이 이전 빌드와 충돌할 수 있습니다.```bashssh server "cd /app && \ docker compose down && \ docker volume rm app_next_cache && \ docker compose up -d"```text볼륨 이름은 `docker-compose.yml`의 프로젝트명과 볼륨명의 조합입니다. `docker volume ls`로 확인합니다.#### 4단계: --no-cache 강제 재빌드`Dockerfile`이나 `package.json`을 변경했다면, 캐시를 무시하고 완전히 다시 빌드해야 합니다.```bashssh server "cd /app && \ docker compose build --no-cache app && \ docker compose up -d app"```text이미지 크기가 크면 시간이 걸립니다. 로그를 모니터링합니다.### 데이터베이스 연결 실패 처리```bash# DB 컨테이너 상태 확인ssh server "docker compose ps db"# DB 로그 확인ssh server "docker logs my-blog-db --tail 50"# DB 직접 접속 테스트ssh server "docker compose exec db psql -U blogs -d myblog -c 'SELECT 1'"```textDB가 실행 중인데 앱이 연결 못 한다면 환경변수의 `DATABASE_URL`을 확인합니다. 컨테이너 내부에서 DB는 `localhost`가 아닌 서비스 이름(`db`)으로 접근해야 합니다.```bash# 잘못된 DATABASE_URLDATABASE_URL="postgresql://user:pass@localhost:5432/myblog"# 올바른 DATABASE_URL (docker-compose 내부 통신)DATABASE_URL="postgresql://user:pass@db:5432/myblog"```text### 롤백 절차배포 후 문제가 발생했을 때 이전 버전으로 돌아가는 방법입니다.```bash# 이전 커밋으로 코드 되돌리기ssh server "cd /app && git log --oneline -5"# 커밋 해시 확인ssh server "cd /app && \ git checkout {이전_커밋_해시} && \ docker compose build --no-cache app && \ docker compose up -d app"```text또는 이전 Docker 이미지를 저장해두었다면 그것을 사용합니다.```bash# 이미지 태그 목록 확인ssh server "docker images my-blog-app"# 특정 버전의 이미지로 롤백ssh server "docker compose down && \ docker tag my-blog-app:previous my-blog-app:latest && \ docker compose up -d"```text### 장애 예방 — 배포 전 체크리스트배포하기 전에 확인하는 습관을 들이면 장애를 줄일 수 있습니다.```text배포 전 체크리스트:[ ] npm run build가 로컬에서 성공하는가?[ ] 환경변수가 프로덕션에 모두 설정되어 있는가?[ ] 데이터베이스 마이그레이션이 필요한가? - 필요하다면 배포 전 먼저 적용한다[ ] Dockerfile 또는 package.json을 변경했는가? - 변경했다면 --no-cache 재빌드가 필요하다[ ] 변경 사항이 로컬에서 예상대로 동작하는가?
자주 발생하는 장애와 해결 요약
| 증상 | 가능한 원인 | 해결 방법 |
|---|---|---|
| 컨테이너가 계속 재시작 | 환경변수 누락, 포트 충돌 | 로그 확인, 환경변수 점검 |
| 페이지 응답 없음 (hang) | standalone 빌드 + 볼륨 마운트 충돌 | standalone 제거, next start 모드 사용 |
| 정적 파일 403 에러 | 파일 권한 문제 | chown -R nextjs:nodejs /app |
| DB 연결 실패 | DATABASE_URL 잘못됨 | db 호스트명 사용 확인 |
| 빌드 후 캐시 충돌 | next_cache 볼륨 | docker volume rm 후 재시작 |
| API 타임아웃 | Vercel 무료 플랜 10초 제한 | 쿼리 최적화 또는 Pro 플랜 |
장애는 피할 수 없지만, 빠르게 대응하는 능력을 키울 수 있습니다. 매번 장애를 겪을 때마다 원인과 해결 방법을 기록해두면 다음에는 훨씬 빠르게 해결할 수 있습니다.
다음 PART에서는 이 긴 여정을 마무리하며 앞으로의 방향을 이야기합니다.