Lobsters

Don't couple your Go code to GitHub

Go 코드를 GitHub에 종속시키지 마세요

Go 패키지 경로에 GitHub 같은 호스팅 주소를 직접 쓰면 저장소 이전 때 import 경로도 바꿔야 합니다. 글쓴이는 자체 도메인과 Go 메타 태그를 사용해 경로를 고정하고, 뒤에서 연결할 Git 호스팅 서비스를 바꾸는 방법을 소개합니다.

AI 요약

Go는 패키지를 가져올 경로에 코드 위치를 함께 적습니다. 예를 들어 저장소가 github.com/thetrueares/boneclone에 있으면 import 경로도 그대로 github.com/thetrueares/boneclone이 됩니다. 중앙 패키지 관리 시스템 없이 코드를 배포하고, 버그를 제보할 저장소를 찾기 쉽다는 장점이 있습니다. 하지만 Git 호스팅 주소를 패키지 경로로 쓰면 호스팅 업체를 옮길 때 코드까지 바꿔야 합니다.

호스팅 주소에 생기는 종속성

저장소를 GitHub에서 GitLab으로 옮겨도 기존 import 경로는 이전 주소를 가리킵니다. 새 주소를 사용하려면 코드를 수정해야 하고, 전환 작업이 부담스러우면 기존 호스팅에 계속 남게 됩니다. 글쓴이는 GitLab, GitHub, Azure DevOps를 동시에 사용하던 한 회사 사례를 소개합니다. 코드 위치를 옮기는 작업에 시간이 들자 회사는 세 서비스를 모두 운영했고, 그만큼 호스팅 비용도 발생했습니다. 글쓴이는 여러 Git 호스팅 서비스에 뼈대 코드를 복제하는 도구 Boneclone을 만들었다고 설명합니다.

자체 도메인으로 경로를 고정하기

대안은 go.iain.rocks, go.uber.org, go.mongodb.org처럼 자체 도메인을 패키지 경로에 쓰는 방식입니다. go.iain.rocks/boneclone을 사용하면 실제 저장소가 GitHub에서 GitLab으로 옮겨가도 사용자의 설치 명령은 그대로 유지됩니다. 도메인이 가리키는 위치만 바꾸면 됩니다. 글쓴이는 특히 Go를 쓰는 상업 개발팀이 내부 라이브러리와 패키지에 자체 도메인을 사용하는 편이 불필요한 종속성을 피하는 데 좋다고 권합니다.

Go 메타 태그와 Nginx 설정

Go 도구는 패키지 경로에 ?go-get=1을 붙여 요청하고, 서버가 반환하는 HTML의 go-import 메타 태그에서 저장소 위치를 확인합니다. 예시에서는 go.iain.rocks/boneclone이 Git 저장소라는 정보와 실제 GitHub 주소를 태그에 적습니다. go-source 태그에는 소스 코드와 파일을 볼 주소도 지정합니다.

Nginx 설정은 go-get=1 요청에는 해당 HTML 파일을 제공하고, 일반 브라우저 요청에는 GitHub 주소로 영구 리디렉션합니다. HTTP 요청은 HTTPS로 보내며, SSL 인증서는 Certbot 설정을 유지합니다. 이 구성에 따르면 패키지 경로는 자체 도메인으로 유지하면서 사람은 기존 호스팅 사이트에서 코드를 확인합니다.

Lobsters 반응

  • @confusedcyborg — 다만 암묵적인 신뢰 문제가 있습니다. GitHub가 호스팅한 서비스의 무결성은 믿기 때문에 GitHub에서 어떤 코드가 제공되는지 확인할 수 있습니다. 잘 모르는 도메인은 같은 수준으로 신뢰하기 어렵습니다. 악성 도메인이 브라우저에 보여주는 내용과 Go가 의존성을 가져갈 때 제공하는 내용이 서로 다르면 어떻게 하나요?
    • @twp — Go 모듈 프록시가 이런 공격을 감지합니다. 서버가 매번 정확히 같은 바이트를 제공하지 않으면 오류가 발생합니다.
    • @georgelesica — 제 생각에 우려는 악성 사이트가 Go 도구에만 다른 내용을 제공한다는 뜻이 아닙니다. 사람이 감사를 위해 소스 코드를 확인하는 UI에는 한 가지를 보여주고, Go 도구가 저장소를 가져갈 때는 다른 코드를 주는 상황을 말하는 것 같습니다. 코드가 내 컴퓨터에 도착한 뒤 직접 확인할 수는 있지만, 번거로움이 더해집니다.
    • @kiyurica — 정확히 말하면 Go 모듈 프록시는 콘텐츠가 시간에 따라 바뀌지 않는지 확인합니다. 웹 UI에 보이는 내용과 Git으로 가져오는 내용이 같은지는 검증하지 않습니다. 혼란을 제기한 분이 말한 문제는 그 부분인 듯합니다.
  • @mdaniel — 주장 자체에는 개념적으로 동의하지만, 이런 방식을 쓰는 사람들은 제가 “그래서 소스는 어디 있나요?”라고 확인할 때 단계를 하나 더 늘립니다. ?go-get=1 문법을 기억하고, 페이지 소스를 열고, 메타 선언의 변수를 머릿속으로 치환해야 합니다. 이런 번거로움에다 go.mod의 replace 지시문까지 더하면, 개인적으로는 Go에서 정말 없어도 좋았을 요소들입니다.

원문: Iain Rocks / 번역·요약: Trawling