2026/06/17(水)Forgejoを設置して公開するまでをやったログと長いあとがき
ここしばらくGitHubに思うところがありすぎて、GitHubを使い続けることに悩ましさを感じていたが、折角自宅サーバーの運用が軌道に乗ってきたのだし、それならGitHubもセルフホストしちゃおう!というのでやってみたログ。
あとがきに熱が入りすぎて異様な長さになってしまったので、この記事はあとがきが本体な可能性がある。
構築条件
- Dockerを使わずバイナリ直運用
- nginxからのリバースプロキシ
- 内部か外部かを問わずIPv6を使用する
- unixsocketを利用する
- GitのSSH操作にForgejo組み込みのSSHを利用する
確認環境
| Env | Ver |
|---|---|
| Forgejo | 11.0.15+gitea-1.22.0 |
やり方
基本は公式のインストールガイドの通り。
バイナリの配置~デーモンの配置を行う
# Forgejoバイナリの入手 wget https://codeberg.org/forgejo/forgejo/releases/download/v11.0.15/forgejo-11.0.15-linux-amd64 # Forgejoバイナリの配置 sudo cp forgejo-11.0.15-linux-amd64 /usr/local/bin/forgejo sudo chmod 755 /usr/local/bin/forgejo rm forgejo-11.0.15-linux-amd64 # gitとgit-lfsのインストール(gitは既に普通あると思うが) sudo apt update sudo apt install git git-lfs # Git操作用ユーザーの追加 sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \ --group --disabled-password --home /home/git git # Forgejoディレクトリの作成 sudo mkdir /var/lib/forgejo sudo chown git:git /var/lib/forgejo && sudo chmod 750 /var/lib/forgejo sudo mkdir /etc/forgejo sudo chown root:git /etc/forgejo && sudo chmod 750 /etc/forgejo # Systemdの入手と配置 sudo wget -O /etc/systemd/system/forgejo.service https://codeberg.org/forgejo/forgejo/raw/branch/forgejo/contrib/systemd/forgejo.service # デーモンの開始(設定ファイルとかを作らせるためにしている) sudo systemctl daemon-reload sudo systemctl enable forgejo.service sudo systemctl start forgejo.service # 設定ファイルのパーミッションを変える sudo chmod 640 /etc/forgejo/app.ini/etc/systemd/system/forgejo.serviceを開き[service]セクションに以下を追記する
下二行はケイパビリティの設定で、これをしておくと22番ポートが使えるようになるRuntimeDirectory=forgejo RuntimeDirectoryMode=0755 AmbientCapabilities=CAP_NET_BIND_SERVICE CapabilityBoundingSet=CAP_NET_BIND_SERVICEnginxからリバプロする
server { listen [::]:443 ssl; server_name git.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; client_max_body_size 100M; location / { proxy_pass http://unix:/run/forgejo/forgejo.sock; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } }/etc/forgejo/app.iniを開き、適当に設定を書く。設定系はConfiguration Cheat Sheetに全部書いてある。# Webページのタイトルの一部が変わる APP_NAME = Forgejo # Webページのタイトルの一部が変わる APP_SLOGAN = Beyond coding. We Forge. # 実行ユーザー RUN_USER = git # 本番 RUN_MODE = prod # 実行パス WORK_PATH = /var/lib/forgejo [server] # unixsocketを使う PROTOCOL = http+unix # Forgejoを置いているドメイン DOMAIN = git.example.com # unixsocketのパス HTTP_ADDR = /run/forgejo/forgejo.sock # unixsocketのパーミッション # www-dataがアクセスできるように666にしているがwww-dataをgitグループに入れてもいいかも? UNIX_SOCKET_PERMISSION = 666 # 組み込みSSHを起動する START_SSH_SERVER = true # IPv6でListenさせる SSH_LISTEN_HOST = :: [repository] # リポジトリを格納するルートパス ROOT = /var/lib/forgejo/data/forgejo-repositories # アップロード制限、とりあえず公式のコピペ [repository.upload] ; ; max size for files to the repo via web interface, in MB, ; ; defaults to 3 (this sets a limit of about 4GB) FILE_MAX_SIZE = 4095 ; ; by default 5 files can be uploaded at once, increase to 20 MAX_FILES = 20 # Gitのタイムアウト制限、とりあえず公式のコピペ [git.timeout] ; Git operations default timeout seconds DEFAULT = 3600 ; Migrate external repositories timeout seconds MIGRATE = 6000 ; Mirror external repositories timeout seconds MIRROR = 3000 ; Git clone from internal repositories timeout seconds CLONE = 3000 ; Git pull from internal repositories timeout seconds PULL = 3000 ; Git repository GC timeout seconds GC = 600- デーモンの再起動
sudo systemctl restart forgejo.service https://git.example.comにアクセスし適当に設定する
基本的に初期設定そのままで大きな問題がないものばかりだった気がする

SSH鍵を作成し、Forgejoで自分のアカウント設定ページを開き、公開鍵を登録する
クライアントになる環境にSSHに繋ぐための設定(
~/.ssh/config)を書くHost git.example.com HostName git.example.com IdentityFile /path/to/forgejo.sec- 疎通確認。WindowsでもLinuxでも同じ
ssh -T git@git.example.com
GitHubのリポジトリを一括でForgejoに移行する方法
GITHUB2FORGEJOを使うとできる。
以下は移行のコマンド例。マニュアルが親切なのでマニュアルを読めばわかる。
一個でも外すとこのオプションどうする?と聞かれるが、何も指定しなければウィザードを流してくれるので、環境変数を指定せずに叩いても動く。
以下のコマンドではGitHubと決別し、完全にForgejoに移行する前提の設定としている。
wget https://github.com/PatNei/GITHUB2FORGEJO/archive/refs/heads/main.zip
unzip main.zip
rm main.zip
cd GITHUB2FORGEJO-main
GITHUB_USER=YourGitHubUserName \
GITHUB_TOKEN=ghp_XXXXXXXXXXXXX \
FORGEJO_URL=https://git.example.com/ \
FORGEJO_USER=YourForgejoUserName \
FORGEJO_TOKEN=XXXXXXXXXXXXXXXXX \
STRATEGY=clone \
MIRROR_DIRECTION=pull \
PUSH_MIRROR_INTERVAL=8h \
PUSH_MIRROR_SYNC_ON_COMMIT=no \
MIGRATE_ARCHIVE_STATUS=yes \
MIGRATE_FORKS=no \
VISIBILITY=both \
SORT=pushed \
SORT_DIRECTION=desc \
FORCE_SYNC=no \
DRY_RUN=no \
./github-forgejo-migrate.sh
どうやらリポジトリ本体は持ってこれるもののIssueやWikiは持ってこれないようだ。
forgejo dump-repoというGitHub系サービスの中身をダンプするコマンドがあったので試してみたが、こちらは引っ張ってはこれるっぽいもののForgejoのDBやディレクトリ構造と合わないようで、移行用途では使えなかった。
gh repo list Lycolia --limit 1000 --json name --jq '.[].name' \
| while read url; do
echo sudo -u git forgejo dump-repo --git_service github --auth_token XXXXXXXXXXXXXXXXXX--clone_addr https://github.com/Lycolia/$url --config /etc/forgejo/app.ini --repo_dir /var/lib/forgejo/data/forgejo-repositories/lycolia/$url
done
GitHubのアカウントエクスポートも試してみたが、中身が省略されているように見える.gitディレクトリの山がパッケージされており、ググった感じGitHub間のアカウント移行に使う物らしかったので、諦めた。
トラブルシュート
../ssh/ssh_graceful.go:25:listen() [F] Failed to start SSH server: listen tcp 0.0.0.0:22: bind: permission deniedというエラーが出る
/etc/systemd/system/forgejo.serviceを開き[service]セクションに以下を追記して再起動すれば治る。
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
動作確認で起動と起動時のログ確認を同時にやりたい
動作確認時にデーモンの上げ下げしてジャーナル見るのが面倒なので、パッとやりたいときに便利なコマンド
sudo -u git /usr/local/bin/forgejo web --config /etc/forgejo/app.ini
あとがき
あとがきが長すぎて、実はこっちが記事の本体という可能性が…w
構築していて思ったこと
SSHの穴をあけるのは危険か?と思ったが組み込みのSSHであればgitユーザーが出来ること以外できないだろうし、任意のコマンドが実行されたところで、精々リポジトリの全消し以上のリスクはなさそうなので開けることにした。理由としてはHTTPはパフォーマンスが悪いらしいからだ。
構築していて思ったがForgejoのマニュアルは親切で比較的解り易く、構築が楽だったのが良かった。
unixsocketの利用について
積極的に使い始めたのはUbuntuのadiaryをlibfcgi-perlで動かす方法が初めてだが、unixsocketはTCP通信をしないのでポート管理が不要になるのが利点なのと、TCPのオーバーヘッドがない分処理が速いというのをどっかで見たので、使うことにした。
内部通信のポートが被らないように管理するのは地味に大変なのでアプリケーション間の通信は極力unixsocketに倒したいなと思った。
Forgejoを使おうと思った理由
GitHub周辺のセキュリティ事情の変化と、それに伴う対応
最大の理由は、ここ数年でGitHubやnpm周辺のサプライチェーンリスクを強く意識せざるを得なくなったからだ。
例えばSecrets漏れなどの事故はここ数年で非常に聞くようになったし、npmjsからGitHubのToken奪取などの問題もあったと思う。
そしてその関係でセキュリティが面倒なことになり、GitHub Actionsからnpm publish出来なくなってたのを対応したみたいなことをする羽目になったこともあり、非常に煩わしさを感じていた。
Value-DomainでcertbotのDNS Challengeをやるスクリプトを書き直した理由の一つも、npmjsから手を引きたい思いが実はあり、そもそも別にリポジトリから拾えばいいじゃんと思い、パッケージ化しなかったというのもある。だって別にPerlでもnpmレジストリに入れることはできるからね。
そして昨日npmjsのアカウントを消そうと思い立ちログインしようとしたらロックアウトされてしまった。私はホビープログラマとしてやっているだけなので、こういった変化についていくのに疲れてしまった。
GitHub離れの加速
例えば最近GitHub離れが進んでいることも理由の一つだ。
理由にはいろいろあると思う、例えばここ最近GitHubは不安定で、GitHub Actionsが失敗する、Webページが開けない、APIがダウンしているのは最早日常といってもいいだろう。少なくとも私はそう思っている。
他にもCopilotなどのAI化の推進や、UXの悪いPR、行儀の悪いソフトウェアの排除もある。
CopilotなどのAI化の推進についてはGitHubのWebページ上でコミットを打つと解るのだが、LLMによって勝手にコミットメッセージが補完される。あのメッセージに意図などなく、変更内容を文字列にしただけだ。これを避けるためにはAIが書き切るより早く書き起こしてコミットするか、或いは書き終わるのを待って上書きするか、何も考えず即座にコミットボタンを押しUpdate hoge.mdのようなメッセージにするかしかない。個人的にはこれが非常に煩わしく、避けたいと思っている。
そして、もしこれを回避する設定があるとしてもGitHubの設定は既に増えすぎており、もう探す気も起きない。
UXの悪いPRについては、PRを作ったときにベースリポジトリに更新が走ると更新するボタンが出てくるが、これを押すと中身のない空のマージコミットが作られることや、GitHubのバグとしか思えないよく解らない差分が出ることがあるのも挙げられる。こうやってやらなくていいことを増やすだけのシステムはUXが悪いと思う。
そして行儀の悪いソフトウェアの排除だ。行儀の悪いソフトウェアとは何かというと、もっぱら権利侵害を目的に利用されているのではないかと疑われているようなものである。
かつてGitHubでホスティングされていたyoutube-dlというソフトウェアがDMCA侵害でGitHubから消されることがあり、当時は結構騒がれた話だったと思う。その後、紆余曲折ありyoutube-dlは現在は再公開されているが、最近はほとんど更新されていない。恐らくフォークであるyt-dlpに開発が移ったと思われる。
そして今年に入ってからFAKKU, LLCが大規模なDMCAを通告した。これによりGitHubから多くのダウンローダー系ツールが削除されて祭りとなった。
この対応を受け、gallery-dlはCodebergへの移行を決めた。
個人的にはTwitterの画像を落とすのにHitomi-Downloaderをよく使っていたのだが、これもDMCAに含まれており削除の憂い目にあった。Hitomi-DownloaderはTwitterがXになり、APIが有料化してからもTwitterのメディアをバルクで落とせるので重宝していた人が多くいたと思う。なおHitomi-Downloaderについては移転したとかはなく、単に消えてそうだ。バイナリはググれば出てくるが、APIが変わってるので、もう動かないと思う。余談だが、現在Twitterの画像をバルクで落とせる無料のソフトウェアはgallery-dlくらいだと思う。
また前述したGitHubの不安定さや、AIの存在を理由にGitHubを離れたものとしてプログラミング言語のZigがある。ZigはGitHubの現状に失望し、痛手を負ってでもCodebergに移行した。現在のGitHubは更新されておらず、移行のメッセージが残されている。
また玄人向けのLinuxディストリとして知られるGentoo LinuxもGitHubのLLM方針に反発し、Codebergへの移行を発表している。
Gentooの2025年振り返りでは、「Goodbye Github, welcome Codeberg」という言葉も見られ、Planet Gentooでは開発者からLLMに対する鬱憤ともいえる批判が多く寄せられている。
個人的に強く共感したものには次のものがある。
They start using LLMs because they don’t want to maintain their code anymore. Software turns into slop, which burns out even more people.
(ja: 彼らは、もうコードのメンテナンスをしたくないという理由で、LLMを使い始める。その結果、ソフトウェアはずさんなものとなり、さらに多くの人々が燃え尽きてしまう。)
LLMを使う理由はコードを書きたくないから、メンテしたくないから、動いている風に見えればよいからだというのは私も思う。バイブコーディングで出てきたものがまともに動く保証はない。
公私ともにLLMを使ってコーディングしているが、本当にそう思うし、仕事ではLLMに毒されすぎたのか判断能力を失ってしまった人も見かける。
Gentoo aims to be made by humans
We banned LLM contributions two years ago, and never regretted it. We didn’t “wait and see”, we took decisive action, and if we got left behind, it’s only for the better. I can’t give you a 100% guarantee that no tainted code slipped through, but we’re doing our best to stay vigilant. In the end, it’s all about trust, and trusting one another is what builds our community.
(ja: 私たちは2年前にLLMによる投稿を禁止しましたが、その決断を後悔したことは一度もありません。「様子を見る」のではなく、断固たる措置を講じました。もし他者に遅れをとったとしても、それはむしろ良いことなのです。不適切なコードが混入していないことを100%保証することはできませんが、私たちは警戒を怠らないよう最善を尽くしています。結局のところ、すべては信頼にかかっており、互いを信頼し合うことこそが、私たちのコミュニティを築き上げるのです。)
この人間らしさには非常に共感した。特に「もし他者に遅れをとったとしても、それはむしろ良いことなのです。」の部分だ。誰かより早くある必要はない、誰かと比べて遅れていても問題ではない。何故なら競技ではないし、そもそもベクトルが違うと私は思う。
他にもAutodesk Fusion 360 for Linuxも同様の理由でCodebergへの移行を行い、GitHubは既にアーカイブされている。
GitHubでホストする意味がなかった
lycolia.info、つまりサイトトップを触っていて思ったのだが、自分が作ったソフトウェアを見てもらうのに外部サイトにアクセスしないといけないというのが癪だと思った。
ソフトウェアの配布なら最悪自分のサイト上でzip配布でもすりゃあいいじゃんという話だ。
ただまぁ事はそう単純でもなく、リポジトリをWebサイトに置いておくと、出先でちょろっといじりたいとか、テキストとして転がして置き、会社のPCでコピペしたい[1]みたいな絶妙な需要を満たせるので、セルフホストでかつ、GitHubの様な機能を満たせるものというところでForgejoを採用したのである。
勿論、先述したようなGitHubへの信頼性問題もあるが、私がDMCAでどうにかなる可能性は今のところないので、まぁ宗教みたいな話ではある。
そういえば以前WSL2のUbuntu 20.04にGiteaを生やすという記事を書いたし、Giteaにはコントリビュートしたこともあるが、GiteaのフォークであるForgejoでこんなことを始めるとは夢にも思わなかったので、めぐりあわせだなぁと思うのであった。
GitHubの個人用アカウントと業務用アカウントがどうのこうのを解決する糸口として
業務用と個人用でGitHubの無料アカウントを分けるは、このブログで二番目にアクセスの多い記事だが、Forgejoに完全に移行すれば、こういったことも解消できる。
なお現状ではGitHubのアカウントそのものはOSSのコントリに使うことが稀にあるため保持しておくつもりだが、いつ消し去っても良いくらいの温度感では持っておきたい所存である。
Forgejoに対する思い
分散型という諸刃の剣
Forgejoは、その構造上、各ホスト上でアカウントを作らないとコントリビューションができないと思うので、特定のプラットフォームからの支配や思想を回避できるのが利点だが、同時に欠点だとも感じている。
端的に言うとそれぞれのForgejoサーバーには何ら繋がりがない。あるForgejoサーバーでアカウントを作ったとしても、別のForgejoサーバーでは使えない。これはForgejoサーバーが増えれば増えるほど難しくなっていく問題かもしれない。私の様なサーバーでは問題にならないので別にいいが…。
但しFediverseにあるActivityPubのようにオープンプロトコルを作り連合を作る計画はあるようで、将来的には各ホスト同士での疎通が実現するかもしれない。
とはいえ、連合は連合で問題である。Fediverseも連合制をとっていて様々なサーバーが連合しているがMastodonとMisskeyには互換性の問題があるし、連合は数が増えれば増えるほど負荷が大きくなる問題もある。例えばA Forgejoサーバーの変更が10の連合先に伝播し、そこから更に各サーバーの先にある10に連合…となれば伝播する時間もリソースも無駄になってくる。
設計次第ではあるものの相互に繋がった数千のサーバーがやり取りを始めたらDoS攻撃に匹敵する負荷が発生するかもしれないし、様々な分散サーバーに同一の情報が保存されるのはストレージの無駄である。
この辺りはMisskeyの開発者であるsyuiloさんや、.ioの運営者である村上さんも話しているし、連合のコストについてはfedibird管理人ののえるさんも話している。
分散型はプラットフォーマの支配を受けず、独自性を出しやすい代償に、スケールしづらいのだ。ただ、DMCAの通報がされるようなソフトウェアにとってはそっちの方が都合がいいかもしれない。とはいえ、GitHubにBANされなくとも、次はAWSやVPSからBANされたり、ドメインが差し押さえられたり、自宅サーバーであってもISPから契約解除されるなどのリスクはあるので、程度問題ではある。
そういえば、この手の話をまさにしているスレッドがRedditにあったので、記録に残しておく。
今回設置した物体が見れる場所
エクスプローラー - LycoGit: Lycolia's Git Hostingで公開リポジトリの一覧が見れる。
ドメイン直下にアクセスすると「自分で立てる、超簡単 Git サービス」という強めのおもしろアピールが出てくる。
今のところはGitHubのリポジトリを丸ごと移しただけなので、中身的には同じものである。
- こうしておくと変なセキュリティにかからず、情報漏洩にもならず仕事で合法的に自分が過去に書いたコードを使えるのだ ↩
