가난뱅이의 버전관리 서버 운영
개인용 버전 관리에 사용하는 퍼포스는 예상보다 비싸 비용을 절약하기 위해 꼼수가 필요해졌습니다. 꼼수 없이 사용하기에 지금은 너무 가난합니다.
이전에는 온라인에서 여러 역할을 처리해 주고 있는 장난감 서버 비용을 크게 걱정하지 않았습니다. 이 서버는 돌고 돌아 퍼포스에서 소개한 forgejo라는 개인 깃 서버를 구동하기도 하고 또 자동화 도구 n8n 사용기에서 소개한 n8n이라는 자동화 도구를 구동하고 있기도 합니다. 그 외에도 모니터링 소프트웨어인 uptime kuma를 돌리기도 하고 오픈서치로 시작한 임시변통 로그 집계 환경에 사용한 MariaDB 데이터베이스를 돌리고 있습니다. 하지만 이들 모두를 합쳐도 AWS Lightsail의 램 2기가, 스토리지 60기가짜리 서버로도 훌륭하게 구동되었으며 비용은 월 10달러에 불과합니다. 게다가 이 비용에는 네트워크 전송 비용이 포함되어 있어 정말 딱 10달러만 내면 이 모든 서비스를 편안하게 구동할 수 있었습니다.
하지만 최근 돌고 돌아 퍼포스에서 아무래도 제 개인적인 버전 관리 용도에는 깃이 어울리지 않으며 깃을 아무리 개인 서버에 설치해 여러 가지 제한을 없앤 다음 사용한다 하더라도 깃은 큼직한 바이너리 파일의 안정적인 버전 관리를 원하는 제 요구사항에 별로 적합하지 않았습니다. 회사에서는 이미 결정되었으니 어쩔 수 없이 언리얼 프로젝트에 깃을 사용하고는 있지만 커다란 바이너리 파일을 커밋하며 온갖 이상한 문제를 겪고 있습니다. 이 상황에서 화가 나는 지점은 바이너리 파일을 커밋하는 사람들은 주로 엔지니어가 아니기 때문에 트러블슈팅 상황은 비 엔지니어들에게 일어나 불편을 겪지만 정작 엔지니어들은 대부분 코드를 커밋하고 빌드를 돌린 결과물인 바이너리는 CI 서버가 커밋하므로 이들은 트러블슈팅 상황을 거의 겪지 않는다는 점입니다. 하지만 이들은 형상관리도구를 결정할 권한을 가지고 있어 언리얼 개발에 깃을 선택했고 비 엔지니어 직군에 일어나는 온갖 트러블슈팅 상황에 대처할 뿐 근본적인 문제에는 관심을 가지지 않는 것 같아 보입니다.
한동안은 그래도 전 세계에서 가장 널리 사용되는 형상관리도구이니 개인적인 버전 관리에도 의미 있을 거라고 생각해 이를 사용해 봤지만 심지어 깃은 한 명이 바이너리 파일을 커밋하는 상황 조차 똑바로 커버하지 못합니다. 게임 스크린샷 몇 장을 포함한 파워포인트 파일이나 비지오 파일은 순식간에 몇 십 메가에 달하는데 제 관점에서는 그냥 이미지 하나 넣고 다이어그램 좀 그려 만든 비지오 파일의 새 버전을 커밋하다가 온갖 에러 메시지를 뿜어내며 푸시에 실패하는 동작은 아무리 깃이 세계적으로 가장 널리 사용되건 말건 이건 결함 소프트웨어에 불과합니다.
깃헙이나 빗버킷에서 깃을 사용하다가 여러 이상한 동작을 유발하는 것으로 알려진 깃의 30년 전에 만들어진 제약을 수정하면 좀 잘 돌아갈까 해서 앞에 소개한 장난감 서버에 forgejo를 사용해 개인 깃 서버를 돌리고 여러 설정을 바꿔 봤지만 큰 개선은 없었습니다. 커다란 바이너리를 어떻게 푸시하는데 성공하기는 했지만 나중에 다른 기계에서 리파지토리를 풀 받으려니 또 다시 온갖 이상한 문제가 일어났고 결국 새 기계에는 기존에 리파지토리를 받아 둔 기계에서 리파지토리 전체를 복사해 새 기계에 옮긴 다음 거기서 풀을 받아야 했습니다. 이쯤 되니 깃을 욕하면서 깃을 사용해 보려고 고통 받는 저 자신이 고통을 즐기고 있는 것이 아닌가 싶은 생각이 들 정도입니다.
드라마 하우스 오브 카드 도입부에서 주인공 프랭크는 시청자들에게 고통에는 두 가지 종류가 있고 이들 중 하나는 의미 있지만 다른 하나는 아무런 의미가 없는 그냥 고통일 뿐이라고, 이는 빨리 끝내는 편이 낫다고 말합니다. 회사에서의 깃 사용은 제 권한으로 어쩔 수 없으며 언리얼 개발에 깃을 형상관리도구로 사용한 경험은 여러 트러블슈팅을 겪으며 이 고통이 단지 제가 이 형상관리도구의 깊은 곳을 제대로 이해하지 못해 겪는 것이 아니라 근본적으로 이 도구가 바이너리 파일이 득실대며 개발에 사용하는 미들웨어 역시 바이너리 파일을 만들어내는 상황에 어울리지 않기 때문이라는 결론에 도달하게 만들었습니다. 이는 여전히 고통이지만 적어도 “앞으로 언리얼 프로젝트에 깃 쓰자고 하는 놈은 내가 직접 목을 도려낼 것”이라는 굳은 선언을 하게 만들었으며 앞으로 프로젝트 초반의 의사결정에 큰 역할을 하게 될 겁니다. 그러니 회사에서 깃을 사용하며 겪은 고통은 아무 의미가 없다고는 볼 수 없을 겁니다. 하지만 개인적인 버전 관리에 깃을 사용하며 겪는 고통은 그렇지 않습니다. 이는 아무런 의미도 없으며 빨리 끝내는 편이 낫습니다. 가끔 너무나도 어처구니 없는 동작에 화를 내며 타임라인에 깃에 대한 깊은 분노로부터 나온 진한 욕설을 뿜어내 깃 사용자들을 불편하게 할 필요도 없습니다.
그래서 돌고 돌아 퍼포스에 설명한 대로 전통의 강자 퍼포스로 돌아왔습니다. 사실 개인 파일 버전관리에 SVN을 사용할까 잠깐 고민했지만 과거의 사용 경험 상 SVN은 종종 아주 오래된 리비전으로 되돌려 보면 종종 파일이 손상되어 있어 리비전을 되돌릴 수 없을 때가 있었습니다. 과거에 사용한 SVN은 서버에서 한 리비전에 올린 모든 파일을 커다란 파일 하나로 묶어 저장했는데 종종 많은 파일을 한 커밋을 통해 올리면 아주 커다란 파일을 만들며 파일시스템과 문제를 일으키기도 하고 또 그렇게 큰 파일 하나로 리비전 하나를 관리하는 모양도 썩 마음에 들지는 않았습니다. 이런 사용 경험은 이제 오래 전 일이라 이 정도 문제는 해결했을 것도 같지만 과거에도 안정적으로 동작한 솔루션을 알고 있는 마당에 또 다른 모험을 할 필요는 없을 것 같았습니다. 그렇게 AWS Lightsail에 두 번째 인스턴스를 만들어 퍼포스를 돌리기 시작합니다.
퍼포스마저 기존 장난감 서버에 함께 돌리지 않기로 한 이유는 퍼포스는 개인 파일 버전 관리에 사용하고 또 중장기적으로는 30일 이전의 히스토리를 보관하지 않는 드랍박스 사용을 중단하고 모두 개인 버전 관리 도구로 이전할 생각이었기 때문에 한 서버에 커다란 스토리지가 필요하고 여기에는 더 큰 비용이 필요한데 이를 장난감 서버와 합쳐 놓으면 비용을 관리하기 어려울 거라고 생각했기 때문입니다. 장난감 서버는 여전히 한 달에 10달러로 동작하면 충분합니다. 그렇게 처음에는 스토리지가 80기가인 한 달에 20달러를 내는 인스턴스로 시작했다가 스토리지가 부족해져 한 달에 40달러를 내는 스토리지가 160기가인 인스턴스 번들을 사용하기 시작했습니다. 돌고 돌아 퍼포스에 설명한 대로 퍼포스는 예나 지금이나 똑같이 잘 동작합니다. 한 번에 몇 만 파일을 보내든 몇 십 메가나 몇 백 메가를 보내든 군소리 없이 잘 동작했고 이는 몇 메가 짜리 파일 하나를 받으려고 해도 온갖 헛소리를 지껄이며 동작을 거부하는 깃과는 완전히 달랐습니다. 이제 퍼소스 서버는 30일 이전의 히스토리를 삭제하지도 않고 아무 새 기계에서 리파지토리를 다운로드 해도 깃처럼 풀을 거절하지 않을 것이 분명하며 지금까지 단 한 번도 그런 적이 없습니다.
하지만 지금까지 한 달에 오직 10달러를 내며 24시간 동작하는 여러 가지 서비스를 구동해 온 것에 비해 월 40달러를 추가 지출하는 건 문제가 있습니다. 월 10달러면 데이터베이스, 모니터링, GUI 기반의 자동화, php 스크립트 기반의 자동화 등등 온갖 용도로 사용하고도 충분했고 이런 편안한 물건에 월 10달러 정도는 낼 수 있다고 생각해 왔습니다. 하지만 월 40달러는 조금 다른 문제입니다. 특히 지금도 아직은 사용하고 있는 드랍박스의 월 비용이 20달러가 채 안 되면서도 2테라를 제공하는데 비하면 이는 엄청난 가격입니다. 하지만 저에게는 드랍박스에 추가 비용을 내고 최대 1년까지 파일의 이전 버전을 보관해 주는 서비스로는 부족합니다. 빈도가 높지는 않지만 작업 하다 보면 꽤 오래 전 파일이 필요할 때가 있는데 어쩌다 이 파일이 이전의 어떤 이벤트에 의해 삭제되었다면 드랍박스로는 추가 비용을 지출하더라도 최대 1년 전 까지만 파일을 꺼낼 수 있었습니다. 이런 어중간한 동작을 원하지 않습니다. 제 스스로 아주 오래된 파일을 영구적으로 제거하는 결정을 내리지 않는 이상 파일은 그 자리에 있어야 했고 파일을 우발적으로 제거했더라도 오래 전 리비전에서 파일을 다시 꺼내 올 수 있어야 합니다.
하지만 이런 요구사항을 만족하는 방법이 바로 데이터센터에서 구동되는 퍼포스 서버라는 사실을 마음으로는 알지만 머리로는 그 비용을 납득하기 쉽지 않았습니다. 그래서 가난뱅이 입장에서 어떻게 하면 한 달에 40달러를 지출해야 하는 퍼포스 서버 유지 비용을 줄일 수 있을지 고민했고 좀 구질구질하고 좀 웃기고 좀 슬프지만 방법을 찾을 수 있었습니다. 이는 이전까지 적극적으로 온갖 작업을 처리하던 아이폰 단축어 앱과 얼마 전에 사용하기 시작해 자동화 도구 n8n 사용기에서 소개한 n8n을 적당히 합쳐 서버를 필요할 때만 구동하고 사용하지 않는 동안에는 꺼 둬서 시간 당 비용을 절약하는 것입니다. 그러니까 저 단 한 명이 사용하는 서버인 이상 제가 자고 있을 때나 컴퓨터를 사용하고 있지 않을 때는 서버를 사용하지 않을 것이 확실하므로 이 때 서버를 꺼 두면 24시간 서버를 운영할 때와 비교해 비용을 획기적으로 줄일 수 있을 거라고 생각했습니다. 그래서 일단 아이폰 단축어를 하나 만들었습니다.
길어서 가로로 눕혔는데 핵심은 아이폰에서 실행하면 시작, 종료 메뉴를 보여주고 여기서 시작을 누르면 퍼포스 서버를 시작하고 종료를 누르면 퍼포스 서버를 종료하는 역할입니다. 다만 아이폰 단축어 앱 만으로도 장난감 서버를 통해 퍼포스 서버를 켜고 끌 수 있지만 기왕 직접 구동하는 n8n이 있으니 메뉴를 선택하는 데 까지만 단축어 앱 기능을 사용하고 나머지 동작은 장난감 서버에서 처리하도록 했습니다. 간단히 단축어 앱에서 시작을 선택하면 장난감 서버에서 동작하는 n8n에 시작하라는 메시지를, 그리고 종료를 선택하면 종료하라는 메시지를 전송합니다. 그럼 나머지는 n8n에서 아주 간단하게 처리할 수 있습니다.
n8n에서는 아이폰 단축어 앱으로부터 명령을 받으면 장난감 서버에 설치한 AWS CLI를 통해 명령을 보내 퍼포스 서버를 켜고 끄도록 했습니다. 다만 이 과정에서 조금 마음에 안 드는 점은 장난감 서버에 명령을 보내기 위해서는 서버를 만들 때 사용한 인증서가 필요한데 인증서는 보통 제 컴퓨터 로컬에 있지만 이 동작을 위해 인증서를 장난감 서버에 올려야 한다는 점입니다. 뭔가 인증서를 계속해서 로컬에 보관한 상태에서 이런 동작을 하도록 해 보안 수준을 올릴 방법이 있지 않을까 싶기는 한데 아직 잘 모르겠습니다. 그래서 지금은 개인적으로 요구하는 보안 수준에 못 미치는 방법으로 동작합니다.
그리고 아이폰에서는 잠 자기 시작할 때와 아침에 일어날 때를 이벤트로 받아 단축어를 실행할 수도 있는데 처음에는 잠 자기 시작할 때 퍼포스 서버를 끄고 아침에 일어날 때 퍼포스 서버를 켰지만 사실은 아침에 일어나서도 한동안은 컴퓨터를 사용하지 않으니 미리 부터 켜져 비용을 사용할 필요가 없어 보였습니다. 그래서 보통은 하루 중 컴퓨터 사용을 끝낼 때 아이폰 단축어를 사용해 퍼포스 서버를 종료하지만 만약 깜빡 하더라도 잠을 자기 시작할 때 한번 더 서버를 종료하도록 했고 대신 아침에 일어날 때는 서버를 시작하지 않도록 바꾸고 서버가 필요할 때는 명시적으로 단축어 앱을 사용해 서버를 시작하도록 바꿨습니다. 이렇게 만들어 놓고 한동안 사용해 보니 한달은 약 720 시간이고 월 비용인 40달러는 이 시간 전체에 걸쳐 서버가 동작할 때 지불해야 하는 비용입니다. 그런데 필요한 시간에만 서버를 켜 사용하고 사용이 끝나면 꺼 보니 한 달 전체 중에서 25%에도 미치지 않는 시간 동안에만 서버가 켜져 있으면 된다는 사실을 파악하게 됐습니다. 그러니까 서버가 켜져 있는 시간에만 과금하면 또 다시 한 달에 추가로 10달러를 내면 됩니다.
하지만 이렇게 계산이 깔끔하게 끝나지는 않습니다. 서버가 꺼져 있더라도 서버가 차지하고 있는 스토리지에는 계속해서 과금 되며 매일 서버를 백업해 일주일 어치를 보관하는 스냅샷이 차지하는 스토리지에도 과금 되기 때문에 전체 시간의 일부만 사용한다 하더라도 정확히 이 사용 시간 만큼만 돈을 내지는 않으며 이보다는 조금 더 큰 돈을 내야 합니다. 하지만 컴퓨터를 사용하는 시간 당 비용에 비해 스토리지 비용은 훨씬 저렴해서 이 정도는 가난뱅이 입장에서도 어느 정도 납득할 수 있는 수준입니다.
한동안 과연 드랍박스보다 더 큰 비용을 들여 드랍박스보다 불편한 방법을 사용하는 것이 올바른지를 고민해 봤는데 제 요구사항은 드랍박스보다 퍼포스 쪽에 더 가깝다는 사실을 늦게서야 깨달았습니다. 오래 전에는 SVN을 오랫동안 같은 용도로 사용하다가 여러 문제로 사용을 포기한 다음 오랫동안 드랍박스에 머물렀고 한동안 깃을 사용하며 의미 없는 고통에 시달린 끝에 이제 퍼포스를 선택했고 이쪽에 오래 전 SVN처럼 오랫동안 정착할 수 있지 않을까 싶습니다. 다만 비용을 통제하기 위해 좀 쪽팔리는 방식으로 서버를 사용하고 있는데 이건 미래의 제가 돈을 더 많이 벌어 해결할 문제라고 생각합니다.