とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど

開催予定の勉強会

読者登録と各種SNSのフォローもよろしくお願いいたします。

GitBucketでGitHubリポジトリーのミラーを作成してみる

Gitとは、一言でいうとソースコードなどの分散型バージョン管理システムです。 もともとはLinuxカーネルのソースコード管理をするためにLinuxカーネルの開発者でもあるリーナス・トーバルズ氏によって開発され、それ以降ほかの多くのプロジェクトで採用されています。

Gitは分散型のバージョン管理システムと最初に説明したように、作業に常時ネットワークアクセスが必要ない点が他のバージョン管理システムと異なるところです。普段はローカルリポジトリー上で開発して、定期的にリモートリポジトリーと同期して開発を進めていく...そんな使い方をします。すでに開発中のソフトウェアに対して開発する場合は、もとのリポジトリーをクローンして開発を行ってソースコード元にコントリビュートするためにプルリクエストを投げたり、コミット権があるリポジトリーであればソースコードをマージします。 ソースコードはすべて履歴管理されるため、複数人でのソースコード開発がしやすくなります。

一人でGitを使ってソースコード管理する場合は必須ではありませんが、Gitで複数人でソースコード管理するには何らかのGitサーバーが必要です。もっとも一人で開発していたとしても現在は何らかのGitサーバーを介してソースコード管理していると思います。

最も多くの人に知られているGitサーバーはGitHubかもしれません。GitHubはアカウントさえ作れば無料でも結構便利に使えるので、聞いたことがあるとか触ったことがあるという人は多いと思います。同じように無料から使えるSaaSのGitサーバーだと、GitLab SaaS版(gitlab.com)やBitBucketなどもあります。

Gitを勉強するだけであればGitのSaaSサービスのいずれかを使えばある程度できるのですが、一方でちょっと高度なことを試したいとか、インターネット上には置きたくないようなソースコードを管理したいときとか、なにか起きても誰にも迷惑がかからないようにオンプレミスの環境でGitサーバーを動かしてみたいということもあるかもしれません。これまで筆者はそういうときはオンプレミス版のGitLabを使っていました。

GitLabはソースコード管理以外にも、さまざまな機能を有しています。バージョンアップデートも比較的に頻繁にあります。きちんと管理できれば問題ありませんが、私のように雑にメンテナンスをしていると結構頻繁に環境が壊れたりします(バックアップを取っていればリカバリーできるのですが、...まあそういうことです)。

そこで、GitLab以外のオンプレミスで動くGitサーバーとして代表的なものをいくつか調べてみました。 この中でGiteaは過去に触ったことがありますし、そのフォークであるForgejoも触ったことがあります。 というわけで、今回はまださわったことがないGitbucketを試すことにしました。

ソフトウェア コメント
GitLab CI/CDも使えていいけど重量級。メンテが難しい(失敗すると壊れる)
Gitea 簡単セットアップ。過去のいざこざの件で将来性が不安
Forgejo Giteaのフォーク。使い勝手は一緒
Gitbucket Java製。簡単そう

Gitbucketの導入

GitBucketはGitHubで開発されており、そこからダウンロードできます。

サイトによると現時点では実行にJava 8が必要とのことです。 https://github.com/gitbucket/gitbucket

次のように実行するだけで、かんたんに実行できます。この後はLinuxディストリビューションの設定によっては、ファイアウォールの設定で8080ポートを開放する必要があります。クラウドのインスタンスで動かす場合は特別な方法でポート開放が必要だと思います。

sudo dnf install java-1.8.0-openjdk
mkdir .gitdir
cd .gitdir
curl -L "https://github.com/gitbucket/gitbucket/releases/download/4.38.4/gitbucket.war" -o gitbucket-4.38.4.war
java -jar gitbucket-4.38.4.war &

GitBucketをVirtualBoxのような仮想マシンで動かす場合は、Javaで動かすので最低4GB以上のメモリーを割り当ててください。vCPUは1もしくは2、ストレージは40GBくらいだといいと思います。

準備ができたら、ブラウザーで初期ユーザーでログインしてみましょう。

  • Go to: http://[hostname or IPアドレス]:8080/
  • log in with ID: root / Pass: root.

rootユーザーでログインしたら、普段使うアカウントを作成しておきましょう。作成した環境を常用する場合は、rootユーザーのパスワードも変更しておいたほうが良いでしょう。普段使うアカウントはユーザー権限と管理権限のあるユーザーを作成できますが、今回の作業では管理権限のあるユーザーとして作っておいてください。

Gitbucketにリポジトリーを作ってみる

いずれかのアカウントでログインしたら画面の右上の+ボタンをクリックすると、リポジトリーを作成できます。リポジトリー名や公開リポジトリーにするか、プライベートにするかなどを洗濯してリポジトリーを作成します。ここら辺はGitHubなどと一緒です。

この後、ソースコードをプッシュしたりリポジトリーソースをプルしたり...などもGitHubなどと使い勝手は同じです。 唯一違うところは、デフォルト設定のままではGitbucketのリポジトリー側に変更を加えるときに、ユーザー名とパスワードの入力が必要な点でしょうか。

GitbucketのバックエンドDBについて

GitbucketはデフォルトではH2 Databaseを利用しています。 次のようにMySQL 5.7以降やPostgreSQLを、バックエンドDBに設定できるようです。大規模で使うなら要検討かもしれません。 https://github.com/gitbucket/gitbucket/wiki/External-database-configuration

今回はデフォルト設定のままにします。

Let's Try

今回、おためしするために次のようなリポジトリーを用意しました。 https://github.com/ytooyama/first

これを自分のGitHubアカウントでフォークしておいてください (以降、 https://github.com/ytooyama/first.git となっている箇所は、自分のアカウントのクローンしたリポジトリーURLに置き換えて実行してください)。

フォークしたリポジトリーを手元の開発環境にクローンします。

git clone https://github.com/ytooyama/first.git

ソースコードを開発環境でクローンしたら、Python3がインストールされた環境で実行してみてください。 次のように表示されるはずです。

コードは単純に今年の西暦から生まれた年を引いて、今年何歳になるかを表示しているだけのコードです。

% python3 test.py
今年は 2023 年
Aさんは 42 歳

ではソースコードに新しい人を追加してみましょう。追加するのは自分でもこの例のようでも構いません。

from datetime import datetime

#今年の年を取得
current_year = datetime.now().year

#人を定義
a = current_year - 1981
dora = current_year - 2012

#結果表示
print('今年は', current_year, '年')
print('Aさんは', a, '歳')
print('ドラえもんは', dora, '歳')

実行してみましょう。

% python3 test3.py
今年は 2023 年
Aさんは 42 歳
ドラえもんは 11 歳

ドラえもんの生まれた年は2012年?

ドラえもんの誕生日はかつては2012年9月3日でした。 一方現在は2023年。私も知らなかったのですが、ドラえもんの誕生日は2012年9月3日からは2112年9月3日に変更されています(100年後に変更)。 100年後の日本や世界がどうなっているかはもはや知る由もないですが、今回のネタでは2012年としています。

GitHubにソースコードをコミット

自分のGitHubリポジトリーに変更をコミットしましょう。 Gitの基本操作についてはここでは詳しく説明しませんが、diffで変更前と変更後の差分を確認して、git addでステージングし、コミットにどういった変更をソースに行ったかメッセージを加えた後、ソースコードをプッシュします。

git diff
git add .
git commit --signoff -m "add dora"
git push -u origin main

--signoffオプションはコミットログメッセージの最後に、コミッターによるサインオフラインを追加するオプションです。サインオフの意味は、通常はコミッターが同じライセンスの下でこのワークを提出する権利を持っており、オリジナル証明書に同意することを証明します (Linux カーネルお​​よび Git プロジェクトで使用されるものについては、http://developercertificate.org を参照してください。) そのプロジェクトでサインオフがどのように使用されるかを理解するには、貢献しているプロジェクトのドキュメント等を参照してください。

ここまで実行すると、リポジトリーに新しい変更が加わったと思います。

GitBucketにGitHubリポジトリーのミラーを作ってみよう

まずGitBucketにログインして、firstという名前の空のリポジトリーを作っておいてください。

空のリポジトリーが作成されると、次のように表示されますが、そのままにしてください。

ミラークローンの作成

リポジトリのミラークローンを作成します。ミラー元として指定するリポジトリーは、自分のアカウントでフォークしたリポジトリーを指定してください。

git clone --mirror https://github.com/ytooyama/first.git
cd first.git

コピー先を追加

コピー先に指定するリポジトリーURLは、GitBucketにログインして自分のGitBucketアカウントで作った「first」という、空のリポジトリーです。 現時点では指定したリポジトリーには何もソースコードは含まれていないはずです。

git remote set-url --push origin http://172.16.214.196:8080/git/ytooyama/first.git

設定を確認するには次のように実行します。Fetchにはコピー元のソースURLが、Pushにはコピー先のソースURLが設定されています。

git remote show origin
* remote origin
  Fetch URL: https://github.com/ytooyama/first.git
  Push  URL: http://172.16.214.196:8080/git/ytooyama/first.git
  HEAD branch: main
  Remote branch:
    main tracked
  Local refs will be mirrored by 'git push'

ミラーしたクローンにはすべてのリモートブランチとタグが含まれますが、フェッチするたびにすべてのローカルの情報が上書きされるため、常に元のリポジトリと同じになります。 プッシュする URL を設定することで、ミラーへのプッシュが簡単になります。

ミラーを更新するには、更新をフェッチしてプッシュします。 これを実行すると、ソース元であるGitHub上のリポジトリーと同期されて、GitBucketのリポジトリーとGitHubのリポジトリーの内容が一緒になります。

git fetch -p origin
git push --mirror

git push --mirrorを実行すると、コピー元とコピー先のGitリポジトリーが同期されます。

git push --mirror
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 1.07 KiB | 1.07 MiB/s, done.
Total 7 (delta 0), reused 7 (delta 0), pack-reused 0
remote: Updating references: 100% (1/1)
To http://172.16.214.196:8080/git/ytooyama/first.git
 * [new branch]      main -> main

GitBucketのリポジトリーをみると、GitHubと同期されていることがわかります。 GitHub側のソースを書き換えたあと次のように実行すると、同様に同期されるはずです。

cd first.git
git fetch -p origin
git push --mirror

これで、万が一GitHubがサービスダウンしていても他のGitサーバー上で開発は継続できる環境ができました。今回はオンプレミスで構築したGitBucketを使っていますが、他のオンプレミス上のGitサーバーでも、他のSaaSのGitサーバーでも同様に対応できます。