TL;DR

  • Go 모듈 경로를 Git 호스팅 제공업체의 주소로 지정하면 호스팅을 옮길 때 코드도 변경해야 하므로, Go 코드의 호스팅 종속성을 피하려면 자체 도메인을 사용해야 함.
  • Go는 코드를 가져올 위치를 네임스페이스에 포함하며, 예를 들어 http://github.com/thetrueares/boneclone에서 호스팅하는 코드는 github.com/thetrueares/boneclone을 가져오는 방식임.
  • Git 호스팅 위치 변경 작업이 부담이 돼 GitLab, GitHub, Azure DevOps를 동시에 운영한 회사 사례가 있으며, 세 호스팅 서비스 비용이 발생함.
  • go.iain.rocks, go.uber.org, go.mongodb.org 같은 자체 도메인을 사용하면 도메인이 가리키는 위치만 바꾸고도 최종 사용자의 설치 명령을 유지할 수 있음.
  • Nginx는 일반 방문자를 GitHub로 영구 리디렉션하고, go-get=1 요청에는 go-import와 go-source 메타데이터가 포함된 HTML을 제공하는 구성임.

문제

  • Go는 코드를 가져올 위치를 네임스페이스로 사용함. 예를 들어 http://github.com/thetrueares/boneclone에서 코드를 호스팅하면 github.com/thetrueares/boneclone을 가져오며, Go는 Git을 사용해 코드를 가져옴.
  • 이 방식은 오픈소스 라이브러리의 버그 신고 위치를 쉽게 파악하고, 중앙 집중식 패키지 관리 시스템 없이 Go 라이브러리를 가져오고 배포하기 쉽게 함.
  • 하지만 코드가 호스팅 제공업체에 종속됨. Git 호스팅을 GitHub에서 GitLab으로 옮기면 코드를 변경해야 하며, 변경하지 않으면 이전 버전의 코드를 가져오게 됨.
  • 전환 작업의 부담 때문에 호스팅 제공업체를 바꾸기 어려워질 수 있으며, Go 커뮤니티에서는 이런 호스팅 위치 기반 네임스페이스가 사실상 표준임.
  • 한 회사는 코드 위치를 바꾸는 작업이 너무 커서 시간이 없다는 이유로 GitLab, GitHub, Azure DevOps를 동시에 사용함. 세 호스팅 서비스 비용을 함께 부담하게 된 사례임.
  • 이 문제를 계기로 여러 Git 호스팅 플랫폼에 스켈레톤 코드를 복제하는 Boneclone을 구축함.

해결책

  • go.iain.rocks, go.uber.org, go.mongodb.org 같은 자체 도메인을 사용하면 도메인이 가리키는 대상을 바꾸는 방식으로 호스팅 위치를 전환할 수 있음.
  • 예를 들어 go.iain.rocks/boneclone은 github.com/thetrueares/boneclone을 가리킬 수 있으며, GitLab으로 옮겨도 최종 사용자의 설치 명령은 그대로 유지됨.
  • 상용 소프트웨어를 개발하는 Go 팀은 내부 라이브러리와 패키지의 네임스페이스에 자체 도메인을 사용하는 것이 바람직하며, 이는 불필요한 종속성을 피하는 간단한 방법임.

Nginx 및 HTML 설정

  • Nginx에서 go.iain.rocks를 서버 이름으로 지정하고 웹 루트를 /var/www/go.iain.rocks로 설정함.
  • 요청의 쿼리 문자열에 go-get=1이 포함되지 않으면 일반 방문자로 처리해 요청 경로를 유지한 채 https://github.com/that-guy-iain$request_uri로 영구 리디렉션함.
  • go-get=1 요청에는 파일 경로를 찾아 제공하고, 없으면 404 응답을 반환함.
  • HTTPS는 go.iain.rocks에 대해 443 포트에서 처리하며, 인증서 경로는 /etc/letsencrypt/live/go.iain.rocks/fullchain.pem 및 /etc/letsencrypt/live/go.iain.rocks/privkey.pem임. Certbot의 Nginx 옵션과 DH 매개변수 설정도 유지함.
  • 80 포트의 HTTP 요청은 https://$host$request_uri로 리디렉션함.
  • HTML의 go-import 메타데이터는 go.iain.rocks/boneclone이 Git 저장소 https://github.com/that-guy-iain/boneclone을 사용한다고 지정함.
  • go-source 메타데이터는 소스 저장소 https://github.com/that-guy-iain/boneclone, 디렉터리 URL https://github.com/that-guy-iain/boneclone/tree/master{/dir}, 파일 URL https://github.com/that-guy-iain/boneclone/blob/master{/dir}/{file}#L{line}을 지정함.