環境変数設定リファレンス - ha1t/php-gm-server GitHub Wiki

環境変数設定リファレンス

このページでは、php-gm-serverの動作を制御する環境変数について、デフォルト値、意味、指定方法、設定例を包括的に説明します。すべての環境変数はサーバー起動時に読み込まれ、ホストバインド、ポート番号、ドキュメント配信パス、TLS証明書管理を制御します。

概要

php-gm-serverは以下の5つの環境変数でサーバー動作をカスタマイズできます。環境変数が指定されない場合、すべての値には安全で汎用的なデフォルトが設定されます。

環境変数 デフォルト値 用途
GEMINI_HOST 文字列 0.0.0.0 バインドするネットワークインターフェース
GEMINI_PORT 整数 1965 リッスンするポート番号
GEMINI_DOC_ROOT パス content/ Geminiコンテンツの配信ディレクトリ
GEMINI_CERT_DIR パス certs/ TLS証明書の保存ディレクトリ
GEMINI_HOSTNAME 文字列 localhost TLS証明書のCommonName

GEMINI_HOST

バインドするネットワークインターフェースのIPアドレスを指定します。

デフォルト値: 0.0.0.0

型: 文字列

用途: GeminiServerコンポーネント で TcpServer を初期化する際に使用されます。

サポート値:

  • 0.0.0.0 : すべてのインターフェースをリッスン(デフォルト)
  • 127.0.0.1 : ローカルマシンのみアクセス可能
  • 192.168.1.100 など:特定のインターフェースのみバインド

実装箇所: bin/server.php:11

$host = getenv('GEMINI_HOST') ?: '0.0.0.0';

例:ローカルホストのみでリッスン

GEMINI_HOST=127.0.0.1 php bin/server.php

注意事項: 0.0.0.0 の場合、外部ネットワークからのアクセスが可能になります。ファイアウォール設定と併用してセキュリティを確保してください。

GEMINI_PORT

サーバーがリッスンするポート番号を指定します。

デフォルト値: 1965

型: 整数

用途: Gemini Protocolの標準ポートは1965です。別のポートで実行する必要がある場合に変更します。

サポート値: 1~65535の有効なポート番号

実装箇所: bin/server.php:12

$port = (int) (getenv('GEMINI_PORT') ?: 1965);

例:カスタムポートで起動

GEMINI_PORT=8080 php bin/server.php

注意事項:

  • 1024以下のポートを使用する場合は、管理者権限(rootまたはsudo)が必要です
  • 既にバインドされているポートを指定するとエラーが発生します
  • ファイアウォールでポートをブロックしていないことを確認してください

GEMINI_DOC_ROOT

Geminiコンテンツファイル(.gmi.txt、画像など)を配信するディレクトリパスを指定します。

デフォルト値: content/(起動スクリプトの親ディレクトリ相対パス)

型: パス(絶対パスまたは相対パス)

用途: StaticFileHandlerコンポーネント によるファイル解決とディレクトリトラバーサル攻撃防止に使用されます。

実装箇所: bin/server.php:13

$docRoot = getenv('GEMINI_DOC_ROOT') ?: __DIR__ . '/../content';

例:カスタムコンテンツディレクトリ

GEMINI_DOC_ROOT=/var/www/gemini-content php bin/server.php

相対パスの場合の解決方法: StaticFileHandlerコンポーネントrealpath() により絶対パスに正規化されます。

$this->docRoot = realpath($docRoot) ?: $docRoot;

セキュリティ機構: 指定ディレクトリの外へのアクセス(パストラバーサル)は realpath() による正規化とドキュメントルート内チェックにより防止されます。 StaticFileHandlerコンポーネント

if ($realPath !== $this->docRoot && !str_starts_with($realPath, $this->docRoot . DIRECTORY_SEPARATOR)) {
    return null;
}

ディレクトリ構造例:

/var/www/gemini-content/
├── index.gmi
├── about.gmi
├── docs/
│   ├── index.gmi
│   └── guide.txt
└── images/
    └── logo.png

ディレクトリアクセス時の自動解決: ディレクトリへのアクセスがあった場合、自動的に同ディレクトリの index.gmi が返されます。 StaticFileHandlerコンポーネント

GEMINI_CERT_DIR

TLS/SSL証明書ファイルの保存ディレクトリを指定します。

デフォルト値: certs/(起動スクリプトの親ディレクトリ相対パス)

型: パス(絶対パスまたは相対パス)

用途: CertificateGeneratorコンポーネント による証明書の生成と保存に使用されます。

実装箇所: bin/server.php:14

$certDir = getenv('GEMINI_CERT_DIR') ?: __DIR__ . '/../certs';

例:カスタム証明書ディレクトリ

GEMINI_CERT_DIR=/etc/gemini/certs php bin/server.php

証明書ファイル: CertificateGenerator により {GEMINI_CERT_DIR}/server.pem が生成・保存されます。 CertificateGeneratorコンポーネント

$pemPath = $this->certDir . '/server.pem';

自動ディレクトリ作成: ディレクトリが存在しない場合は、CertificateGenerator により自動作成されます(パーミッション0755)。 CertificateGeneratorコンポーネント

if (!is_dir($this->certDir)) {
    mkdir($this->certDir, 0755, true);
}

証明書ファイルのパーミッション: 生成される server.pem ファイルのパーミッションは0600に設定されます(所有者のみ読み取り可能)。 CertificateGeneratorコンポーネント

既存証明書の再利用: server.pem が既に存在する場合、新たな証明書は生成されず、既存のものが再利用されます。 CertificateGeneratorコンポーネント

if (file_exists($pemPath)) {
    return $pemPath;
}

セキュリティに関する注意事項: このディレクトリと server.pem ファイルへのアクセスは厳格に制限してください。リモートユーザーがこれにアクセスできると、中間者攻撃の対象になります。

GEMINI_HOSTNAME

TLS証明書のCommonName(CN)として使用するホスト名を指定します。

デフォルト値: localhost

型: 文字列

用途: CertificateGeneratorコンポーネント による自己署名証明書の生成時に、証明書内のCommonNameフィールドに設定されます。

実装箇所: bin/server.php:15

$hostname = getenv('GEMINI_HOSTNAME') ?: 'localhost';

例:カスタムホスト名で証明書生成

GEMINI_HOSTNAME=example.com php bin/server.php

証明書生成処理: CertificateGenerator で以下のように使用されます。 CertificateGeneratorコンポーネント

$dn = [
    'commonName' => $hostname,
];

$csr = openssl_csr_new($dn, $privateKey);

証明書の有効期限: 生成される証明書の有効期限は365日です。 CertificateGeneratorコンポーネント

重要:新しいホスト名での起動

  • 既存の server.pem が存在する場合、GEMINI_HOSTNAME を変更しても新しい証明書は生成されません
  • 異なるホスト名で証明書を生成するには、既存の server.pem を削除してから起動してください
rm certs/server.pem
GEMINI_HOSTNAME=newhost.com php bin/server.php

クライアント側での信頼設定: Gemini Protocolはデフォルトでは自己署名証明書を信頼しません。TOFU(Trust On First Use)モデルに従い、初回接続時にクライアント側で明示的に証明書を信頼する必要があります。

設定例

例1:デフォルト設定での起動

すべての環境変数を指定しない場合の設定:

php bin/server.php

実際の値:

  • GEMINI_HOST = 0.0.0.0
  • GEMINI_PORT = 1965
  • GEMINI_DOC_ROOT = content/
  • GEMINI_CERT_DIR = certs/
  • GEMINI_HOSTNAME = localhost

例2:公開Webサーバーでの運用

export GEMINI_HOST=0.0.0.0
export GEMINI_PORT=1965
export GEMINI_DOC_ROOT=/var/www/gemini-public
export GEMINI_CERT_DIR=/etc/gemini/certs
export GEMINI_HOSTNAME=example.com

php bin/server.php

例3:ローカル開発環境

export GEMINI_HOST=127.0.0.1
export GEMINI_PORT=1965
export GEMINI_DOC_ROOT=./content
export GEMINI_CERT_DIR=./certs
export GEMINI_HOSTNAME=localhost

php bin/server.php

例4:複数インスタンスの同時実行

異なるポートで2つのインスタンスを実行:

# ターミナル1
GEMINI_PORT=1965 GEMINI_HOSTNAME=instance1.local php bin/server.php &

# ターミナル2
GEMINI_PORT=1966 GEMINI_HOSTNAME=instance2.local php bin/server.php &

例5:Docker環境での設定

Dockerfile内での環境変数指定例:

FROM php:8.1-cli

RUN apt-get update && apt-get install -y \
    php-openssl

WORKDIR /app
COPY . .
RUN composer install

ENV GEMINI_HOST=0.0.0.0
ENV GEMINI_PORT=1965
ENV GEMINI_DOC_ROOT=/app/content
ENV GEMINI_CERT_DIR=/app/certs
ENV GEMINI_HOSTNAME=container.local

CMD ["php", "bin/server.php"]

例6:Systemd サービスでの設定

/etc/systemd/system/gemini-server.service:

[Unit]
Description=Gemini Protocol Server
After=network.target

[Service]
Type=simple
User=gemini
WorkingDirectory=/opt/gemini-server
Environment="GEMINI_HOST=0.0.0.0"
Environment="GEMINI_PORT=1965"
Environment="GEMINI_DOC_ROOT=/var/www/gemini"
Environment="GEMINI_CERT_DIR=/etc/gemini/certs"
Environment="GEMINI_HOSTNAME=gemini.example.com"
ExecStart=/usr/bin/php bin/server.php
Restart=on-failure

[Install]
WantedBy=multi-user.target

環境変数の読み込みフロー

┌─────────────────────────────────────────────────────────────┐
│                     php bin/server.php                       │
└──────────────────────────┬──────────────────────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
        ▼                  ▼                  ▼
   ┌────────────┐   ┌─────────────┐   ┌──────────────┐
   │ getenv()   │   │ getenv()    │   │ getenv()     │
   │GEMINI_HOST │   │GEMINI_PORT  │   │GEMINI_DOC_   │
   │            │   │             │   │ROOT          │
   │Default:    │   │Default:     │   │Default:      │
   │0.0.0.0     │   │1965         │   │content/      │
   └────────────┘   └─────────────┘   └──────────────┘
        │                  │                  │
        └──────────────────┼──────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
        ▼                  ▼                  ▼
   ┌────────────┐   ┌─────────────┐   ┌──────────────┐
   │ getenv()   │   │ getenv()    │   │ Cert path    │
   │GEMINI_CERT │   │GEMINI_HOST  │   │resolved      │
   │_DIR        │   │NAME         │   │              │
   │            │   │             │   │              │
   │Default:    │   │Default:     │   │              │
   │certs/      │   │localhost    │   │              │
   └────────────┘   └─────────────┘   └──────────────┘
        │                  │                  │
        ├──────────────────┼──────────────────┤
        │                  │                  │
        ▼                  ▼                  ▼
   ┌──────────────────────────────────────────────────┐
   │          CertificateGenerator::generate()        │
   │                                                  │
   │  - Check if server.pem exists                    │
   │  - If not, create with hostname as CN           │
   │  - Return path                                   │
   └──────────────────────────────────────────────────┘
        │
        ▼
   ┌──────────────────────────────────────────────────┐
   │           GeminiServer initialization            │
   │                                                  │
   │  - TcpServer bound to host:port                 │
   │  - SecureServer with cert_path                  │
   │  - StaticFileHandler with docRoot               │
   │  - Event loop started                           │
   └──────────────────────────────────────────────────┘

トラブルシューティング

ポートが既に使用されている場合

エラーメッセージ:

Error: Address already in use

対処方法:

# 別のプロセスがポートを占有していないか確認
lsof -i :1965

# 別のポートを指定して起動
GEMINI_PORT=2965 php bin/server.php

ドキュメントルートが見つからない場合

動作: ファイルは配信されず、すべてのリクエストに対して「見つかりません」エラーが返されます。

対処方法:

# ディレクトリが存在することを確認
ls -la /var/www/gemini-content

# パスを絶対パスで指定
GEMINI_DOC_ROOT=/var/www/gemini-content php bin/server.php

証明書ディレクトリへの書き込み権限がない場合

エラーメッセージ:

Failed to write PEM file

対処方法:

# ディレクトリのパーミッションを確認
ls -la certs/

# 必要に応じてパーミッションを変更
chmod 755 certs/

ホスト名を変更しても新しい証明書が生成されない場合

原因: 既存の server.pem ファイルが再利用されています。

対処方法:

# 既存の証明書を削除
rm certs/server.pem

# 新しいホスト名で起動
GEMINI_HOSTNAME=newhost.com php bin/server.php

Sources

Related Pages