プログラミング
GoコードをGitHubに依存させない
Don't couple your Go code to GitHub (iain.rocks)
要約
Go言語のデフォルトのインポートパスは、コードのホスティング場所と結びついているため、GitHubのような特定のプロバイダーにコードが強く依存してしまう問題があります。この依存関係は、ホスティングサービスを変更する際の大きな障害となり、コスト増加にもつながりかねません。解決策として、カスタムドメインを使用することで、ホスティングプロバイダーの変更に柔軟に対応できるようになります。
全文翻訳
GoコードをGitHubに依存させない
2026年9月27日
Goの優れた機能の1つは、コードを取得する場所でコードに名前空間を設けることです。これは、Goコードをhttp://github.com/thetrueares/bonecloneでホストする場合、import “github.com/thetrueares/boneclone”という行があり、Goはgitを使用してそれを取得することを意味します。これにより、オープンソースライブラリのバグを報告する場所が非常にわかりやすくなり、中央集権的なパッケージ管理システムなしでGoライブラリを取得および配布することが非常に簡単になります。多くの人にとって、これは文字通りgitホスティングの場所ですが、これにはいくつかの欠点があり、独自のカスタムドメインを使用すべきであり、その理由を説明します。
問題
gitホスティングの場所を使用する主な問題は、コードがホスティングプロバイダーに依存してしまうことです。つまり、gitホスティングをGitLabに移行する場合、コードを変更しなければなりません!そうでなければ、古いバージョンを取得することになります。これにより、切り替えにかかるオーバーヘッドの量が原因で、gitホスティングプロバイダーを変更できなくなる可能性があります。そのため、コードは文字通りGitHubに依存した状態になります。これはまったくばかげているように聞こえますが、Goコミュニティでは事実上の標準となっています。
この問題が、GitLab、GitHub、Azure Devopsを同時に使用していた企業にとって非常に大きな問題となったのを目の当たりにしました。コードの場所を変更するのは彼らにとって非常に大きなタスクであり、「時間がなかった」ため、3つのプラットフォームで運用する方が簡単でした。そして、私がBonecloneを構築した理由も、複数のgitホスティングプラットフォームで同時にスケルトンコードのレプリケーションを処理するためです。そのため、この問題は文字通り、企業にコストをかけました。なぜなら、彼らは同時に3つのホスティングサービスに料金を支払う必要があったからです。
解決策
解決策は、go.iain.rocks、go.uber.org、go.mongodb.orgなどのカスタムドメインを使用することです。これにより、これらのドメインが指す場所を変更するだけで済みます。たとえば、go.iain.rocks/bonecloneはgithub.com/thetrueares/bonecloneを指し、GitLabに移行してもエンドユーザーには何も変わりません。インストールコマンドは同じです。
私の意見では、Goを使用するすべての商用ソフトウェア開発チームは、内部ライブラリやパッケージの名前空間を設定するためにカスタムドメインを使用すべきです。なぜなら、それは無駄な依存関係を回避する簡単な方法だからです。
プロジェクトでも設定できるように、私の設定のコピーを以下に示します。
Nginx.conf
server {
server_name go.iain.rocks;
root /var/www/go.iain.rocks;
index index.html;
location / {
# クエリ文字列に 'go-get=1' が含まれていないかチェックします。
# '~' は大文字と小文字を区別するマッチングです。
if ($args !~ go-get=1) {
# これは人間の訪問者です。GitHubへの恒久的なリダイレクトを発行します。
# $request_uri はパスになります。例: /boneclone
return 301 https://github.com/that-guy-iain$request_uri;
}
# Goツール(?go-get=1付き)の場合は、これまでどおりHTMLファイルを配信します。
try_files $uri $uri/ =404;
}
# --- CertbotからのSSL設定はここに残しておく必要があります ---
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/go.iain.rocks/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/go.iain.rocks/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
# HTTPからHTTPSへのリダイレクトブロックも残しておく必要があります。
server {
listen 80;
listen [::]:80;
server_name go.iain.rocks;
return 301 https://$host$request_uri;
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="go-import" content="go.iain.rocks/boneclone git https://github.com/that-guy-iain/boneclone">
<meta name="go-source" content="go.iain.rocks/boneclone https://github.com/that-guy-iain/boneclone https://github.com/that-guy-iain/boneclone/tree/master{/dir} https://github.com/that-guy-iain/boneclone/blob/master{/dir}/{file}#L{line}">
</head>
<body>
</body>
</html>