---
title: ReactPHP で Gemini Protocol Server を作る
tags: 
author: [halt](https://docswell.com/user/halt)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/G75M134L74.jpg?width=480
description: 第186回 PHP勉強会 at 東京
published: April 21, 26
canonical: https://docswell.com/s/halt/5DMJWD-2026-04-21-gemini-protocol-server
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/G75M134L74.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
GEMINI PROTOCOL × REACTPHP
ReactPHP で
Gemini Protocol
Server を作る
シンプルさとプライバシーを追求した
ミニマリストプロトコルを PHP で実装してみた
黒井春人 / @halt / 有限会社アリウープ
2026-04-21 第186回 PHP勉強会@東京
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/9J291ZV3ER.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
自己紹介
halt
黒井 春人 (くろい はると)
@halt
直近3年間は無職でしたが、今年から有限会社アリウープで働いています
ずっと無職だったので発表も久しぶりです。お手柔らかに 🙇
東京のPHP勉強会に関わっています — なんと20年前から…
x.com/halt
zenn.dev/halt
phpstudy アーカイブ
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/DEY4ZR38JM.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Laravel Live Japan は 5月26日 - 27日開催！
2026年5月26日（火）〜 27日（水）
📍 立川
所属企業である 有限会社アリウープ が
ゴールドスポンサー をやってます。
他のゴールドスポンサー：Sentry / JetBrains / CodeRabbit
よろしくおねがいします！
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/VJNY3DV978.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
執筆
📚 PHPと共に歩んできた
PHP4 の最初くらいから PHP5.3 くらいまで極めてました
15年くらい前の話ですが、書籍執筆とかもやってました
このあと起業したり EM になったりして、こういう活動しなくなってしまった…
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/YE9P9G63J3.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
今日話すこと
1. Gemini Protocol とは何か
2. Google Gemini との違い（大事）
3. IndieWeb という思想
4. 宇宙との関係・用語の世界観
5. Gemtext ― 専用マークアップ言語
6. ReactPHP の仕組み
7. 実装：GeminiServer をゼロから作る
8. Lagrange で実際に見てみる
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GE8D9VZLED.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
現代の Web はどうなっているか
5 MB+
68%
3 sec
平均ページサイズ (2024)
サードパーティ
トラッカー含有率
モバイル平均
読み込み時間
広告・トラッキングスクリプトが常時ユーザーを監視
JavaScript の肥大化で低スペック端末では表示すら困難
「情報を届ける」という本来の目的が二次的になっている
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/LELMW5DQ7R.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Gemini Protocol とは？
🌐
⚡
1991年の Gopher にインスパイアされ、TLS を取り入れた現代的再構築。2019
年誕生。
文書テキストの表示に特化。JS なし、CSS なし、動画なし。
🔒
✨
Cookie もトラッカーも広告もプロトコルレベルで存在しない。TLS 必須。
「情報を届ける」という Web 本来の機能に立ち返る設計思想。
誕生の背景
プライバシー重視
超軽量設計
デジタルミニマリズム
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/4JMY93WKJW.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
まず最初に大事なこと
「Gemini」は 2 つある
Google Gemini
Gemini Protocol（今日の話）
大規模言語モデル（LLM）
通信プロトコル（HTTP の仲間）
Google の AI サービス
有志のコミュニティが開発
2023年「Bard」で登場
2019年に誕生
2024年「Gemini」に改名
AI とは一切無関係
gemini.google.com
gemini:// スキーム
注意：Google の改名で混乱しがちですが、全くの別物です。
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/PJR9GQY679.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Web・Gopher・Gemini の比較
項目
HTTP/Web
Gopher
Gemini
暗号化
任意
なし
必須
マークアップ
HTML+CSS+JS
プレーン
Gemtext
スクリプト
あり
なし
なし
トラッキング
ふんだん
なし
なし
ポート番号
80/443
70
1965
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/PEXQX5GDJX.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
IndieWeb という思想
自分のコンテンツを、自分で管理する
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/3EK9W64DED.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
POSSE の原則
Publish (on) Own Site, Syndicate Elsewhere
“
“
まず自分のサイトに投稿し、SNS には**配信（コピー）**する。
SNS が流れ去っても、自分の「家」は残り続ける。
🏠 オーナーシップ
🔗 ウェブ標準の活用
コンテンツは自分のドメインに保存。SNS に依存しない。
HTML, RSS, Webmention などの公開技術で連携。
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/L73W16LP75.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
なぜ SNS 依存は危険なのか？
💀
🤖
倒産・サービス終了・アカウント凍結で過去の投稿が消える。Vine・Google+ の前
例。
表示順・範囲は運営の都合で変わる。フォロワーがいても届かない。
🗂
🎯
データ消失リスク
分断された記録
複数 SNS を使うと活動記録がバラバラに。検索もできない。
アルゴリズムの支配
主張の歪み
バズる内容に引っ張られ、伝えたい内容から遠ざかる。
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/87DKXVN3JG.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Gemini と宇宙のメタファー
💊 Capsule
📡 Port 1965
NASA のジェミニ計画
から。アポロ計画（月
面着陸）の前段とし
て宇宙ドッキング技術
を確立した計画。
Gemini のウェブサイト
単位。宇宙船帰還カ
プセルから連想。独立
した小さな領域を表
す。
デフォルトポート。ジェミ
ニ 3 号（NASA 初の
有人ミッション）が行
われた年。
技術仕様を超え、宇宙というメタファーで哲学・世界観を表現している。
“
“
🚀 Gemini
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/VJPKPV5PE8.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Gemtext ― 専用マークアップ言語
構文
意味
備考
# テキスト
見出し 1
最大ヘッダー
## テキスト
見出し 2
中ヘッダー
=&gt; URL [ラベル]
リンク
行の先頭のみ
* テキスト
リスト
箇条書き
&gt; テキスト
引用
ブロック引用
インライン装飾（太字・斜体）も テーブル も CSS も JS も無し。
必要最小限の要素のみ。
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/2EVV2ZPVEQ.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Gemtext を書いてみると…
# Gemini カプセルへようこそ
これは Gemtext で書いたページです。
HTMLとは違い、装飾は最小限。
## リンク集
=&gt; gemini://example.com トップページ
=&gt; gemini://example.com/about About
* シンプル
* プライベート
* テキスト中心
&gt; Less is more.
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/57GLR4P1EL.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
ReactPHP とは？
PHP でイベント駆動・非同期プログラミングを実現するライブラリ
通常の PHP（同期）
ReactPHP（非同期）
リクエスト来る → プロセス起動
イベントループが常に動く
DB クエリ発行（待つ）
待機中に並行で他を処理
HTML を返す → 終了
1 プロセスで数千接続
TCP/UDP サーバー実装に最適 ― まさに今回のユースケース。
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/4EQYVG2NJP.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Gemini プロトコルの通信シーケンス
1
Client → Server : TLS ハンドシェイク
2
Server → Client : 証明書交換（自己署名も可）
3
Client → Server : gemini://host/path\r\n （1 行）
4
Server → Client : 20 text/gemini\r\n （ステータス + MIME）
5
Server → Client : 本文（Gemtext）
6
接続切断（keep-alive なし）
リクエストは 1 行、レスポンスはステータス行 + 本文のみ ― 驚くほど単純。
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/KJ4WM5L371.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
実装：エントリーポイント
&lt;?php
$host
= getenv(&#039;GEMINI_HOST&#039;) ?: &#039;0.0.0.0&#039;;
$port
= getenv(&#039;GEMINI_PORT&#039;) ?: 1965;
$docRoot
= getenv(&#039;GEMINI_DOC_ROOT&#039;);
$hostname = getenv(&#039;GEMINI_HOSTNAME&#039;);
// TLS 証明書を自動生成
$cert = new CertificateGenerator($certDir);
$path = $cert-&gt;generate($hostname);
// サーバー起動
$server = new GeminiServer(
$host, $port,
new StaticFileHandler($docRoot),
$path
);
$server-&gt;run();
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LE1Y8WLZ7G.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
実装のポイント
① 環境変数で設定を外部化
② TLS は自動生成
ホスト・ポート・ドキュメントルートを env で切り替え可能に。
Gemini は TLS 必須。openssl で自己署名を自動作成。
③ StaticFileHandler
④ run() = イベントループ
.gmi ファイルを text/gemini で返すだけ。
ReactPHP のイベントループが起動し接続を待つ。
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/GEWGZ6V6J2.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
GeminiServer の内部実装
class GeminiServer {
public function run(): void {
$loop = Factory::create();
// TLS コンテキスト設定
$ctx = stream_context_create([
&#039;ssl&#039; =&gt; [&#039;local_cert&#039; =&gt; $this-&gt;certPath]
]);
// TLS サーバーソケット起動
$server = new SecureServer(
new Server(&quot;{$this-&gt;host}:{$this-&gt;port}&quot;, $loop),
$loop, [&#039;tls&#039; =&gt; $ctx]
);
$server-&gt;on(&#039;connection&#039;, function($conn) {
$conn-&gt;on(&#039;data&#039;, fn($url) =&gt;
$this-&gt;handler-&gt;handle($conn, $url)
);
});
$loop-&gt;run();
}
}
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/47ZL1Y4RJ3.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
ReactPHP の API ポイント
SecureServer
on(&#039;connection&#039;)
TLS 対応ソケットサーバー。証明書パスを渡すだけで HTTPS 的な暗号化ができ
接続が来るたびにコールバックが呼ばれる。同期的な while ループは不要。
る。
on(&#039;data&#039;)
$loop-&gt;run()
データが届いたタイミングで handler を呼び出す。Gemini はリクエストが 1 行。
ここでイベントループに入り、プロセスは終了せず待ち続ける。
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/YJ6WLD31JV.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Lagrange で実際に見てみる
$ php bin/server.php
Certificate: /certs/localhost.pem
Gemini server listening on 0.0.0.0:1965
# Lagrange ブラウザで
$ open gemini://localhost:1965/
Lagrange ― Windows/Mac/Linux 対応の Gemini 専用ブラウザ。
表示される：見出し・リスト・リンク・引用・コードブロック
クリックで開く：画像・動画
存在しない：テーブル・スタイル指定・JS
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/GJ5M13LLJ4.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
実際に使ってみて感じたこと
👍 よかった点
🤔 ストイックすぎる点
思想・哲学に強く共感
テーブルが存在しない
実装が驚くほどシンプル
画像はクリックで開く
仕様書が数ページで読める
インライン装飾が一切なし
コンテンツに集中できる
専用ブラウザが必要
ReactPHP との相性が抜群
SEO という概念がない
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/9E291ZL37R.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
Gemini は「普及」を目指していない
“
現代 Web の置き換えではなく、
ミニマルな補完として存在する。
“
“
デジタルミニマリズムを実践したい人のためのスペース。
遅くていい、不便でいい、それが哲学。
“
小さなコミュニティが今も活発に運営
「書くこと」そのものを楽しむ文化
技術者が自分で実装できるシンプルさ
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/D7Y4ZRQ8EM.jpg)

GEMINI PROTOCOL × REACTPHP
Gemini Protocol × ReactPHP
自分のものを
自分でホストする
X でつぶやいて終わり、になっていませんか？
レコメンドシステムに自分の主張をおさえつけられていないか？
20 年後も参照できるコンテンツを、自分のカプセルから発信しよう。
github.com/ha1t/php-gm-server
25


