#화면을 고쳤는데 어느 코드가 돌고 있었나
개발은 Mac에서 하고 계속 도는 일은 Ubuntu로 옮겼다. 이후 웹 화면을 확인하는 서버도 작업별로 Ubuntu에 띄우기 시작했다. Mac의 작업 공간을 나누는 것만으로는 어떤 코드가 서버에서 실행되는지 설명하기 어려웠다.
화면이 예상과 다르면 먼저 구분해야 할 것이 있었다. 수정이 잘못된 것인지, 수정한 파일이 아직 전송되지 않은 것인지, 브라우저가 다른 작업의 주소를 보고 있는 것인지였다.
작업마다 주소와 소유자, 전송할 소스 묶음을 기록했다. 실행 단위는 Next.js 컨테이너와 Docker Compose 프로젝트로 나누고, Traefik의 Host(...) 규칙이 각 작업 주소를 해당 컨테이너로 보내도록 했다. Mac과 Ubuntu 사이의 접근은 기존 Tailscale 연결을 사용했다. 기존 서비스의 주소나 서버를 바꾸지 않고 새 작업의 실행본을 구분하는 방식이었다.
Compose 프로젝트 이름은 컨테이너 같은 자원을 묶어 구별하는 데 쓰인다. Traefik의 Host 규칙은 들어온 요청을 어느 실행본으로 보낼지 정한다. 소스가 무엇인지 증명하는 일은 둘의 기능만으로 해결되지 않아 별도 manifest를 뒀다.
#전송부터 따로 검증했다
10월 25일에는 새 폴더로 소스를 보내는 단계만 시험했다. 기존 서버를 다시 띄우거나 DB를 바꾸는 시험은 아니었다.
정한 기준 커밋의 추적 코드와 이번 전송 수정만 소스에 넣었다. 다른 작업의 미추적 파일은 포함하지 않았다. 대상 부모 폴더의 소유자와 권한, 새 목적지의 존재 여부를 먼저 확인하고 전송했다.
소스 묶음은 tar로 전송했다. 준비 단계에서 파일마다 상대 경로·SHA-256·권한을 기록하고, 그 목록을 직렬화한 값의 SHA-256을 sourceId로 삼았다. 기준 커밋은 출발점을 나타내고 sourceId는 전송에 포함한 수정까지 식별한다. 둘은 용도가 달랐다.
manifest 항목의 실제 필드만 남긴 설명용 예다. 해시와 파일명은 예시이며 이번 전송의 원본값은 아니다.
{"file":"src/example.ts","sha256":"<파일 SHA-256>","mode":420}
mode의 420은 8진수 0644다. 수신 쪽은 각 파일의 내용과 권한을 목록과 대조하고, 목록 밖 파일·누락·심볼릭 링크도 거부했다. 전송 중 내용이 바뀌었는데 파일 개수만 맞는 경우를 놓치지 않기 위해서였다.
전송 뒤에는 보내는 도구의 검사에 더해 별도 읽기 전용 검사로 결과를 대조했다. 소스 6,119개의 SHA-256과 권한, 메타데이터 파일 3개의 해시가 일치했다. 누락되거나 추가된 파일은 없었다.
파일 개수만 같다고 같은 소스라고 할 수는 없다. 이름이 같은 파일의 내용이 달라질 수 있고, 실행에 필요한 권한이 달라질 수도 있다. 그래서 파일 내용과 권한을 함께 확인했다.
#다른 서버는 그대로 두었다
같은 Ubuntu에 이미 실행 중인 작업들이 있었다. 전송 전후로 기존 컨테이너 67개의 ID와 이름, 시작 시각을 대조했다. 기존 부모 폴더의 소유자·권한과 서비스 환경 파일의 메타데이터도 그대로였다.
이 확인에서 env 내용이나 DB 데이터는 읽지 않았다. 새 실행 설정이 생기지 않았는지도 확인했다. 전송 성공을 앱의 동작 성공으로 적지 않기 위해서였다.
파일을 잘 보냈다면 다음 단계에서 서버를 띄워야 하고, 서버가 뜨면 그 주소에서 화면과 필요한 동작을 봐야 한다. 10월 25일 시험은 그중 전송까지였다. 별도의 블로그 작업에서는 이 방식의 실행본으로 production 빌드와 실제 화면을 확인했다. 서로 다른 작업의 결과를 하나의 시험처럼 합치지 않았다.
#컨테이너 밖에는 공유하는 것이 남았다
웹 실행본을 분리해도 DB와 계정, 저장소까지 자동으로 분리되지는 않았다. 두 작업이 다른 주소를 사용하면서 같은 개발 데이터를 읽고 쓸 수 있었다.
작업 주소·소유자·소스 식별자·데이터 사용 범위를 실행 계획에 함께 남겼다. 컨테이너에도 같은 소스 식별자를 라벨로 달아 계획과 실행본을 대조했다. 어떤 DB에 연결되는지, 작업이 만든 데이터는 무엇인지 알아야 실행본을 정리할 때 다른 작업의 자료를 건드리지 않을 수 있다.
모든 서비스에 같은 검증을 끝낸 상태는 아니다. 파일을 보내는 공통 경로가 검증됐어도 인증이나 기능 확인은 서비스마다 남는다. 이번에 확보한 것은 소스 전송의 무결성과 선택한 서비스의 실행 기록이다.
이제 화면 결과를 볼 때 주소만 받지 않고 어느 소스가 그 주소에서 실행됐는지도 함께 확인한다. 변경한 코드가 실제 화면에 도달했는지 설명할 근거가 하나 늘었다.