インストール セットアップガイド - ha1t/php-gm-server GitHub Wiki
本ページでは、PHP GM Serverの初期セットアップから初回起動までの手順、および開発環境構築方法を説明します。本ガイドはLinuxおよびmacOS環境を対象としています。システム要件の確認、Composerを使用した依存パッケージの導入、自動TLS証明書生成の仕組みについて網羅的に解説します。
PHP GM Serverを実行するために、以下の環境が必須です。
PHP 8.1以上が必須です。 composer.json:6 に明示されており、モダンなPHP機能(型宣言、nullsafe演算子など)が使用されています。
# PHPバージョンの確認
php --versionOpenSSL拡張の有効化が必須です。 TLS/SSL通信とサーバー証明書生成に使用されます。
# OpenSSL拡張の確認
php -m | grep opensslOpenSSL拡張がインストールされていない場合、以下のいずれかを実行してください:
-
Ubuntu/Debian:
sudo apt-get install php-openssl
-
CentOS/RHEL:
sudo yum install php-openssl
-
macOS (Homebrew):
brew install openssl
- Composer 2.0以上: PHPの依存パッケージ管理ツール
- インターネット接続: 初回インストール時にパッケージダウンロードが必要
-
書き込み権限:
certs/およびcontent/ディレクトリ作成用
git clone https://github.com/ha1t/php-gm-server.git
cd php-gm-servercomposer installこのコマンドは、composer.json:5-8 に記載された以下のパッケージをインストールします:
| パッケージ | バージョン | 用途 |
|---|---|---|
react/socket |
^1.16 | 非同期ソケット通信 |
react/event-loop |
^1.5 | イベントループ駆動 |
phpunit/phpunit |
^10.5 | テスト実行(開発依存) |
composer.json:13-21 に基づき、以下の名前空間が自動読み込みされます:
-
GeminiServer\→src/ディレクトリ -
GeminiServer\Tests\→tests/ディレクトリ
最も簡単な起動方法は以下の通りです:
php bin/server.phpこのコマンドで、以下のデフォルト設定でサーバーが起動します:
| 設定項目 | デフォルト値 | 説明 |
|---|---|---|
| バインドアドレス | 0.0.0.0 |
すべてのインターフェースをリッスン |
| ポート番号 | 1965 |
Geminiプロトコル標準ポート |
| ドキュメントルート | content/ |
コンテンツ配置ディレクトリ |
| 証明書ディレクトリ | certs/ |
TLS証明書保存先 |
| サーバーホスト名 | localhost |
証明書のCommonName |
起動出力例:
Certificate: /path/to/certs/server.pem
Gemini server running on gemini://0.0.0.0:1965/
環境変数を使用して、起動時に設定をカスタマイズできます。bin/server.php:11-15 で環境変数が読み込まれます:
# ポート番号をカスタマイズ
GEMINI_PORT=8080 php bin/server.php
# ドメイン名を指定して証明書を生成
GEMINI_HOSTNAME=example.com GEMINI_PORT=1965 php bin/server.php
# 全設定をカスタマイズ
GEMINI_HOST=127.0.0.1 \
GEMINI_PORT=1965 \
GEMINI_DOC_ROOT=/var/gemini/content \
GEMINI_CERT_DIR=/var/gemini/certs \
GEMINI_HOSTNAME=example.com \
php bin/server.phpPHP GM Serverは起動時に自動的にTLS用の自己署名証明書を生成します。この仕組みについて詳しく解説します。
flowchart TD
A["サーバー起動"] --> B["CertificateGenerator<br/>初期化"]
B --> C["GEMINI_CERT_DIRから<br/>証明書ディレクトリ決定"]
C --> D{"server.pemが<br/>存在?"}
D -->|Yes| E["既存証明書を使用"]
D -->|No| F["certsディレクトリを<br/>自動作成"]
F --> G["RSA 2048ビット<br/>秘密鍵生成"]
G --> H["証明書署名要求<br/>(CSR)生成"]
H --> I["365日有効な<br/>自己署名証明書生成"]
I --> J["PEM形式で<br/>server.pemに保存"]
J --> K["パーミッションを<br/>0600に設定"]
K --> E
E --> L["証明書パスをサーバーに渡す"]
bin/server.php:17 で初期化される際、証明書保存ディレクトリが指定されます:
$certGenerator = new CertificateGenerator($certDir);
$certPath = $certGenerator->generate($hostname);src/CertificateGenerator.php:20-22 で、server.pemがすでに存在するかチェックされます。存在する場合は再利用され、新規生成はスキップされます。
if (file_exists($pemPath)) {
return $pemPath;
}src/CertificateGenerator.php:24-26 で、必要に応じて証明書保存ディレクトリが自動作成されます:
if (!is_dir($this->certDir)) {
mkdir($this->certDir, 0755, true);
}src/CertificateGenerator.php:28-31 で、OpenSSL関数を使用して2048ビットのRSA秘密鍵が生成されます:
$privateKey = openssl_pkey_new([
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);src/CertificateGenerator.php:33-38 で、CSRと自己署名証明書が生成されます。証明書有効期間は365日です:
$dn = ['commonName' => $hostname];
$csr = openssl_csr_new($dn, $privateKey);
$cert = openssl_csr_sign($csr, null, $privateKey, 365);src/CertificateGenerator.php:40-47 で、証明書と秘密鍵がPEM形式で統合保存されます:
$certPem = '';
openssl_x509_export($cert, $certPem);
$keyPem = '';
openssl_pkey_export($privateKey, $keyPem);
file_put_contents($pemPath, $certPem . $keyPem);
chmod($pemPath, 0600);生成されるファイル:
-
パス:
certs/server.pem - 形式: PEM(テキスト形式)
- 内容: 証明書 + 秘密鍵(連結)
-
パーミッション:
0600(所有者のみ読み取り可能)
- 有効期間: 365日
-
更新方法:
certs/server.pemを削除して再度サーバーを起動rm certs/server.pem php bin/server.php
src/GeminiServer.php:36-40 で、生成された証明書を使用してSecureServerが構成されます:
$server = new SecureServer($tcp, $loop, [
'local_cert' => $this->certPath,
'allow_self_signed' => true,
'verify_peer' => false,
]);起動後、以下のディレクトリが自動作成されます:
php-gm-server/
├── bin/
│ └── server.php # エントリーポイント
├── src/
│ ├── CertificateGenerator.php
│ ├── GeminiServer.php
│ ├── RequestParser.php
│ ├── ResponseBuilder.php
│ └── StaticFileHandler.php
├── tests/
│ └── *.php # テストクラス
├── content/ # コンテンツディレクトリ(自動作成)
├── certs/ # 証明書ディレクトリ(自動作成)
├── composer.json
├── composer.lock
└── vendor/ # Composer依存パッケージ
Geminiページを配信するには、content/ディレクトリにファイルを配置します:
# コンテンツディレクトリの作成
mkdir -p content
# サンプルページの作成
cat > content/index.gmi << 'EOF'
# Welcome to Gemini Server
This is a Gemini protocol server written in PHP.
=> /about.gmi About this site
EOF
# その他のページ
cat > content/about.gmi << 'EOF'
# About
This server implements the Gemini protocol specification.
EOFユニットテストを実行するための環境セットアップ:
# テストの実行
vendor/bin/phpunit
# テストカバレッジ付き実行(オプション)
vendor/bin/phpunit --coverage-html ./coveragecomposer.json:10-11 に記載されているPHPUnit 10.5が開発依存として含まれています。
エラーメッセージ:Call to undefined function openssl_pkey_new()
対応:OpenSSL拡張をインストールして有効化してください(前述のシステム要件セクション参照)。
エラーメッセージ:Address already in use
対応:別のポートで起動してください:
GEMINI_PORT=2000 php bin/server.php対応:certs/ディレクトリの書き込み権限を確認してください:
chmod 755 certs/対応:
-
content/ディレクトリが存在するか確認 - ファイルの読み取り権限を確認
-
GEMINI_DOC_ROOTの設定を確認
初回セットアップ完了後、以下のリソースを参照して、さらに詳しく機能を理解してください:
- プロジェクト概要 — プロジェクト全体像と目的
- 環境変数設定リファレンス — 全環境変数の詳細
- TLS証明書管理 — 証明書の詳細管理方法
- Geminiプロトコル仕様実装 — プロトコル仕様
- ディレクトリ構成と規約 — ファイル配置規約