DLP 고도화를 마치며 당직자용 운영 가이드를 받았는데 그대로 따라 움직일 수 있게 쓰여 있었다. 어떻게 만들었는지가 아니라 어떻게 만지는지만 적혀 있는 점이 좋았는데 실시간 토론 서버의 배포 절차에서 걸리는 것이 있었다.
이 서버는 Node.js 로 짠 Socket.io 프로세스라 pm2 로 띄운다. 배포 산출물은 npm run build 가 만드는 tar 하나다.
Table of contents
Open Table of contents
배경 — 당직자를 위한 가이드
산출물 이름이 dlp-realtime-dev.tar.gz 로, 개발 중임을 나타내는 -dev 표시가 그대로 붙어 있었다. 그 표시가 붙은 산출물은 같은 이름으로 계속 새것이 덮인다.
그러면 지금 서버에서 도는 것이 어느 시점의 빌드인지를 파일 이름으로는 알 수 없다. 언제 만든 것인지도 ls -l 이 보여 주는 파일 날짜 말고는 근거가 없다.
증상 — 같은 이름으로 덮이는 산출물
더 큰 문제는 되돌릴 방법이 없다는 것이었다. 이전 판이 같은 이름으로 덮여서 사라졌으므로 돌아갈 대상 자체가 없다.
문제가 났을 때 할 수 있는 것이 이전 커밋으로 다시 빌드하는 것뿐인데 그것은 npm install 까지 포함하면 몇 분이 아니라 몇십 분이 걸린다. 되돌리기가 필요한 상황은 대개 그럴 여유가 없는 상황이다.
조치 — 되돌리기가 링크 교체가 된다
두 가지 방법이 있었다. 올리기 전에 이전 판을 dlp-realtime-dev.tar.gz.bak 으로 옮겨 두는 것과, 산출물에 시각을 붙여 이름이 겹치지 않게 하고 현재 판을 가리키는 링크를 따로 두는 것이다. 뒤쪽을 골랐다. 이유는 .bak 하나로는 한 판 전까지만 갈 수 있어서다.
이제 산출물은 dlp-realtime-20191219-1432.tar.gz 로 이름이 붙고 releases/20191219-1432/ 에 풀린다. current 는 그 폴더를 가리키는 심볼릭 링크이고, 배포는 새 폴더를 풀고 ln -sfn releases/20191219-1432 current 로 링크를 옮긴 뒤 pm2 reload dlp-realtime 하는 것이 된다. -n 이 필요한 것은 coreutils ln 매뉴얼에 적힌 대로, 링크 이름이 이미 디렉터리를 가리키는 링크이면 그 안에 새 링크를 만들지 않고 링크 자체를 갈아 끼우게 하기 위해서다.
이렇게 하면 되돌리는 것이 링크를 이전 폴더로 다시 옮기는 일이 된다. 몇 초면 끝나고 이전 판들이 그대로 남아 있으므로 어느 시점으로도 갈 수 있다.
배포 기록이 없고 로그는 안 잘린다
배포를 WinSCP 로 하고 있어서 언제 무엇이 올라갔는지가 아무 데도 안 남았다. 최소한 언제 누가 어느 판을 올렸는지 releases/DEPLOY.log 에 한 줄이라도 남기게 했다.
pm2 가 프로세스 출력을 ~/.pm2/logs/ 아래 파일 하나에 계속 쌓고 있는 것도 걸렸다. pm2 공식 문서를 보면 회전은 pm2-logrotate 모듈이 따로 맡는다고 되어 있고, 그 모듈이 안 깔려 있으니 디스크가 차야 알게 된다. 모듈을 깔고 가이드에 pm2 flush 로 비우는 자리도 적어 두게 했다.
주의 — 가이드에 적으면 안 되는 것
가이드에 설정 파일의 암호화된 DB 비밀번호를 푸는 명령이 적혀 있는 부분이 있었다. 당직자가 급할 때 그 명령을 쓰라는 뜻이었을 텐데 그 자리에 그것이 있으면 안 됐다.
대신 그 자리에 필요한 값을 정상 경로로 얻는 방법, 즉 누구에게 요청하는지를 적었다. 마지막으로 Node.js·Redis·PostgreSQL 판을 손으로 옮겨 적은 표에서 오기를 하나 찾았는데 그런 표는 package.json 과 node -v 출력에서 뽑는 것이 맞았다.
정리
- 개발 표시가 붙은 산출물은 같은 이름으로 계속 덮인다
- 지금 도는 것이 어느 빌드인지 알 수 없다
- 덮인 이전 판이 없으니 되돌릴 대상이 없다
- 시각을 붙이고
current링크로 현재를 가리킨다 - 되돌리기가
ln -sfn한 번이 된다 - 전송 도구로 배포하면 기록이 없으니 한 줄이라도 남긴다
pm2로그는 모듈 없이는 안 잘리므로 디스크가 찰 때 알게 된다- 가이드에 보안을 푸는 명령 대신 정상 경로를 적는다