🐧

Linux 使いになりたい人向けの Intel N100 ミニ PC で構築する開発環境(5)- Git リポジトリ管理システム

2024/02/08に公開

はじめに

これは、Linux 使いになりたい人向けに Intel N100 ミニ PC を使って開発環境を構築する方法を解説する記事の第5弾です。第1弾はLinux 使いになりたい人向けの Intel N100 ミニ PC で構築する開発環境(1) - 構築する開発環境について にあり、そこから第2弾へと続いています。そちらからご覧ください。

ここで使用する Intel N100 ミニ PC の仕様は次のものを前提とします。

項目 内容
OS Windows 11 Pro
CPU Intel N100
メモリ 16GB
ストレージ SSD 512 GB
画面出力端子 HDMI×2
WiFi 5G/2.4G
イーサネット RJ45×1
Bluetoot BT4.2
USB USB3.0×2/USB2.0×2

このマシンで最終的に Windows と Ubuntu Desktop が使えるように環境構築することを目指します。zenn.dev を購読している人のレベルを考えると、画面キャプチャはそれほど必要がないと考えているため少なめです。また、説明についても明示しないとわかりにくいと思われるものに絞っているので少なめです。

なお、実際に作業するときは、ネットワーク回線については数GBのデータをダウンロードしても問題ないものを使うようにしてください。作業の中には、数GBのデータをダウンロードするものも含まれてますので、テザリング環境では使用可能なパケットを使い切ってしまうこともあります。

試してみるソフトウェア

今回は Git リポジトリ管理システムを使ってみます。Hyper-V 仮想マシンで動作する Docker Desktop を使って、次のソフトウェアを動かしてみます。

ソフトウェア名 サイト ソースコード
Gitea https://about.gitea.com/ https://github.com/go-gitea/gitea
Forgejo https://codeberg.org/forgejo/forgejo https://codeberg.org/forgejo/forgejo

Git リポジトリ管理システム用のソフトウェア

Git リポジトリ管理システム用のソフトウェアは色々ありますが、ここでは次のものを取り上げます。

ソフトウェア名 サイト ソースコード
Gitea https://about.gitea.com/ https://github.com/go-gitea/gitea
Forgejo https://codeberg.org/forgejo/forgejo https://codeberg.org/forgejo/forgejo
GitBucket https://gitbucket.github.io/ https://github.com/gitbucket/gitbucket
GitLab CE https://about.gitlab.com/ https://gitlab.com/rluna-gitlab/gitlab-ce

これらのソフトウェアを使うと、クラウドサービスのバージョン管理システムである GitHub(https://github.co.jp/)のようなものを個人や組織で用意して提供することができます。

これらは、いずれもオープンソースのバージョン管理システムで、Git リモートリポジトリを Web インタフェースで管理できるソフトウェアで、Git リポジトリ管理システムと言います。なお、ライセンスについて、Forgejo と Gitea と GitLab は MIT License、GitBucket は Apache-2.0 license となっています。

Git は、オープンソースのソフトウェア開発において広く利用されているバージョン管理システムで、ファイルの変更履歴を管理したり、複数のマシンでコードを共有しながら開発をするための機能を提供します。一般的には複数人で共同で開発を行うときに使いますが、個人でも使うと便利なので自分は環境を構築して日常的に使っています。

ここに挙げたソフトウェアでは、いずれも Git の基本的な機能を Web ブラウザから操作できるようになっています。具体的な機能は、以下のとおりです。

  • ファイルの閲覧
  • 変更履歴の確認
  • バージョンごとの差分の表示
  • 課題管理
  • Wiki

このように、ファイルの閲覧や変更履歴の確認、バージョンごとの差分の表示などの基本的な機能はもちろん、課題管理(イシュー管理)や Wiki などの機能も備えています。

いずれも、Web ブラウザからアクセスして操作できるため、これらが提供する Git リモートリポジトリは、Git が使える Windows、macOS、Linux などの OS から利用できます。また、クラウド環境や LAN 環境など、さまざまな環境で利用できます。

ここからは、各ソフトウェアについて簡単に紹介します。

Gitea

Gitea の特徴は、以下のとおりです。

  • 単一バイナリで動作するため、インストールやメンテナンスが容易
  • 少ないコンピュータリソースで動作するため、低スペックな環境でも利用可能
  • 提供されている実行ファイルは Windows 版、Linux 版、macOS 版と Forge より多い
  • ビルド自動化
  • 通知

Forgejo

Forgejo の特徴は、以下のとおりです。Gitea と基本的に同じですが、こちらは提供されている実行ファイルが Linux 版のみとなります。

  • 単一バイナリで動作するため、インストールやメンテナンスが容易
  • 少ないコンピュータリソースで動作するため、低スペックな環境でも利用可能
  • 提供されている実行ファイルは Linux 版
  • ビルド自動化
  • 通知

GitBucket

GitBucket の特徴は、以下のとおりです。Forgejo や Gitea と基本的に同じですが、実行するには Java が必要です。

  • Java 実行環境が用意された Windows、Linux、macOS で実行可能
  • Java 実行環境でのインストールやメンテナンスが容易
  • 提供されている実行に必要なファイルは単一ファイル
  • Forgejo、Gitea よりも高いコンピュータ性能や必要なコンピュータリソースは多いが、比較的低スペックなコンピュータでも稼働可能
  • プラグインによるビルド自動化
  • 通知

GitLab CE

GitLab CE の特徴は、以下のとおりです。

  • 商用サービス版の GitLab EE のベースとなるソフトウェア
  • インストールは少し複雑だが、パッケージ管理システムによりメンテナンスは容易
  • 実行にあたっては専用の高性能マシンを推奨
  • ビルド自動化、CI/CD のための充実した機能
  • 通知

なお、GitLab CE は GitLab Inc. が開発・提供する https://gitlab.com/ というクラウドサービスで実際に使われている GitLab EE というソフトウェアのベースとなるソフトウェアです。Forgejo、Gitea、GitBucket と比較すると GitLab の利用者は多いため、開発の継続性については安心感があります。

使用するソフトウェアの選定について

Gitea、Forgejo、GitBucket、GitLab CE といった Git リポジトリ管理システムについて、簡単な紹介をしました。いずれも Web ブラウザから利用可能なインターフェースが用意されている Web システムです。

これらについて、実際に本格的な運用をしながら使えるようにするには、ネットワーク、Web サーバー、SSH サーバーの設定関連についての知識が必要になります。

とはいえ、それらの知識がつくまで使わないというのはもったいないです。どんな形であれ、バージョン管理システムが使える環境にしてから、開発というものはした方が良いですし、その際に課題管理や Wiki が使える環境にしておくのが望ましいです。

クラウドサービスで提供されているものを使うのも良いのですが、Linux が使えるようになりたい人で、ソフトウェアの開発者なら、プライベートな環境でも同じようなものが使えるようにしておきたいと思うはずです。

ここで、自分が Git リポジトリ管理システムを本格的に稼働させるなら Linux マシンを使いますが、これから Linux 使いになりたいというレベルの人の場合は、最初の一歩としては、Windows マシンで動かせるもので環境を用意するのが良いと考えています。

「個人で使える環境で良い」と割り切れるなら、Windows マシンで Git リポジトリ管理システムを稼働させるということで大丈夫です。Windows で稼働させるとなると、Windows へインストールできる Gitea を選択するのが良さそうです。お試し用の環境として Win11Eval 仮想マシンがあるので、そこへ Gitea をインストールして使えるか検討するという方針としましょう。

ただし、本当に Linux 使いになりたい人の場合は、Linux マシンで Git リポジトリ管理システムを稼働できるようになりたいしょう。そういった場合は、Linux で Git リポジトリ管理システムを動かす方法が知りたいはずです。

Linux マシンを用意するのは大変ですが、すでに用意してある環境には、Linux の仮想マシンに相当する WSL2 と、コンテナー実行用の Docker Desktop があります。

今回紹介したものは、いずれも Docker 用のイメージがあるので、試すだけなら、そちらを先に使った方が良さそうです。使うことがわかっていて Linux に慣れているなら、WSL2 へインストールするのが良いですが、Linux に慣れていなくて試すということなら Docker の方が適しています。

以上のことを考慮すると、順番としては、先に Docker Desktop で Git リポジトリ管理システムを試しに動かしてみてから、実際に試用するものを Windows 評価環境へインストールするということにしましょう。

本格的に利用する前に Windows 評価環境へインストールして試用するのは時間をかけすぎだと思うかもしれませんが、まだよく知らないサーバーソフトウェアを使うときは、これぐらいのんびりやっていくのが良いです。こうやって無理せずに少しずつステップアップしながら、少しずつできることを増やしていくのが、サーバー系ソフトウェアの運用ができるようになるコツです。

ところで、Docker Desktop は試用のために使い、手軽に利用できます。「個人で使える Git リポジトリ管理システムの環境を Windows に用意する」という目的を考えると Gitea だけ試せば良いのですが、せっかくなので、もうひとつ別のものも動かしてみたいところです。ということで、ここでは Gitea に近い Forgejo を動かしてみます。両方とも動かしてみて、どれぐらい似ているのか確認してみましょう。

なお、説明の分量の都合上、今回は Docker Desktop で Gitea と Forgejo を動かすところまで説明します。Gitea を Windows へインストールするのは次回となります。

Git リポジトリ管理システムの試用

それでは、Docker Desktop で Git リポジトリ管理システムの Gitea と Forgejo を利用してみましょう。

Docker Compose

ここでは、Docker Compose という「複数の Docker コンテナーを管理しやすくするためのもの」を使います。これを使うと、コンテナーで実現する環境が docker-compose.yml というファイルで表現できるようになり、このファイルをバージョン管理することで、実行環境のバージョン管理ができるようになります。

そういったメリットがあるので、自分は Docker Compose を積極的に使うようにしています。また、Docker Compose を使うと、Docker コンテナーの利用が簡単にできるようになります。さらに、Docker コンテナーの利用が終わった後に必要な、コンピューターを元の状態に戻すための作業も簡単になります。

ここでは、Docker Compose について、詳しい説明はしませんが、より深く知りたい場合は、それらについて説明している 公式サイトの Docker Compose を有志が翻訳した日本語ドキュメント などの Web ページ、書籍、記事といったものを参考にしてください。

ここで使用する Docker Compose 用の docker-compose.yml ファイルについては、次のようなディレクトリー構成でよういします。

/c/Users/User/workspace/docker/
├── forgejo/                ← Forgejo 用
│   └── docker-compose.yml
└── gitea/                  ← Gitea 用
    └── docker-compose.yml

これらを使って Gitea と Forgejo を試用してみます。

Git Bash

ここでは、Docker Compose 用のコマンドを使って Docker コンテナーを実行するのですが、その際には、Git Bash を使うことにします。Linux を使えるようになりたい人なら、Bash に慣れたほうが良いからです。

Git Bash ではファイルパスが Linux で使われているパス表現へ自動変換される環境となっています。そのため、例えば Windows の C:\Users\User\workspace\docker というファイルパスは /c/Users/User/workspace/docker/ のファイルパスで表現されます。

なお、ファイルパスは Windows の場合はドライブがあったり、パス区切りが \ になっていますが、最近のコンピューターでは <スキーマ>://<パス> でリソースの場所を表現する URL を使ってファイルパスを表現することも多いです。URL でファイルパスを表現するときは、スキーマが file となり、パスにはファイルパスを指定するので、file://<ファイルパス> のように表現することになります。このときのパスは / で区切るので、先程の Windows の C:\Users\User\workspace\docker というファイルパスに対応するものは file:///c/Users/User/workspace/docker/ と書くことになります。

こういったこともあるので、ここではファイルパスのパス区切りは / を使うことにします。URL で表現することにしても良いのですが、その場合は file:// が先頭について冗長になるだけなので、通常は省略することにして、必要な場合はスキーマの部分も指定します。

Gitea と Forgejo を動かすには Docker Desktop を実行している必要があります。Docker Desktop を開いてから「Gitea の Docker イメージの利用」以降の作業をしてください。なお、Docker Desktop を開く際にはコンピューターの変更を許可する必要があります。許可のための画面が表示されたら「はい」をクリックします。

Gitea の Docker イメージの利用

Gitea の Docker イメージは Docker Hub の gitea/gitea で公開されています。使い方は Gitea サイトの Documentation にある Installation with Docker に説明されています。

ここでは、gitea というサービス名で gitea コンテナーを動かし、データは gitea-data ボリュームへ保存して永続化し、ネットワークとして gitea-net ネットワークを利用することにします。

Docker を知らない人からすると何を言っているかわからないかもしれませんが、要するに「コンテナーに必要なストレージとネットワークについて、名前をつけて用意して使います」ということです。

これを実現するには、次のような gitea/docker-compose.yml ファイルを用意します。

gitea/docker-compose.yml
name: gitea

services:
  gitea:
    image: gitea/gitea:1.21.4
    container_name: gitea
    hostname: gitea
    restart: always
    volumes:
      - gitea-data:/data
    networks:
      - gitea-net
    ports:
      - "127.0.0.1:3000:3000"
      - "127.0.0.1:2222:22"
    environment:
      - USER_UID=1000
      - USER_GID=1000

volumes:
  gitea-data:
    name: gitea-data

networks:
  gitea-net:
    name: gitea-net

このファイルで定義した gitea サービスを起動すると、Gitea が使えるようになります。なお、gitea サービスは gitea コンテナーが提供するサービスなので、gitea サービスを起動すると gitea コンテナーが起動します。

gitea サービスを起動するには、Git Bash を開いて、このファイルを置いた gitea ディレクトリーをカレントとして docker compose up コマンドを実行します。

cd ~/workspace/docker/gitea/
docker compose up

実際に実行した場合の結果は次のようになります。

/images/20240202_gitea/gitea-01.png
Docker で Gitea の起動

Server listening on 0.0.0.0 port 22. や、Starting new Web server: tcp:0.0.0.0:3000 といった出力メッセージからわかるように、gitea コンテナーは、ポート番号の 22 と 3000 でネットワークアクセスの待機をします。22 は SSH 用で、3000 は HTTP 用のものになります。

ここで、Gitea のサービスは起動していますが、まだ初期設定が済んでいないので実際に使うことは、まだできません。初期設定をするためには、ブラウザから http://localhost:3000/ にアクセスして作業します。

ちなみに、ブラウザから http://localhost:3000/ にアクセスすれば良いというのは、docker-compose.yml からわかります。このファイルでは ports: の指定で、ホスト OS のポート番号 2222 を gitea コンテナーの 22、ホスト OS のポート番号 3000 を gitea コンテナーの 3000 へ転送する指定をしてあります。そのため、Gitea へ HTTP でアクセスするにはホスト名を localhost とし、ポート番号は 3000 を指定すれば良いことがわかります。

Gitea のインストールとログイン

Web ブラウザで Gitea へアクセスすると、初期設定の画面が表示されます。

/images/20240202_gitea/gitea-02.png
Gitea の初期設定画面

ここでは初期値のまま「Gitea をインストール」をクリックしてインストールします。こうすると、初期の管理者ユーザーがいない状態でインストールされます。インストール後に、ユーザーを登録することができて、最初に登録されたユーザーが管理者となります。

インストールが完了すると自動でログインの画面になります。

/images/20240202_gitea/gitea-03.png
Gitea のログイン画面

タブにある「アカウントを登録」をクリックすると、アカウントの登録画面となります。必要な項目を入力して「アカウントを登録」をクリックします。次の例では user001 を登録しています。

/images/20240202_gitea/gitea-04.png
Gitea のアカウント登録画面

アカウントを登録すると、そのアカウントでログインしてダッシュボードの画面になります。

/images/20240202_gitea/gitea-05.png
Gitea のダッシュボード画面

Gitea で新規リポジトリ作成

最初にリポジトリを作成してみましょう。画面の「+」をクリックすると表示されるメニューで「新しいリポジトリ」をクリックします。

/images/20240202_gitea/gitea-06.png
Gitea で新しいリポジトリを作成

新しいリポジトリを作成する画面が表示されるので、リポジトリ名を入力します。また、「公開/非公開」の欄はチェックをいれてプライベートなリポジトリとします。設定を間違えて Git リポジトリ管理システムが他のマシンからも参照できる状態となってしまったとしても、このように指定しておけば公開されません。

次の例ではリポジトリ名に「proj001」を指定しています。

/images/20240202_gitea/gitea-07.png
Gitea の新しいリポジトリを作成する画面1

新しいリポジトリを作成する画面では、さらに「リポジトリの初期設定」の欄もチェックします。こうしておくと、Git リポジトリを使うときによく用意されるファイルが自動で作られます。

/images/20240202_gitea/gitea-08.png
Gitea の新しいリポジトリを作成する画面2

それから「リポジトリを作成」をクリックすると、リポジトリが作成され、画面の URL は http://localhost:3000/user001/proj001 へ遷移します。

/images/20240202_gitea/gitea-09.png
Gitea のリポジトリの画面

リポジトリの URL は HTTP 版は http://localhost:3000/user001/proj001.git となります。この URL を使った Git クローンの方はできるようになっています。

なお、リポジトリの URL を SSH とすると git@localhost:user001/proj001.git となります。

/images/20240202_gitea/gitea-10.png
Gitea SSH のリポジトリの URL

ここで、docker-compose.yml では、ポート番号の設定について 2222:22 としてあったので、この URL では SSH 接続ができません。そのため、このままでは SSH での Git クローンができません。これを解決するための設定は後ですることにします。

Gitea のリポジトリをクローン

それでは、Gitea のリポジトリをクローンしてみましょう。

ここでは Docker ホストのマシンの Git Bash で、カレントディレクトリーを ~/worksapce として、proj001 のリモートリポジトリをクローンします。

cd ~/workspace
git clone http://localhost:3000/user001/proj001.git

このとき、Windows では Git Credential Mangaer (GCM) が起動して、このアプリケーションが Gitea にログインしているアカウントへアクセスすることを許可するための画面が Web ブラウザで表示されます。GCM は Git のリモートリポジトリを使う時の認証情報を管理するためのソフトウェアで Git for Windows に含まれているものです。

/images/20240202_gitea/gitea-11.png
アカウントへのアクセスをアプリケーションへ許可する画面

「アプリケーションを許可」をクリックすると、Web ブラウザに「Authentication successsful」の画面が表示されます。

/images/20240202_gitea/gitea-12.png
Authentication successsful の画面

このように許可されたアプリケーションは、http://localhost:3000/user/settings/applications で表示できる Gitea の user001 の設定画面で確認できます。「アプリケーション」を開いて「許可済み OAuth2 アプリケーション」に「Git Credential Manager」が登録されているはずです。

/images/20240202_gitea/gitea-13.png
許可済み OAuth2 アプリケーション

このように GCM を使った認証を許可すると、きちんとクローンができます。

実際に実行した際の Git Bash の画面の方は、次のようになります。警告が出ていますが、クローンは成功しています。

User@WinDev2401Eval MINGW64 ~/workspace
$ git clone http://localhost:3000/user001/proj001.git
Cloning into 'proj001'...
warning: auto-detection of host provider took too long (>2000ms)
warning: see https://aka.ms/gcm/autodetect for more information.
warning: auto-detection of host provider took too long (>2000ms)
warning: see https://aka.ms/gcm/autodetect for more information.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

警告が出ているのは、接続先の Git リポジトリ管理システムを自動で検出しようとしていて、その処理に時間がかかっているからです。次のコマンドを実行することで、解消します。

git config --global credential.localhost:3000.provider generic

Windows 資格情報

Gitea へ GCM のアプリケーションの登録がされましたが、そのときに使った http://localhost:3000 の Gitea へアクセスするための認証情報は Windows へ保存されています。これについても意識しておいた方が良いので簡単に説明しておきます。

この情報は、Windows の「コントロール パネル」-「ユーザー アカウント」-「資格情報マネージャー」-「Windows資格情報」で確認することが出来ます。git:http://localhost:3000git:http://refresh_token.localhost:3000 の2つが登録されたものになります。

/images/20240202_gitea/gitea-14.png
Windows 資格情報

これらを削除すると Gitea へアクセスするための認証情報がなくなってしまうので、認証が失敗するようになります。

なお、Git Bash で認証情報について確認することもできます。その場合は git credential-manager get コマンドを使います。

例えば、http://localhost:3000 の認証情報を確認するには、次のコマンドを実行します。

git credential-manager get << EOS
protocol=http
host=localhost:3000
EOS

結果は次のようになります。

protocol=http
host=localhost:3000
username=OAUTH_USER
password=eyJhbGciOiJSUzI1NiIsImtpZCI6IldVRnlmY(略)

Gitea の設定ファイル

Gitea の設定ファイルは gitea コンテナー内の /data/gitea/conf/app.ini にあります。コンテナー内のファイルを示すには コンテナー名:ファイルパス と表現することが多いので、ここでもそうします。つまり、gitea:/data/gitea/conf/app.ini と表記したら、gitea コンテナー内の /data/gitea/conf/app.ini を意味します。

さて、Docker コンテナーにあるファイルの app.ini を編集する方法はいくつかあります。どの程度の編集をするのかにもよりますが、自分は次のどれかを使うことが多いです。

  • コンテナーへアタッチして sed コマンドを使った文字列置換で編集
  • コンテナーへアタッチして bash を起動し、そこで vi コマンドを使って編集
  • docker compose cp コマンドを使ってファイルコピーをして編集

他には、VS Code の DevContainers 拡張機能を使って編集するという方法もあります。

コンテナーへアタッチして sed コマンドを使った文字列置換で編集

コンテナーへアタッチして sed コマンドでファイルを編集する場合は次のようにします。

upadte_app_ini.sh
docker compose -p <プロジェクト名> exec <サービス名> \
  bash -c 'sed -i "s/<置換前文字列>/<置換後文字列/>" <ファイルパス>'

ここでは、SSH クローンができるように設定ファイルを編集するにあたって、この方法を使ってみましょう。これについては、sed コマンドで簡単に置換できます。

具体的には app.ini で指定されている SSH_PORT の値を、docker-compose.yml の指定に合わせて 2222 へ変更します。

次の upadte_app_ini.sh スクリプトでは、gitea コンテナー上で sed コマンドを使って app.ini ファイルの SSH_PORT = 22 の文字列を SSH_PORT = 2222 へ置換しています。さらに、gitea コンテナー上で cat コマンドと grep コマンドをパイプラインの | を使って組み合わせて、app.ini ファイル内の SSH を含む行の表示をすることで、置換結果の確認をしています。

upadte_app_ini.sh
docker compose -p gitea exec gitea bash -c 'sed -i "s/SSH_PORT = 22/SSH_PORT = 2222/" /data/gitea/conf/app.ini'
docker compose -p gitea exec gitea bash -c 'cat /data/gitea/conf/app.ini | grep SSH'

これを実行すると、gitea コンテナーの SSH を使う場合のクローンパスの URL に 2222 が含まれるようになり、SSH を使ったクローンができるようになります。

sh ./update_app_ini.sh

実際に実行すると次の結果となります。

User@WinDev2401Eval MINGW64 ~/workspace/docker/gitea
$ sh update_app_ini.sh
SSH_DOMAIN = localhost
DISABLE_SSH = false
SSH_PORT = 2222
SSH_LISTEN_PORT = 22

SSH_PORT の値が 2222 となっていることがわかります。

この方法で編集してみたときに、失敗して変な結果となってしまった場合は、他の方法を使って修正してください。

コンテナーへアタッチして bash を起動し、そこで vi コマンドを使って編集

この方法は vi コマンドが使える前提のものとなります。vi コマンドの使い方を知らない場合は他の方法を使ってください。

コンテナーへアタッチして bash を起動し、そこで vi コマンドを使ってファイルを編集する場合は次のようにします。

docker compose -p <プロジェクト名> exec <サービス名> bash
vi <ファイルパス>

今回用意した gitea コンテナーの /data/gitea/conf/app.ini ファイルを編集する場合の例は次のようになります。

docker compose -p gitea exec gitea bash
vi /data/gitea/conf/app.ini

docker compose cp コマンドを使ってファイルコピーをして編集

docker compose cp コマンドを使ってファイルコピーをして編集する場合は、次のようにします。

docker compose -p <プロジェクト名> \
  cp <コピー元のファイルのパス> <コピー先のファイルのパス>

Docker コンテナーから Docker ホストへコピーしたファイルを、ホストで動作するエディタで編集してから、Docker ホストから Docker コンテナーへコピーして戻します。

具体的な例としては次のようになります。この例では、最後に app.ini ファイルがコピーされたことを確認する ls コマンドの実行を追加してあります。

User@WinDev2401Eval MINGW64 ~
$ cd ~/workspace/docker/gitea/

User@WinDev2401Eval MINGW64 ~/workspace/docker/gitea
$ docker compose -p gitea cp gitea:/data/gitea/conf/app.ini .
[+] Copying 1/0
 ✔ gitea copy gitea:/data/gitea/conf/app.ini to . Copied                                                           0.0s

User@WinDev2401Eval MINGW64 ~/workspace/docker/gitea
$ ls
app.ini  docker-compose.yml

app.ini を編集したら、gitea コンテナーへコピーして反映します。そのときに使う具体的なコマンドは次のようになります。

docker compose -p gitea cp app.ini gitea:/data/gitea/conf/

Gitea 設定変更の反映

変更内容を反映するには、gitea コンテナーの再起動が必要です。docker compose up コマンドを実行しているターミナルとは別に Git Bash のターミナルを開いて、docker compose down コマンドで gitea コンテナーを停止します。

docker compose down コマンドで -p オプションを指定すると、Docker Compose のプロジェクト名を使ってサービスの停止ができます。ここではプロジェクト名は gitea となっているので、次のコマンドとなります。

docker compose -p gitea down

実際のコマンド実行結果は次のようになります。

User@WinDev2401Eval MINGW64 ~/workspace/docker/gitea
$ docker compose -p gitea down
[+] Running 2/2
 ✔ Container gitea    Removed                                                                                      1.4s
 ✔ Network gitea-net  Removed                                                                                      0.5s

次に docker compose up コマンドを実行しているターミナルへ戻ると、コマンドが停止しているはずです。再度 docker compose up コマンドを使って gitea サービスを起動します。

Gitea の SSH 関連の設定確認

それから、Gitea へログインしてから http://localhost:3000/admin/config を開いて管理設定を確認してみましょう。

/images/20240202_gitea/gitea-15.png
Gitea の設定1

下の方に SSH の設定があります。ポートが 2222 となっていれば成功です。

/images/20240202_gitea/gitea-16.png
Gitea の設定2

今度は、SSH クローンのための URL を確認してみましょう。ssh://git@localhost:2222/user001/proj001.git となっているはずです。

/images/20240202_gitea/gitea-17.png
SSH クローンのための URL

SSH

Gitea で SSH クローンのための設定が終わったので、SSH クローンを試してみましょう。

SSH キーペアの作成

Git Bash で Gitea 用の SSH キーペアを作成します。コマンドは ssh-keygen コマンドを使います。

ssh-keygen -t <タイプ> -f <キーのパス> -C <コメント>

ここでは、キーのタイプに ed25519 を指定し、キーのパスには ~/.ssh/id_ed25519_gitea、コメントには "User@Win11Eval" を指定することにします。

実行すると、パスフレーズの入力を求められます。パスフレーズは、このキーペアを使う時に要求される文字列になります。推測されにくいものを指定します。確認のためにパスフレーズは2回指定が必要です。

キーが生成されると、キーのファイルがペアで生成されます。それぞれのファイルパスは ~/.ssh/id_ed25519_gitea~/.ssh/id_ed25519_gitea.pub になります。

コマンド実行例を次に示します。

User@WinDev2401Eval MINGW64 ~/workspace
$ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_gitea -C "User@Win11Eval"
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/User/.ssh/id_ed25519_gitea
Your public key has been saved in /c/Users/User/.ssh/id_ed25519_gitea.pub
The key fingerprint is:
SHA256:8TG4sMiu4rUQhxlG5DglBYuf1AGe1ofqbSxqxWYFsaQ User@Win11Eval
The key's randomart image is:
+--[ED25519 256]--+
|+=++o            |
|==o=.o   .       |
|=E=.= o o o      |
|.=++ + o + o     |
| +=.+ . S .      |
| .oO             |
| .*.=            |
|.oo+.            |
|+o..             |
+----[SHA256]-----+

User@WinDev2401Eval MINGW64 ~/workspace
$ ls -l ~/.ssh
total 2
-rw-r--r-- 1 User 197121 411 Feb  2 22:47 id_ed25519_gitea
-rw-r--r-- 1 User 197121  96 Feb  2 22:47 id_ed25519_gitea.pub

ファイル名に pub がついている方が公開鍵で、ついていない方が秘密鍵になります。公開鍵の ~/.ssh/id_ed25519_gitea.pub の内容を表示して確認しておきます。

$ cat ~/.ssh/id_ed25519_gitea.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8y1Xi6eEBXD2L4WPz9Kyp/MFYEtOt8rJJ0q5u/Z402 User@Win11Eval

この SSH 用の公開鍵の文字列をコピーして Gitea へ登録すると、SSH を使った Git クローンが使えるようになります。

接続先のホストのフィンガープリント

SSH を使った Git クローンをするには、接続先のホストについてフィンガープリントを確認して、~/.ssh/known_hosts ファイルへ登録しておく必要があります。

フィンガープリントの確認をするには、ssh コマンドを実行して、localhost:2222 へアクセスします。

なお、接続先のホストのフィンガープリントは gitea:/data/ssh/ にあります。使用する暗号化方式に応じて次のようなファイルがあります。

  • ssh_host_ecdsa_key.pub
  • ssh_host_ed25519_key.pub
  • ssh_host_rsa_key.pub

ファイルの内容は、次のようにして確認できます。

$ docker compose -p gitea exec gitea \
    bash -c 'cat /data/ssh/ssh_host_ed25519_key.pub'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOApKbWtQcwR6(略)root@gitea

フィンガープリントは、これらのファイルを使って生成されるので、自分が使う秘密鍵に応じてフィンガープリントを確認しておきます。

docker compose -p gitea exec gitea \
  bash -c 'ssh-keygen -lf /data/ssh/ssh_host_ed25519_key.pub'

実行結果は次のようになります。

256 SHA256:WbHna1DLsODv5GOjrbFxjHPtBR/sNm0ulEQCiZsLx90 root@gitea (ED25519)

この例だと、暗号化方式に ed25519 を使う場合のフィンガープリントが SHA256:WbHna1DLsODv5GOjrbFxjHPtBR/sNm0ulEQCiZsLx90 だということがわかります。

フィンガープリントの登録

ssh コマンドは、-p オプションでポート番号の指定ができます。また、接続で使うユーザー名とホスト名は <ユーザー名>@<ホスト名> のフォーマットでパラメーターに指定します。

ssh -i <秘密鍵のパス> -p <ポート番号> <ユーザー名>@<ホスト名>

gitea コンテナーへ SSH で接続するには次のようにします。

ssh -i ~/.ssh/id_ed25519_gitea -p 2222 git@localhost

これを実行すると、SSH ホストのフィンガープリントと、Are you sure you want to continue connecting (yes/no/[fingerprint])? のプロンプトが表示されます。フィンガープリントが一致していることを確認してからプロンプトに対して yes を入力し、続いて Enter キーを入力します。

シェルを使ってリモートで作業をするわけではないので、ここでの接続自体は git@localhost: Permission denied (publickey). と権限がなくて失敗となりますが、これでフィンガープリントを使った検証が自動で行われるようになり、gitea の SSH クローンができるようになります。

コマンド実行時の結果をまとめると、次のようになります。

User@WinDev2401Eval MINGW64 ~/workspace
$ ssh -i ~/.ssh/id_ed25519_gitea -p 2222 git@localhost
The authenticity of host '[localhost]:2222 ([127.0.0.1]:2222)' can't be established.
ED25519 key fingerprint is SHA256:WbHna1DLsODv5GOjrbFxjHPtBR/sNm0ulEQCiZsLx90.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:2222' (ED25519) to the list of known hosts.
git@localhost: Permission denied (publickey).

このコマンドの実行により、~/.ssh/known_hosts ファイルが作成されて、ここに SSH ホストのフィンガープリントが保存されます。

User@WinDev2401Eval MINGW64 ~/workspace
$ ls -l ~/.ssh/known_hosts
-rw-r--r-- 1 User 197121  98 Feb  2 11:50 known_hosts

Gitea へ SSH キーを登録

それでは、Gitea へログインしてから http://localhost:3000/user/settings/keys を開いて、SSH キーの登録をします。

「キー名」には、公開鍵のコメントと同じにしておくとわかりやすいでしょう。Gitea で区別がつけば良いので、他の文字列にしてもかまいません。

/images/20240202_gitea/gitea-18.png
SSH キーの登録

「キーを追加」をクリックすると、SSH キーが追加されます。

/images/20240202_gitea/gitea-19.png
登録された SSH キー

Gitea リポジトリの SSH クローン

それでは Gitea リポジトリを SSH クローンしてみましょう。

使用する SSH の秘密キーを指定するには、-c オプションをつけた git コマンドを実行します。

git clone -c "core.sshCommand=ssh -i <秘密鍵のパス> -F /dev/null" \
  <リポジトリの SSH URL>

ここでは、~/.ssh/id_ed25519_gitea の秘密鍵を使って、ssh://git@localhost:2222/user001/proj001.git の URL から Git リポジトリをクローンするので、コマンドは次のようになります。

git clone -c "core.sshCommand=ssh -i ~/.ssh/id_ed25519_gitea -F /dev/null" \
  ssh://git@localhost:2222/user001/proj001.git

この例を実際に実行すると、次のような結果となります。

User@WinDev2401Eval MINGW64 ~/workspace
$ git clone -c "core.sshCommand=ssh -i ~/.ssh/id_ed25519_gitea -F /dev/null" \
  ssh://git@localhost:2222/user001/proj001.git
Cloning into 'proj001'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

これで Gitea の設定についての説明はおしまいです。Docker を使って Gitea を試して使える環境を用意することができました。

Forgejo の Docker イメージの利用

次に Forgejo を使ってみましょう。基本的に Gitea と同じ環境を用意することにして、サービス、コンテナー、ボリューム、ネットワークの名前を gitea から forgejo へ変更したものを用意します。これを実現するには、次のような forgejo/docker-compose.yml ファイルを用意します。

Docker ホスト側のポート番号について、HTTP については Gitea とは違うポート番号としてみました。SSH については同じポート番号を指定してあるので、Gitea と同時に起動して使うことはできません。設定を調整することで、両方を同時に稼働させることができますが、ここでは起動するときはどちらか片方だけという使い方を想定したものにしています。

Docker で Gitea を動かしてみて、インストール手順がわかっているので、後の設定が楽になることを期待して、ここでは docker-compose.yml のポート指定について、工夫をすることにしました。

HTTP では 13000 を使い、SSH では 2222 を使うことにして、初期設定時に、これらのポートを指定するようにします。注意点としては、使用する Docker イメージは、最初の初期設定画面を表示する際にはポート番号 3000 を使う設定となっているので、ポート番号 3000 の設定もしておく必要があります。

以上のことを考慮して作成した docker-compose.yml は次のようになります。

forgejo/docker-compose.yml
name: forgejo

services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:1.20
    container_name: forgejo
    hostname: forgejo
    restart: always
    volumes:
      - forgejo-data:/data
    networks:
      - forgejo
    ports:
      - "127.0.0.1:3000:3000"
      - "127.0.0.1:13000:13000"
      - "127.0.0.1:2222:2222"
    environment:
      - USER_UID=1000
      - USER_GID=1000

volumes:
  forgejo-data:
    name: forgejo-data

networks:
  forgejo-net:
    name: forgejo-net

このファイルで定義した forgejo サービスを起動してから初期設定をすると、Forgejo が使えるようになります。

forgejo サービスを起動するには、Windows ターミナルで Git Bash を開いて、このファイルを置いた forgejo ディレクトリーをカレントとして docker compose up コマンドを実行します。なお、ここでは、-d オプションを指定して、forgejo サービスをバックグラウンドで起動しています。

cd forgejo
docker compose up -d

少し待ってから、ブラウザから http://localhost:3000/ にアクセスすると初期設定の画面になります。画面が表示されない場合は、ログを確認してみましょう。docker compose logs コマンドで確認して、Forgejo が起動するまで待ちます。

docker compose -p forgejo logs

初期設定の画面が表示できたら、初期設定を指定します。このとき、ポート番号については Gitea とは違った指定をすることにします。HTTP については 13000、SSH については 2222 を指定しましょう。URL についても http://localhost/3000 となっているところは http://localhost/13000 へ変更が必要です。

/images/20240202_gitea/forgejo-01.png
Forgejo 初期設定の画面

他の指定内容については Gitea と変わりません。インストール後に最初に登録したアカウントが管理者となるのも同じです。

注意点としては、インストールが終わっても自動で http://localhost:13000/ は開きません。

/images/20240202_gitea/forgejo-02.png
Forgejo インストール中の画面

自分で http://localhost:13000/ を Web ブラウザで開く必要があります。インストールが無事終了していたら、Forgejo の画面が表示されます。

/images/20240202_gitea/forgejo-03.png
Forgejo の画面

後は、Gitea のときと同じようにアカウントを登録します。

/images/20240202_gitea/forgejo-04.png
Forgejo のアカウント登録画面

アカウントを登録するとサインインしてダッシュボード画面になります。Gitea と同じです。

/images/20240202_gitea/forgejo-05.png
Forgejo のダッシュボード画面

それから、SSH のキーを登録しておきましょう。キーペアは Gitea 用に作ったものをそのまま使って良いでしょう。別にしたい場合は、キーのパスを変更して作成したものを使うようにしてください。

さて、ここでシステムの環境設定を確認してみたところ、SSH のビルトインサーバーが起動していませんでした。また、SSH サーバーが待機するポートが 22 となっていました。Forgejo の初期設定ではビルトインサーバーの自動起動は無効になっていて、待機ポートは 22 になっているようです。

次は、これについて修正しましょう。

Forgejo の SSH ビルトインサーバーの有効化

Forgejo の SSH ビルトインサーバーの有効化するには、START_SSH_SERVER = true の設定を app.ini ファイルへ追加します。

また、docker-compose.yml で指定したコンテナー内の SSH 用の待機ポート番号は 2222 なので、それに合わせて SSH_LISTEN_PORT = 22SSH_LISTEN_PORT = 2222 へ変更する必要もあります。

ここでは、それらの設定を修正するためのスクリプト update_forgejo_app_ini.sh を用意します。SSH_LISTEN_PORT = 22SSH_LISTEN_PORT = 2222 へ置換するのと、START_SSH_SERVER = true の設定を DISABLE_SSH = の前に追加する処理となっています。

update_forgejo_app_ini.sh の内容は次のようになります。

update_forgejo_app_ini.sh
docker compose -p forgejo exec forgejo bash -c 'sed -i "s/^SSH_LISTEN_PORT = 22$/SSH_LISTEN_PORT = 2222/" /data/gitea/conf/app.ini'
docker compose -p forgejo exec forgejo bash -c 'sed -i "s/^DISABLE_SSH =/START_SSH_SERVER = true\nDISABLE_SSH =/" /data/gitea/conf/app.ini'
docker compose -p forgejo exec forgejo bash -c 'cat /data/gitea/conf/app.ini | grep SSH'

このスクリプトでは、update_app_ini.sh とちがって sed コマンドの文字列マッチング時に正規表現を使っています。^ は行頭を意味して $ は行末を意味します。つまり、^SSH_LISTEN_PORT = 22$ は、該当する行の文字列が SSH_LISTEN_PORT = 22 となっている場合にヒットします。SSH_LISTEN_PORT = 22 だと、これを含む文字列であればヒットしてしまうため、例えば SSH_LISTEN_PORT = 2222 もヒットしてしまいます。

なお、START_SSH_SERVER = true\nDISABLE_SSH = に出てくる \nsed コマンドで LF(ラインフィード)の改行コードを意味します。これをつけることで、START_SSH_SERVER = true の後が改行がされます。

実際に実行した時の結果は次のようになります。

User@WinDev2401Eval MINGW64 ~/workspace/docker/forgejo
$ sh update_forgejo_app_ini.sh
SSH_DOMAIN = localhost
START_SSH_SERVER = ture
DISABLE_SSH = false
SSH_PORT = 2222
SSH_LISTEN_PORT = 2222

変更した設定の反映にはforgejo サービスの再起動が必要です。docker-compose.yml ファイルの修正もするので、ここでは停止します。

docker compose down

forgejo サービスの設定変更と起動

docker-compose.yml ファイルで指定したポート番号 3000 の設定は初期設定時にしか必要ないので、次のようにコメントにします。

forgejo/docker-compose.yml
name: forgejo

services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:1.20
    container_name: forgejo
    hostname: forgejo
    restart: always
    volumes:
      - forgejo-data:/data
    networks:
      - forgejo
    ports:
      #- "127.0.0.1:3000:3000"
      - "127.0.0.1:13000:13000"
      - "127.0.0.1:2222:2222"
    environment:
      - USER_UID=1000
      - USER_GID=1000

volumes:
  forgejo-data:
    name: forgejo-data

networks:
  forgejo-net:
    name: forgejo-net

それから、Forgejo を起動します。

docker compose up -d

http://localhost:13000 を開いて、サインインします。それから、リポジトリを作成します。ここでは proj001-forgejo を作成したとします。

Forgejo のリモートリポジトリの利用

リポジトリ proj001-forgejo を作成したら、Gitea と同様にして Git クローンを試してみましょう。

git clone http://localhost:13000/user001/proj001-forgejo.git

このとき、Gitea では「許可済み OAuth2 アプリケーション」に「Git Credential Manager」が登録される処理が動きましたが、Forgejo では認証情報を入力する画面が表示されました。Forgejo へログインするときに使う認証情報を指定します。

/images/20240202_gitea/forgejo-06.png
認証情報を入力する画面

これで、proj001-forgejo リポジトリーがクローンできます。

なお、認証情報については、Windows の「コントロール パネル」-「ユーザー アカウント」-「資格情報マネージャー」-「Windows資格情報」で確認することが出来ます。git:http://localhost:13000 が登録されたものになります。

/images/20240202_gitea/forgejo-07.png
git:http://localhost:13000 の Windows 資格情報

Forgejo のリモートリポジトリを SSH クローン

次に、Forgejo のリモートリポジトリを SSH クローンしてみましょう。HTTP を使ってクローンした proj001-forgejo リポジトリーがある場合は消しておきます。

rm -fr proj001-forgejo

最初に、Gitea の SSH ホストのフィンガープリントを削除しておきます。Gitea のときとホスト名とポート番号が同じため、これを残してあると Gitea へアクセスしようとしているのに、Gitea を詐称しているサーバーへアクセスしたと判定されてエラーとなります。Forgejo の SSH ホストへアクセスしようとしているので、これが理由でエラーになっては困ります。

フィンガープリントを削除するには ssh-keygen -R コマンドを使います。

ssh-keygen -R <接続先>

接続先には、ポート番号 22 を使っている場合は ホスト名 を指定します。他のポート番号を使っている場合は [ホスト名]:ポート番号 を指定します。

ここでは localhost でポート番号 2222 の接続先のフィンガープリントを削除するので、次のコマンドになります。

ssh-keygen -R [localhost]:2222

実際に実行すると、次のような結果となります。

User@WinDev2401Eval MINGW64 ~/workspace/docker/forgejo
$ ssh-keygen -R [localhost]:2222
# Host [localhost]:2222 found: line 1
# Host [localhost]:2222 found: line 2
# Host [localhost]:2222 found: line 3
/c/Users/User/.ssh/known_hosts updated.
Original contents retained as /c/Users/User/.ssh/known_hosts.old

この後、Forgejo の SSH ホストのフィンガープリントを登録します。これについては、Gitea と同じなので、説明を省略します。

準備ができたら、URL が ssh://git@localhost:2222/user001/proj001-forgejo.git のリモートリポジトリをクローンしてみましょう。次のようにできるはずです。

User@WinDev2401Eval MINGW64 ~/workspace/docker/forgejo
$ git clone -c "core.sshCommand=ssh -i ~/.ssh/id_ed25519_gitea -F /dev/null" \
    ssh://git@localhost:2222/user001/proj001-forgejo.git
Cloning into 'proj001-forgejo'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

これで Forgejo の試用についての説明はおしまいです。

Docker を使うと Linux マシンがなくても Linux のソフトウェアを動かすことができて便利だということがわかったでしょうか。

Discussion