배포가 끝났다는 말을 나눠서 사용한다

win-j.com과 별도 Django 프로젝트를 운영하면서 마이그레이션 누락, 정적 파일 경로, 리디렉션과 링크 문제를 겪었다. 초기 글에서는 배포 후 확인할 항목과 서버를 바꾸는 명령을 한 목록에 섞었다. 지금은 먼저 상태를 읽고, 원인을 좁힌 다음 필요한 변경을 적용하는 순서로 구분한다.

특히 이 사이트에서는 Git push로 코드가 배포되어도 DB에 저장된 게시글 본문이 자동으로 교체되지는 않는다. 코드 배포, DB 반영, 공개 응답, 사용자 화면 확인을 각각 완료해야 해당 수정이 반영됐다고 기록할 수 있다.

배포 후 확인하는 열두 항목

순서 확인 항목 남길 증거와 실패 시 다음 확인
1 배포 버전·설정 실행 중인 코드 버전과 DEBUG 여부. 비밀 값은 출력하지 않음
2 컨테이너 실행·재시작 상태와 시간. 실행 중이어도 기능 정상과 구별
3 DB·migration 적용 목록과 누락 파일. 오류 로그의 테이블·필드 확인
4 정적 파일 깨진 CSS·JS의 실제 URL, 상태 코드, 응답 형식
5 업로드 파일 기존 이미지·다운로드가 유지되는지, 파일 저장 경로
6 HTTPS·대표 주소 HTTP/HTTPS, www 유무별 도착 주소와 반복 리디렉션
7 공개·비공개 로그아웃 상세 응답, 초안·비공개 내용 노출 여부
8 검색 안내 robots·sitemap·canonical·noindex의 일관성
9 링크·404 변경한 주소와 본문 링크. 사라진 글은 실제 상태 코드 확인
10 로그·재현 발생 시각·URL·입력 단계·오류 종류, 민감정보 제거
11 백업·복구 DB·media·설정의 보관 위치와 별도 환경 복원 확인
12 화면·사용 흐름 좁은 폭의 표·코드·버튼, 소개·정책·문의 동선

한 번의 배포에 모든 항목을 같은 깊이로 실행할 필요는 없지만, 영향을 받는 항목은 생략하지 않는다. 본문만 바꿨다면 제목·요약·본문·링크와 좁은 화면을, 계산 로직을 바꿨다면 정상 입력·잘못된 입력·경계값·다운로드 결과를 추가한다.

먼저 읽는 명령

아래 Docker 명령은 컨테이너 목록과 제한된 로그를 읽는다. myapp_web은 이 사이트에서 사용한 컨테이너 이름이므로 다른 프로젝트에서는 해당 이름으로 바꾼다.

docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
docker logs --tail 100 myapp_web
docker exec myapp_web python /app/src/manage.py check --deploy
docker exec myapp_web python /app/src/manage.py showmigrations --plan

check --deploy는 현재 프로세스가 읽은 설정에 대한 점검이다. 다른 설정 모듈로 실행했다면 운영 설정을 검사한 것이 아니다. 경고가 없다고 배포 전체가 검증된 것도 아니다. Django 배포 체크리스트

migrate, collectstatic, 재시작은 상태를 바꾸는 명령이므로 자동으로 한꺼번에 실행할 점검 목록에서 분리한다. 특히 운영에서 즉석으로 makemigrations를 실행해 누락을 덮기보다 검토한 migration 파일이 배포에 포함됐는지 먼저 확인한다. createsuperuser도 배포 때마다 실행할 정상 확인 명령이 아니다.

내가 겪은 사례에서 일반화하지 않을 부분

별도 프로젝트에서는 관리자 권한을 추가할 때 500 오류가 났고 migration 파일 누락을 찾아 수정했다. 다른 배포에서는 CSS가 깨져 정적 파일 수집과 제공 경로를 확인했다. 이는 당시의 원인이며, 모든 관리자 500이나 CSS 오류의 원인을 같은 것으로 단정할 수는 없다.

초기 운영 기록에는 ads.txt 접근 문제를 조사하면서 307 리디렉션과 Nginx 설정을 확인한 경험도 있다. 하지만 ‘307이면 크롤러가 읽지 못한다’는 일반 규칙으로 쓰지 않는다. 현재 요청의 리디렉션 목적지와 최종 본문을 확인해야 한다. URL 이름을 바꿨던 경험도 있어, 기존 글의 주소를 바꾸는 작업은 링크·리디렉션·사이트맵 영향까지 함께 검토한다.

백업 파일 생성과 복원 가능성은 다르다

본문 일괄 수정에서는 변경 전 데이터를 새 백업 파일로 저장하고 컨테이너 밖의 지속 보관 위치로 복사한다. 이 파일은 해당 글의 복구 자료이며 전체 PostgreSQL, 업로드 media, 운영 설정의 백업을 대신하지 않는다. 같은 NAS 장치 안에만 보관한 복사본은 장치 전체 장애에 대한 별도 사본도 아니다.

복구 절차는 운영 DB를 덮어쓰는 연습으로 확인하지 않는다. 별도 환경에 복원해 글·관계·파일 경로가 맞는지 확인하고 시각과 범위를 남긴다. 백업 파일이 있다는 사실만 확인했다면 ‘백업 생성 확인’, 복원까지 했다면 ‘별도 환경 복원 확인’으로 기록을 나눈다.

기록을 다음 배포에 재사용하기

배포 기록에는 대상 버전, DB 변경 여부, 확인한 URL, 입력과 기대 결과, 실제 결과, 남은 문제를 남긴다. 화면 확인은 폭·브라우저를 적고, 자동 검증과 사용자의 수동 확인을 구별한다. 외형상 정상인 한 화면으로 모든 기능을 완료 처리하지 않는다.

검색 관련 실패는 robots.txt 점검과 사이트맵 조건으로, 승인 준비는 애드센스 신청 후 점검 기록으로 나눠 조사한다. 계정의 검색·심사 결과는 공개 응답이나 로컬 테스트와 별도의 증거로 관리한다.