배포 스크립트를 하나로 합친 날


처음엔 집 데스크탑 한 대에서만 배포했어요. 편했죠. 스크립트 하나 돌리면 끝이었으니까요.

그런데 프로젝트가 6개를 넘어가고, 노트북을 들고 나와서도 작업하게 되면서 이 간단한 구조가 조금씩 무너지기 시작했어요.

scp가 자기 자신한테 쏘면

처음 배포 스크립트는 scp로 이미지를 서버에 전송해서 실행하는 구조였어요. 로컬 머신에서만 배포할 땐 문제가 없었는데, 어느 날 실제 서버에 직접 들어가서 작업하다 배포해보니 바로 에러가 나더라고요. 자기 자신한테 scp를 쏘는 꼴이 되어버려서요.

그래서 원격용, 로컬용으로 스크립트를 나눴어요. 그런데 이번엔 Claude Code가 헷갈려 했어요. 지금 환경이 로컬인지 원격인지 제대로 판단하지 못하고 엉뚱한 쪽을 실행하려 들더라고요.

“이럴 거면 하나로 합쳐서 스크립트가 알아서 판단하게 하자” 싶었어요.

각자 살던 스크립트들

합치려고 보니까, 프로젝트마다 스크립트 모양이 제각각이더라고요.

body-log는 배포 끝에 Cloudflare 캐시 퍼지까지 직접 호출하고 있었어요. 코드를 새로 올렸는데 캐시된 파일이 계속 응답으로 오길래, 아예 스크립트에 넣어버렸거든요.

pet-walking은 도커 이미지를 gzip으로 압축해서 전송했고, passport-ping은 환경변수를 --build-arg로 Dockerfile 빌드 시점에 박아뒀어요. 각자 그때그때 필요해서 붙인 것들이죠.

4월 9일, 이 김에 싹 다

그날 다른 기능 작업을 하고 있다가, 배포 스크립트 쪽을 건드리게 됐어요. 어차피 건드리는 김에 나머지도 싹 다 하자 싶어서 하루에 6개를 몰아서 통합했어요.

통합된 deploy.sh는 단순해요. 실행 중인 OS를 보고 자동으로 분기해요.

if grep -qi ubuntu /etc/os-release 2>/dev/null; then
  deploy_local
else
  deploy_remote
fi

빌드 스크립트(docker-build.sh)도 없앴어요. 어차피 빌드는 항상 배포 직전에만 했거든요. 굳이 나눠놓을 이유가 없더라고요.

남은 것

이제 데스크탑이든 노트북이든, 집이든 밖이든 ./deploy.sh 하나만 치면 돼요. 스크립트가 알아서 지금 어디서 실행되고 있는지 판단하고 맞는 방식으로 배포해요. Claude Code한테 시켜도 더 이상 어느 걸 써야 할지 헷갈려하지 않고요.

별거 아닌 변화인데, 막상 써보니 묘하게 마음이 가벼워졌어요. 배포할 때마다 “이 프로젝트는 어떻게 돌렸더라” 하고 잠깐 멈칫하던 게 사라졌거든요.