처음으로 도커 이미지를 만들어 보고 배운 것

도커를 사용해 개인 인프라를 지탱한 지 1년이 다 되어 가지만 지금까지 도커 이미지를 한번도 만들어 본 적이 없었습니다.

처음으로 도커 이미지를 만들어 보고 배운 것

개인용 퍼포스 사용기 및 영업에서 퍼포스를 파일 관리에 사용하고 있다고 소개했습니다. 개인적으로 파일을 관리하기에 익숙하지 않다는 점을 제외하면 거의 장점이 없는 것처럼 이야기했습니다. 일단 모든 파일의 변경사항을 제한 없이 기록할 수 있다는 점이 가장 크고 일단 파일을 서브밋 하고 나면 클라이언트 측에서는 사실상 삭제할 방법이 없어 실수할 여지가 전혀 없다는 점, 여러 플랫폼과 여러 기계에 걸쳐 내가 필요할 때 필요한 만큼만 파일을 동기화 할 수 있다는 점 등은 여느 파일 동기화 서비스와 비교할 수 없을 정도로 강력한 장점입니다. 게다가 개인용으로 사용할 때 사용자 최대 다섯 명, 워크스페이스 최대 스무 개 까지 무료로 사용할 수 있는 점 역시 훌륭합니다. 하지만 장점만 있는 것은 아닙니다. 특히 모바일 환경을 전혀 지원하지 않기 때문에 파일 동기화가 필요한 모든 작업에 반드시 랩탑이나 데스크탑 환경이 필요합니다. 지금은 좀 익숙해졌지만 처음에는 이런 환경이 말이 안된다고 생각한 적도 있습니다. 이런 단점에도 불구하고 지난 1년 가까운 시간에 걸쳐 잘 동작하고 있을 뿐 아니라 다른 강력한 경쟁자가 나타나지 않는다면 계속해서 퍼포스에 머물 작정입니다.

이 환경은 다른 누군가가 만든 도커 이미지를 사용해 구축했습니다. 실은 퍼포스 서버를 처음 구축하려고 할 때 직접 퍼포스 서버를 서버 로컬에서 실행할까 생각한 적 있긴 하지만 당시 VPS에서 막 온프레미스로 전환한 참이어서 그동안 사용할 수 없었던 도커를 사용하기 시작할 때였고 다른 모든 서비스를 도커를 사용해 돌리는 김에 퍼포스 서버 역시 도커를 사용해 돌리면 깔끔하지 않을까 하는 생각이 들었습니다. 살펴보니 여러 사람들이 각자 퍼포스 서버의 도커 이미지를 만들어 사용하고 있었는데 당시 도커를 처음 써봐서 그런지 그들은 분명 동작한다고 주장했지만 막상 제가 실행해보면 예상대로 동작하지 않는 경우가 많아 시행착오를 한참 겪었습니다. 그러다가 여태까지 사용해 온 이미지를 만났고 이 이미지 역시 정확한 이유를 설명할 수 없지만 이번에는 예상대로 동작한 덕분에 도커를 사용해 퍼포스 서버를 구축한 다음 이 인프라에 제 거의 모든 파일 관리를 맡깁니다. 이 시스템은 안정적으로 잘 동작했습니다. 처음에는 서버를 돌리는 기계 사양이 VPS에 비해서는 좋지만 여러 서비스를 돌리기에는 충분하지 않은 M1 맥미니에 8기가 램을 붙인 기본 사양이어서 과연 괜찮을까 싶었는데 숫자를 보면 아슬아슬하게 동작하기는 했지만 숫자를 안 보고 사용하면 그리 걱정할 필요 없이 잘 돌아갑니다. 이 이미지를 사용해 컨테이너를 만들 때 이미지에 포함된 퍼포스 서버 버전은 2023.2로 당시 최신 버전이었습니다. 당시 시험적으로 아카이브 디팟에 한해 오브젝트 스토리지 지원이 추가되어 꽤 매력적이라고 생각해 도전했다가 아직은 때가 아니라는 교훈을 얻기도 합니다.

한편 시간이 흘러 최신 버전이 2024.1로 업데이트 되었습니다. 기나긴 릴리즈 노트를 살펴봐도 저 같은 개인 사용자가 관심을 가질 만한 기능은 많지 않습니다. 다만 이런 종류의 장기간에 걸쳐 사용되는 소프트웨어는 종종 오랜 세월에 걸쳐 최신 버전을 따라 가지 않을 경우 미래에 오래된 버전에서 한 번에 최신 버전으로 한 번에 올라갈 수 없을 때가 있습니다. 가령 같은 온프레미스 서버에서 함께 돌고 있는 MySQL 데이터베이스를 한동안 업데이트 하지 않다가 별 생각 없이 이미지를 받아 컨테이너를 실행했더니 제 기준에서는 버전이 그리 멀지도 않았는데 마이그레이션을 지원하지 않아 일단 이전 버전의 이미지로 돌아간 다음 마이그레이션을 지원하는 마이너 버전 단위로 이미지를 변경해 재시작 해 가면서 마이그레이션 과정을 겪은 다음에야 최신 버전을 사용할 수 있었습니다. 때문에 릴리즈 노트 상에 당장 필요해 보이는 기능이 없어 보이더라도 웬만하면 최신 버전을 따라갈 필요가 있습니다. 물론 개인 사용자 입장에서 관심이 갈 만한 변경사항이 아예 없지는 않았습니다. 일단 바이너리 파일을 서브밋 할 때 이전에는 항상 파일 전체를 올린 다음 서버에서 스토리지 설정에 따라 처리해 왔습니다. 가령 100메가짜리 바이너리 파일을 변경하면 일단 100메가 전체를 업로드 한 다음 서버에서 모든 리비전을 별도로 기록하도록 설정되어 있다면 각 파일을 따로 기록하고 변경사항만 기록하기로 되어 있으면 변경사항만 기록하고 있었습니다. 그런데 이제 클라이언트에서 서버로 보낼 때도 변경사항만 보낼 수 있어 크기가 큰 바이너리 파일의 일부만 변경될 때 파일 전체를 보내지 않을 수 있어 압도적으로 빨리 작업할 수 있으리라 기대할 수 있습니다.

개인 사용자 입장에서 관심 가는 또 다른 변경사항에는 오브젝트 스토리지 지원이 있습니다. 이미 2023.2 버전에서 아카이브 디팟에 한해 오브젝트 스토리지 지원을 시작했는데 사실 당시에는 제 예상대로 잘 동작하지 않았습니다. 특히 그들의 주장에 따르면 S3 호환 서비스도 지원한다고 했지만 실제로는 정확히 S3에 해당하는 설정에서 조금만 어긋나도 정확하지 않은 에러 메시지와 함께 동작하지 않기를 반복해 사용을 거의 포기하게 만들었습니다. 또한 아카이브 디팟에 한해 오브젝트 스토리지를 지원했기에 이를 사용하려면 아카이브 디팟을 사용해야만 했습니다. 아카이브 디팟은 퍼포스를 통한 파일 라이프사이클 관리 단계에서 가장 마지막 단계에 해당하는 단계에 사용하는 디팟으로 이제 직접적으로 파일에 접근할 일이 없어 성능이나 스토리지 비용 관리 차원에서 제거하기를 원하지만 아예 파일을 제거하기에는 미래에 무슨 일이 일어날지 모르니 위험성이 있을 대 오래된 파일이나 프로젝트를 아카이브 디팟으로 옮겨 관리하도록 만들어졌습니다. 특히 아카이브 디팟은 마운팅 포인트를 분리할 수 있어 이론적으로 아카이브 디팟을 콜드스토리지에 만든 다음 프로젝트나 날짜, 리비전 기준으로 파일을 옮긴 다음 스토리지를 분리해 별도 보관할 수 있고 미래에 이 파일이 필요한 이벤트가 일어나면 콜드스토리지를 다시 붙여 아카이브를 복원한 다음 이전과 똑같이 사용할 수 있었습니다. 이 시나리오는 말로 할 때는 그럴듯해 보이지만 실제로 활용하기에는 당장 개인 사용 시나리오에서조차 문제를 일으켰습니다. 일단 파일들이 어떤 ‘프로젝트’ 단위로 관리되지 않는 이상 리비전 기준이나 날짜 기준의 아카이빙은 이 경계선 이전의 파일을 앞으로 반영구적으로 사용하지 않겠다고 선언하는 행동이 되고 마는데 이런 선언은 항상 근미래에 어긋나기 마련입니다. 마치 영원히 사용하지 않을 것 같은 랜케이블을 다 갖다 버린 다음 며칠 뒤 랜케이블을 사용할 일이 생기는 것과 비슷합니다.

게다가 스토리지 비용 관리를 위해 아카이브 디팟을 사용하는 시나리오 역시 문제가 있습니다. 보통 퍼포스 디팟이 사용하는 스토리지는 서버에 직접 연결된 빠른 스토리지이기 대문에 비용이 높을 겁니다. 아카이브 디팟은 이 비용이 높은 스토리지로부터 사용빈도가 거의 없는 파일을 분리 보관해 비용을 관리할 수 있다고 주장합니다. 그런데 당장 아카이브 디팟으로부터 파일을 가져와 사용하려 할 때 그 절차가 복잡하고 또 큰 스토리지를 필요로 합니다. 처음 퍼포스 서버를 만들 때는 당시 M1 맥미니 중에서는 가장 큰 스토리지 옵션인 1테라바이트 짜리 스토리지를 사용했는데 로컬에 이 정도 크기를 유지하고 디팟이 이보다 더 커지면 아카이브 디팟으로 보내 스토리지 비용을 통제할 작정이었습니다. 실제로 제가 퍼포스에 서브밋 한 모든 파일의 크기가 1테라를 초과하면서 아카이브 디팟으로 파일을 보내야만 했는데 이를 통해 로컬 스토리지를 확보하는 것 까지는 좋았지만 일단 아카이브 한 파일을 다시 사용해야 하는 시나리오에서 문제가 일어날 수밖에 없었습니다. 아카이브 디팟으로부터 파일을 되돌리려면 당연히 로컬 스토리지에 충분한 공간이 필요하기 때문에 스토리지 용량 관리를 위해 아카이브 디팟을 사용한다는 것은 말이 안 됩니다. 만약 일반 디팟과 아카이브 디팟 사이에 파일을 편안하게 주고 받을 수 있다면 그나마 문제를 덜 겪을 수 있었을른지도 모르지만 퍼포스 비주얼 클라이언트(p4v) 상에서는 아카이브에 관련된 어떤 기능도 제공하지 않아 아카이브에 접근하려면 반드시 퍼포스 커맨드라인 클라이언트(p4cli)를 사용해야만 했고 이 과정은 굉장히 귀찮았습니다.

이 난리를 겪은 다음 이런 문제를 근본적으로 해결할 방법으로 맥미니에 썬더볼트 인터페이스를 통해 직접 연결되는 대용량 하드디스크를 붙이고 모든 퍼포스 디팟을 옮깁니다. 이제 이전에 비해 방대한 공간이 생겨 더 이상 아카이브 디팟에 의존할 필요가 없어졌습니다. 이전에 아카이브 했던 모든 파일을 라이브 디팟으로 되돌린 다음 아카이브 디팟을 제거할 수 있었습니다. 이제 스토리지를 관리하기 위해 남은 공간에 관심을 가질 필요가 없어졌고 어떤 파일의 오래된 리비전이 필요할 때 이 리비전이 아카이브 경계선 이전에 있지는 않은지 신경 쓸 필요도 없어집니다. 그냥 아무 생각 없이 파일을 서브밋하고 그냥 그걸로 잊어버릴 수 있게 됩니다. 하지만 장기적으로 이런 상황이 지속될 수 있으리라 생각하지는 않습니다. 아무리 온프레미스 환경을 구축하고 있다 하더라도 이 환경이 너무 복잡해져 하드웨어 관리에 시간을 써야 하거나 너무 많은 전력을 소모하거나 너무 거창한 하드웨어를 사용해야만 하는 상황을 만들고 싶지 않습니다. 그래서 서버 기계로 확장이 불가능함을 알면서도 맥미니를 선택했고 또 확장이 불가능함을 알면서도 물리적인 하드디스크 한 개만 사용하는 외장 하드디스크를 선택했습니다. 이들의 한계는 명확하지만 최대한 간결한 환경을 만들어 개인적인 유지보수 비용을 낮출 수 있습니다. 하지만 컨슈머용 하드디스크는 최대 용량이 24테라바이트 까지만 판매되고 있고 이 한계가 당분간 급격히 증가할 것 같지 않기 때문에 언젠가 이 공간이 부족한 날이 찾아올 테고 그 때를 대비한 시나리오는 필요합니다. 비록 그 때가 먼 미래에 있다 하더라도 말입니다.

그런데 2024.1 버전부터는 오브젝트 스토리지 지원이 아카이브 디팟 뿐 아니라 모든 디팟으로 확대됩니다. 이론적으로 조금 느린 속도를 참을 수 있으면 이전처럼 복잡하고 귀찮은 아카이브 과정 없이 라이브 디팟 전체를 오브젝트 스토리지로 옮긴 다음 그냥 그대로 사용할 수 있습니다. 오브젝트 스토리지는 이론적으로 온프레미스 환경에서 사용 가능한 최대 용량인 24테라바이트보다 훨씬 거대한 용량을 사용할 수 있게 해 줄 뿐 아니라 확장이 자유롭기 때문에 장기적으로 맥미니 서버에 붙어 있는 커다란 하드디스크가 가득 찰 때 아직 컨슈머용 하드디스크 최대 크기가 충분히 커지지 않은 상황에 대응할 수 있는 적당한 방법입니다. 게다가 지금은 오프사이트 백업에 크래시플랜이라는 별도 서비스를 사용하고 있습니다. 백업을 서버와 같은 장소, 또는 가까운 장소에 놔두는 것 자체가 말이 안 되므로 차라리 로컬 백업 없이 오프사이트 백업만 유지하는 편이 차라리 나은 선택이라고 생각합니다. 백업 크기에 관계 없이 가격이 월 약 8달러 고정인 점은 강력한 장점이지만 만약 이를 실제로 사용해야 하는 광범위한 사고가 일어난다면 백업을 복원하는데 엄청난 시간이 필요할 겁니다. 없는 것 보다는 완벽하게 훌륭한 상황이지만 복원 과정은 썩 즐겁지 않을 거라고 예상합니다. 반면 라이브 디팟 전체가 오브젝트 스토리지를 사용한다면 애초에 이들을 위한 별도의 백업을 운영할 필요가 거의 없습니다. 당장 이 기능을 사용하지 않더라도 앞으로 오브젝트 스토리지 지원 기능이 점점 더 개선될 것이 확실해 보이니 최신 버전을 따라가지 않을 이유가 없습니다.

이제 개인 사용자 입장이라도 퍼포스 서버 최신 버전을 따라 갈 이유는 확실해졌는데 여기에는 작은 문제가 하나 있습니다. 앞서 퍼포스 서버를 구축하는데 누군가가 만들어 놓은 이미지를 사용했는데 이 이미지가 최신 버전으로 업데이트 되지 않고 있다는 점입니다. 사실 기존 이미지를 만드는데 사용한 소스코드는 최신 버전을 빌드할 수 있도록 업데이트 되어 있었지만 정작 이를 실행한 결과 이미지는 도커 허브에 올라와 있지 않았습니다. 이런 점들이 누군가 만들어 놓은 인프라를 편안하게 사용하는 대가가 아닐까 싶습니다. 언제까지 누군가가 소스코드를 사용해 최신 퍼포스 서버를 포함한 이미지를 빌드하기를 기다리는 것 보다는 그동안은 별로 배우고 싶지도 않고 또 주의 깊게 살펴보지 않은 상태에서 뭔가 복잡하고 귀찮아 보이는 이미지 빌드를 직접 해 보기로 마음 먹습니다. 사실 이쯤 해서 도커 이미지를 직접 만들 결정을 하는데 이 난리를 칠 정도로 도커 이미지 만드는 과정이 복잡하지 않다는 사실을 아시는 분들은 좀 웃긴 상황으로 보일 겁니다. 이제 와서 생각해보면 저는 이미지를 빌드한다는 표현을 보고 리눅스에서 소스코드를 내 환경에 맞도록 바이너리를 만드는 빌드와 같은 의미로 생각해 뭔가 복잡하고 귀찮은 과정이 도사리고 있을 뿐 아니라 올바른 하드웨어에서 빌드해야만 할 거라는 선입견을 가지고 있었습니다. 그래서 더더욱 이미지를 직접 만들 생각을 안 해 왔던 것 같습니다. 하지만 퍼포스 서버 버전을 2024.1로 따라가기로 결정했고 이미지를 직접 만들어 보기로 합니다.

일단 기존 이미지를 만드는데 사용된 소스코드를 포크하는데서 시작합니다. 모르긴 몰라도 분명 제가 뭐라도 수정할 것이 거의 확실하니 실제로 수정을 하든 말든 일단 포크한 다음 살펴보기로 합니다. 포크 해 온 다음 살펴보니 이 소스코드를 만든 분은 저 같은 사람이 빌드 과정을 쉽게 시작할 수 있도록 그냥 스크립트 하나를 실행하면 나머지 과정이 모두 수행되도록 만들어 놓은 상태였습니다. 다만 저는 이 시점까지도 아직 이미지를 만드는데 필요한 도커파일이니 뭐니 하는 설정들을 전혀 모르는 상태였기 때문에 일단 파일들을 하나하나 열어 대체 무슨 소리를 하는 것인지 알아봐야 했습니다. 빌드를 시작하는 엔트리 포인트 스크립트를 실행하면 Dockerfile로 이어지는데 처음 보는 스크립트이긴 했지만 뭘 하고 싶은지, 어떤 식으로 진행되는 과정인지 파악하는데 어려움을 겪지는 않았습니다. 마치 제가 일하다가 종종 겪는 소위 노가다 과정을 회피하기 위해 화면을 직접 조작하는 스크립트를 만드는 것과 비슷해 보입니다.

가령 어떤 개발환경의 인터페이스가 너무 후진 나머지 여러 데이터를 한 번에 처리할 인터페이스를 제공하지 않는 상황이라면 이들을 한 번에 처리할 수 있을 가능성이 있음에도 어쩔 수 없이 후진 인터페이스를 이용해 데이터를 하나하나 처리할 수밖에 없습니다. 이럴 때 반복해서 조작해야 하는 화면 상 인터페이스 구성요소의 핸들을 얻어와 조작하거나 그럴 수 없는 환경이라면 그냥 화면 상의 좌표를 직접 조작하는 방식으로 후진 인터페이스를 돌파해 잠깐 돌려 놓고 화장실 다녀 오면 일이 끝나 있는 스크립트를 만들 수 있습니다. 화면을 직접 조작해야만 하는 최악의 상황에서 스크립트를 만들다 보면 눈을 감고 화면을 조작하는 것과 굉장히 유사합니다. 버튼을 클릭한 다음 이 클릭에 의한 결과가 화면에 나타났으리라 가정하고 다음 눌러야 하는 버튼이 있는 좌표를 클릭해야 하는데 이는 믿음의 영역입니다. 어떤 이유로 이전 조작이 실패한 상태라면 다음 조작은 연달아 실패하게 됩니다. 이런 상황에 대비해 조작을 스크립트로 옮기다 보면 마치 눈을 감고 화면을 조작하는 것과 비슷한 로직을 만들게 되는데 도커파일이 딱 그런 모양처럼 보입니다.

일단 특정 운영체제 이미지로부터 시작하는데 정확한 기술적 배경은 여전히 잘 모르지만 특정 운영체제의 이미지를 VM 기반으로 실행한 다음 그 안에서 여러 명령어를 입력해 필요한 소프트웨어를 설치하고 필요한 설정을 하는 것 같아 보입니다. 제가 살펴본 도커파일은 우분투 이미지로부터 시작하는데 의미 있는 첫 번째 실행 구문이 RUN apt-get update인 것으로 미루어 특정 운영체제 이미지를 지정하면 일단 이 운영체제를 실행하는 것 같습니다. 저는 M1 맥에서 이 작업을 하고 있었지만 도커를 통해 AMD64 아키텍처용 우분투를 받아 VM을 통해 실행했기 때문에 앞서 ‘빌드’라는 단어 때문에 겁 먹게 만든 CPU 의존적인 컴파일 과정을 필요로 하지 않습니다. 그냥 VM을 통해 우분투를 실행한 다음 적혀 있는 명령어를 실행하기를 반복해 특정 상태를 만든 다음 마지막으로 이 이미지가 실행될 때 운영체제의 부팅이 끝나면 맨 처음 어떤 파일을 실행할 것인지를 지정하는 구문으로 끝납니다. 그러니까 제 관점에서 도커 이미지 생성 과정은 노가다를 피하기 위해 작성한 화면 조작 스크립트와 똑같아 보였습니다. 일단 도커 이미지 생성 과정이 대강 어떻게 돌아가는지 나름의 방식으로 이해했으니 다음은 제 필요에 맞게 수정할 차례인데 어떤 버전을 가져와야 하는지는 퍼포스에서 직접 운영하는 우분투 배포 파일을 살펴보고 필요한 버전을 가져와야 합니다. 제가 설치하려는 패키지 이름은 퍼포스 서버를 의미하는 Package: helix-p4d여서 그냥 이 문자열을 검색한 다음 살펴보면 제가 도커 이미지 생성 과정 도중 다운로드 해서 설치해야 할 버전이 2024.1-2655224~focal이라는 것을 알 수 있습니다. 실망스런 부분도 있었는데 퍼포스 릴리즈 노트에 따르면 이번 버전부터는 애플 실리콘에서 네이티브로 실행되는 ARM64 아키텍처를 지원한다고 되어 있습니다. 하지만 제가 포크 해 사용하려는 소스코드는 APT를 사용해 바이너리를 다운로드 하게 되어 있습니다. 하지만 퍼포스는 아직 AMD64 바이너리만 APT를 통해 제공할 뿐 ARM64 바이너리는 압축 파일을 직접 배포하고 있습니다. 이를 해결할 방법을 모르는 상태이므로 이번에는 어쩔 수 없이 AMD64이미지를 만들고 지금까지와 마찬가지로 로제타 신세를 지기로 합니다.

도커파일의 제 수정사항은 먼저 맨 처음 시작할 운영체제 버전을 정확히 명시한 것입니다. 이전에는 ubuntu:focal로 되어 있었는데 사실 이거면 충분합니다. 하지만 앞서 설명했듯 얼마 전 데이터베이스 이미지를 업데이트 하고 컨테이너를 새로 띄울 때 이번 버전과 최신 버전 사이에 간격이 커 마이그레이션을 지원하지 않아 상당히 귀찮은 상황이 일어났음을 알고 있는 입장에서 정확한 버전을 입력하지 않고 무작정 latest 태그를 붙여 이미지를 가져오면 문제가 생길 수 있다는 인식을 가지게 됩니다. 그래서 굳이 필요하지 않을 것 같지만 항상 모든 이미지에 정확한 태그를 사용해 의도하지 않은 이미지를 사용하지 않는 습관이 생겼고 이미지에 사용할 운영체제는 ubuntu:focal-20240918로 수정합니다. 다음으로 \ 문자와 && 문자를 사용해 여러 명령어를 한번에 실행하던 것을 모두 한 줄에 명령어 하나만 실행되도록 수정했는데 이건 순전히 제가 보기 편하게 만들기 위한 것입니다. 또 이전에 비해 systemd 설치를 추가했습니다. 이를 설치하지 않아도 퍼포스 서버는 멀쩡히 잘 동작하지만 표준시 기준으로 동작해 퍼포스 클라이언트 상에 낯선 시각이 표시됩니다. 퍼포스 클라이언트 설정에 서버 시각 대신 로컬 시각을 표시하는 옵션이 있음을 알고 있지만 클라이언트마다 설정을 변경하고 싶지 않았기 때문에 운영체제의 시간대 설정을 변경하기 위해 필요했습니다. 일단 systemd가 설치되고 나면 RUN cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime을 수행해 시간대를 한국 표준시로 바꿀 수 있습니다. 이는 시스템을 재시작 할 때 적용되는데 어차피 이미지는 처음 실행될 때 재시작 될 예정이므로 신경 쓸 필요가 없습니다.

이미지는 랩탑에서 만들었기 때문에 이를 서버 기계로 옮길 방법을 잠깐 고민했는데 그냥 도커 허브에 보낸 다음 도커 허브로부터 받으면 되는 간단한 문제였습니다. 이미지를 도커 허브에 보낼 때도 앞서 설명한 정확한 버전을 태그에 언급하는 원칙에 근거해 latest 같은 제 기준에서는 위험하기 짝이 없는 표현은 아예 넣지 않았습니다. 그 대신 태그 이름은 2024.1이라고 했는데 이미지를 만들어 공개한 다음에 살펴보니 최신 버전은 2024.1이 맞지만 메이저 버전 번호가 바뀌지는 않았지만 서로 다른 빌드넘버로 두 번 배포가 일어났다는 사실을 알게 됩니다. 이를 이미지를 올리기 전에 알았더라면 태그를 2024.1-2655224~focal이라고 버전넘버와 운영체제 이름을 포함한 더 정확한 이름으로 설정했을 것 같습니다. 퍼포스는 1년에 한 두 번 정도 최신 버전을 발표하는 것 같은데 이 정도 주기를 지킨다면 다음 번 이미지 빌드는 앞으로 몇 달은 지난 다음일 테니 일단 지금 올라간 이미지는 그대로 두고 다음 번 최신 버전 이미지를 만들 때는 좀 더 정확한 버전 이름을 태그에 포함해야겠습니다. 그리고 어쩌면 그때는 애플 실리콘에서 네이티브로 동작하는 ARM64 바이너리도 APT를 통해 배포될지도 모르니 미래에는 로제타 신세를 지지 않아도 될지도 모릅니다. 이제 직접 만든 이미지를 사용해 퍼포스 서버를 최신으로 올릴 수 있게 됐지만 동시에 이제부터는 새 퍼포스 서버 버전이 나올 때마다 이 작업을 직접 해야 하는 귀찮음이 생겼습니다. 또 데이터베이스 마이그레이션이 일어나 데이터베이스 버전이 52에서 54로 변경되어 이제 이전 버전으로 되돌리고 싶으면 체크포인트 파일을 사용해 데이터베이스를 다시 생성해야만 합니다. 돌아갈 일이 생기지 않기를 바랄 뿐입니다.

한편 이번에 처음으로 도커 이미지를 만들어 보며 배운 점, 느낀 점들이 있습니다. 일단 도커 이미지 빌드는 ‘빌드’라는 단어를 보고 소스코드에 기반해 컴파일 과정을 거쳐 바이너리를 만드는 과정일 거라고 생각했습니다. 그래서 꽤 복잡하고 어렵고 예상대로 동작하지 않는 수많은 트러블슈팅의 연속일 거라고 예상해 도커 이미지를 만들 생각 자체를 아예 하지 않아 왔습니다. 그런데 실상은 빌드 과정이 VM - 혹은 도커 - 기반에서 실행되기 때문에 실행 환경은 아무런 영향을 주지 않습니다. 또한 운영체제가 실행된 다음 필요한 환경을 만들기 위한 명령어들은 마치 일할 때 노가다를 피하기 위해 작성한 화면 조작 스크립트와 비슷한 느낌이어서 그저 모든 명령이 문제 없이 실행되기를 기도하는 것과 별로 다르지 않습니다. 그냥 평소에 하던 것처럼 커맨드라인 기반으로 필요한 소프트웨어를 설치하고 필요한 설정을 변경하면 됩니다. 설정을 변경하기 좀 귀찮은 상황이라면 미리 설정 파일을 만들어 놨다가 운영체제 밖에서 안으로 복사해 넣으면 문제가 굉장히 간단해집니다. 또 개인적으로 사용할 이미지여서 SSL 설정을 기본으로 설정하고 또 서버 시간대를 한국 표준시로 설정한 것도 재미있었습니다. 다만 제 핵심 파일 관리 환경을 제가 직접 통제할 수 있게 된 것 까지는 좋지만 앞으로 서버 버전이 올라갈 때마다 이런 작업을 매번 직접 수행해야 한다는 점은 아쉽습니다. 제가 사용한 소스코드를 만든 누군가가 최신 버전 이미지를 도커 허브에 좀 올려주면 좋지 않았을까 싶은 생각이 잠깐 들었지만 거기까지 바라는 건 좀 너무한 것 같습니다.

https://hub.docker.com/r/neoocean/helix-p4d

처음으로 빌드해 본 helix-p4d:2024.1이미지는 위 주소에 있습니다. 제가 포크해 온 버전과 달라진 가장 큰 차이점은 서버 시간이 한국 표준시로 설정되어 있다는 점입니다. 개인용 퍼포스 사용기 및 영업을 보고 퍼포스로 파일을 관리해 볼 생각을 하셨다면 이 이미지로 시작해 보시는 것도 나쁘지 않을 겁니다. 이미지를 제가 직접 통제할 수 있으니 트러블슈팅이나 요구사항 반영이 가능합니다. 아니 그냥 남이 만든 이미지를 받아 편안하게 살 생각이었는데 도대체 왜 이렇게 된 것인지 잘 모르겠습니다. 여튼 이제 도커 이미지를 한 번 빌드해본 적 있다고 말할 수 있습니다.