基本
設定は TOML ファイルで、既定の名前は nostrfy.toml です。init で作成します:
nostrfy --config nostrfy.toml init
検証してください(起動のたびに推奨):
nostrfy --config nostrfy.toml check
すべてのコマンドは --config <path> を受け付けます(既定値 nostrfy.toml)。
一般的な構文:
[section]
key = "string"
key = 8080
key = [1, 2]
key = true
設定セクション
| セクション | 目的 |
|---|
[relay] | 識別情報、URL、NIP の切り替え |
[server] | ネットワークバインド、API 分離、メトリクス |
[rpc] | NIP-86 管理 RPC(認証、本体サイズ上限) |
[limits] | すべての制限と過負荷保護 |
[database] | LMDB ストレージ、検索インデックス、キュー上限 |
[daemon] | PID、ログ、統計ファイルとローテーション |
[access] | 初期アクセス制御リスト(実行時に変更可能) |
[blossom] | Blossom ファイルサーバー(メディアホスティング) |
すべてのキーは省略可能です。指定のないキーは既定値が使われます。
セクション [relay] — リレー識別情報
| キー | 型 | 既定値 | 説明 |
|---|
name | string | "nostrfy" | NIP-11 経由でクライアントに表示されるリレー名 |
description | string | "A minimal and stable Nostr relay" | リレーの説明(NIP-11) |
pubkey | string (64 hex) | "" | 管理者の公開鍵(NIP-11 の pubkey フィールド) |
contact | string | "" | 管理者の連絡先 URI(mailto: または https://) |
icon | string | "" | リレーアイコンの画像 URL |
post_policy | string | "" | リレーの投稿ポリシーを指す URL |
private_key | string (64 hex) | "" | リレー自身の秘密鍵。NIP-29 グループに必要 |
public_url | string | "" | 公開 URL(例: wss://relay.example.com) |
livekit_url | string | "" | NIP-29 音声・映像ルーム用の LiveKit サーバー URL |
livekit_api_key | string | "" | LiveKit API キー |
livekit_api_secret | string | "" | LiveKit API シークレット(JWT の署名に使用) |
enabled_nips | array of integers | [] | 明示的な NIP 許可リスト |
disabled_nips | array of integers | [] | 無効化する NIP(enabled_nips が空でない場合は無視) |
reject_ephemeral | boolean | false | NIP-01 のエフェメラルイベント(kind 20000-29999)を拒否 |
enabled_git | boolean | false | NIP-34 git イベントを受け入れ(kind 1617-1633、30617/30618) |
require_pow | integer | 0 | 要求するプルーフ・オブ・ワークの先頭ゼロビット数 |
new_pubkey_min_age_secs | integer | 0 | これより新しい公開鍵からのイベントを拒否(秒。0 = 無効) |
max_events_per_min_per_pubkey | integer | 0 | 公開鍵ごとの投稿レート制限(1分あたり。0 = 無制限) |
max_groups | integer | 1000 | インメモリ NIP-29 グループストアの上限 |
require_auth | boolean | false | REQ/EVENT/COUNT/NEG に NIP-42 認証を要求 |
send_auth_challenge | boolean | true | 接続時に AUTH チャレンジを送信 |
enabled_nip78_auth | boolean | true | kind 78/30078 イベントの受信前に NIP-42 AUTH を要求 |
enabled_command_events | boolean | false | 管理者公開鍵が署名した kind:1 運用コマンドを実行 |
キーの詳細
- private_key — リレー自身の秘密鍵で、リレー生成イベントの署名に使用します:NIP-29 グループ
メタデータ(39000-39005)と NIP-43 のロール/メンバーシップイベント。
nostrfy genkey で生成し、厳重に
保管してください。起動時に一度だけ読み込まれるため、変更には再起動が必要です。 - public_url — クライアント由来の URL 付きタグの検証に使用します:NIP-42 AUTH、NIP-62 vanish、
NIP-98 管理認証。空の場合、リレーは
host:port にフォールバックしますが、0.0.0.0 や 127.0.0.1 にバインドしている場合は実際のクライアント URL と一致せず(警告が記録されます)。 必ず設定してください。 - enabled_nips と disabled_nips — 許可リストが優先されます:
enabled_nips が
空でない場合、その NIP のみが広告され、disabled_nips は無視されます。どちらも再起動が必要です。 - reject_ephemeral — kind 20000-29999 は拒否されますが、NIP が転送を要求する除外 kind は引き続き
転送されます:22242、27235、28934/28935/28936、24133、23194/23195、24242、21059。SIGHUP で適用されます。
- enabled_git — オプトインの NIP-34:kind 1617-1633 および 30617/30618 を受け入れ、NIP-34 を広告します。
パッチペイロードが大きくなる可能性があるため既定では無効です。SIGHUP で適用されます。
セクション [server] — サーバー設定
| キー | 型 | 既定値 | 説明 |
|---|
host | string | "127.0.0.1" | バインドアドレス。0.0.0.0 はどこからでも接続を受け付けます |
port | integer | 8080 | ポート(1-65535)。ポート 80 には root が必要 |
api_host | string | "" | REST API 専用のホスト名 |
metrics_enabled | boolean | true | /metrics で Prometheus メトリクスを提供 |
ws_paths | string | "root" | WebSocket エンドポイントのパス:root、inbox-outbox、all |
inbox_write_policy | string | "any" | /inbox への書き込み許可:"any" または "relay"(イベントには p タグが必須) |
outbox_write_policy | string | "any" | /outbox への書き込み許可:"any"(NIP-42 認証済み公開鍵自身のイベント)または "relay" |
trusted_proxies | array of strings | [] | X-Forwarded-For を信頼するリバースプロキシのアドレス/CIDR(空 = プロキシを信頼しない) |
キーの詳細
- host —
0.0.0.0 はすべての IPv4 インターフェースにバインドします。127.0.0.1 はローカルのみです。 - port — 1-65535。ポート 80 には root が必要です。この 1 つのポートで WebSocket リレー、NIP-11 文書、REST API、NIP-86 RPC をまとめて提供します。
- api_host — REST API を単一ホスト名に専用化し、リバースプロキシ配下で API とリレーが1つのポートを共有できるようにします。起動時に固定 — 再起動が必要です。
- ws_paths —
root は / のみ、inbox-outbox は /inbox と /outbox のみ、all は両方を提供します。起動時に固定 — 再起動が必要です。 - trusted_proxies — プロキシ自身のアドレスのみを列挙します(同一ホストの nginx/Caddy ならループバック、クラウドなら
バランサーの送信元範囲)。設定すると、クライアント IP は信頼できない最後の
X-Forwarded-For エントリから導出され、IP ごとの上限、レート制限、blockip、ログに使用されます。クライアントが直接到達できるアドレスは
絶対に追加しないでください — ヘッダーを偽装して IP ごとの制限を回避される恐れがあります。起動時に固定 — 再起動が必要です。
セクション [rpc] — NIP-86 管理
| キー | 型 | 既定値 | 説明 |
|---|
management_token | string | "" | 管理 API 用の Bearer トークン |
admin_pubkey | string (64 hex) | "" | NIP-98 管理認証用の管理者公開鍵 |
max_admin_body_bytes | integer | 65536 | NIP-86 管理 RPC の本体サイズ上限 |
NIP-86 RPC はリレーの公開 POST / ルートにマウントされます — 専用の管理ポートはありません。management_token と admin_pubkey が古いガイドで [server] 配下に記載されることがありますが、これらはこの [rpc] キーの旧来の別名です。
セクション [limits] — 制限と保護
接続とメッセージ
| キー | 型 | 既定値 | 説明 |
|---|
max_connections | integer | 10000 | 最大同時接続数 |
max_connections_per_ip | integer | 64 | 送信元 IP ごとの最大接続数 |
max_ws_message_bytes | integer | 1048576 | WebSocket メッセージ/フレームあたりの最大バイト数 |
socket_recv_buffer_kb | integer | 64 | 接続ごとのカーネル受信バッファ(KiB) |
max_out_queue_bytes | integer | 262144 | 接続ごとの送信キュー上限(バイト) |
ws_idle_timeout_secs | integer | 300 | アイドル接続をこの時間後に切断 |
http_read_timeout_secs | integer | 30 | HTTP リクエストヘッドのタイムアウト(slow-loris 対策) |
max_connections_per_sec_per_ip | integer | 0 | 送信元 IP ごとの1秒あたりの最大新規接続数 |
サブスクリプションとクエリ
| キー | 型 | 既定値 | 説明 |
|---|
max_filters | integer | 20 | REQ あたりの最大フィルター数 |
max_subscriptions | integer | 20 | 接続あたりの最大サブスクリプション数 |
max_limit | integer | 500 | REQ limit の上限 |
max_count | integer | 2000 | COUNT 結果の上限 |
max_sub_id_len | integer | 64 | サブスクリプション ID の最大長(バイトではなく文字数) |
max_sub_bytes | integer | 1048576 | 接続あたりのサブスクリプションフィルター合計バイト数 |
max_req_response_bytes | integer | 33554432 (32 MB) | 1回の REQ 応答が送信できる合計バイト数の上限 |
イベント
| キー | 型 | 既定値 | 説明 |
|---|
max_content_bytes | integer | 65536 | イベントコンテンツの最大文字数 |
max_tags | integer | 2000 | イベントあたりの最大タグ数 |
max_tag_value_bytes | integer | 1024 | タグ値1つあたりの最大バイト数 |
max_created_at_future_secs | integer | 3600 | created_at の未来方向の許容ずれ |
group_late_publish_secs | integer | 3600 | NIP-29 グループ管理イベントの許容遅延(秒) |
max_neg_items | integer | 100000 | NIP-77 negentropy 同期あたりの最大レコード数 |
旧来の別名:limits.require_pow、limits.new_pubkey_min_age_secs、 limits.max_indexed_words は引き続き relay.require_pow、 relay.new_pubkey_min_age_secs、database.max_indexed_words の別名として受け付けられます。
REST API
| キー | 型 | 既定値 | 説明 |
|---|
max_api_concurrent | integer | 8 | /api/v1 リクエストの最大同時実行数 |
max_api_limit | integer | 5000 | API limit パラメータの上限 |
max_api_offset | integer | 50000 | API offset パラメータの上限 |
max_api_fetch | integer | 55001 | offset クエリの最大オーバーフェッチ幅 — max_api_offset + max_api_limit + 1 をカバーする必要があります(0 = 上限なし) |
max_api_search_bytes | integer | 2048 | API search パラメータの最大バイト数 |
ライブファンアウト
| キー | 型 | 既定値 | 説明 |
|---|
live_batch_interval_ms | integer | 20 | ライブイベントのフラッシュ間隔(ミリ秒) |
live_batch_size | integer | 32 | ライブバッチあたりの最大イベント数 |
live_buffer | integer | 65536 | ライブファンアウトのキューサイズ |
セクション [database] — データベース
| キー | 型 | 既定値 | 説明 |
|---|
path | string | "./data" | データベースディレクトリ(LMDB) |
max_dbs | integer | 32 | LMDB の最大名前付きデータベース数 |
max_readers | integer | 128 | LMDB の最大同時リーダー数 |
map_size | integer | 1073741824 (1 GB) | メモリマップサイズの下限(バイト) |
max_map_size | integer | 1099511627776 (1 TB) | メモリマップの上限(バイト) |
purge_interval_secs | integer | 300 | NIP-40 パージ間隔(秒) |
search_index | boolean | true | NIP-50 単語インデックスを有効化 |
reader_threads | integer | 2 | スキャン専用スレッド数 |
max_indexed_words | integer | 32 | 各イベントの content のうち検索用に索引付けする単語数 |
meta_index | boolean | true | スキャンの事前フィルターが使うイベントごとのメタデータヘッダーを書き込む |
disabled_fsync | boolean | false | 書き込みバッチごとの同期ディスクフラッシュを省略 |
db_buffer_size | integer | 2048 | 接続ごとの初期 WebSocket バッファ(バイト) |
db_request_timeout_secs | integer | 30 | データベース要求が失敗するまで待機できる時間 |
max_db_queue_msgs | integer | 4096 | 高速失敗までにキューできる保留メッセージの上限 |
max_db_queue_events | integer | 262144 | 高速失敗までにキュー済みバッチ内に収められるイベントの上限 |
max_db_queue_bytes | integer | 268435456 (256 MiB) | 高速失敗までにキューできるデータベース要求のバイト数上限(0 = バイト上限なし) |
キーの詳細
- map_size — メモリマップの下限です。マップは常に最低でもこのサイズで開かれます。
- max_map_size — 上限で、スパースな仮想予約として開かれます。物理ディスクは実際に書き込まれたデータ分だけ
増加します。
database map is full が出たら引き上げてください。 - search_index = false — 検索は引き続き動作します(content に対する完全一致スキャン)が、スキャンは
遅くなります。小規模 VPS ではデータベースが半分程度になります。小規模インスタンスにおすすめです。
- disabled_fsync — 耐久性とスループットのトレードオフです。書き込みは OS のページキャッシュにコミットされ、
電源喪失時には直近の書き込みが失われる可能性があります。
セクション [daemon] — デーモン
| キー | 型 | 既定値 | 説明 |
|---|
pid_file | string | "./nostrfy.pid" | PID ファイルのパス |
log_file | string | "./nostrfy.log" | ログファイルのパス |
stats_file | string | "./nostrfy.stats.json" | 統計ファイルのパス |
stats_interval_secs | integer | 5 | 統計の書き込み間隔(秒) |
max_log_size_bytes | integer | 52428800 (50 MB) | ログローテーションのサイズ(0 = ローテーションなし) |
max_log_files | integer | 5 | 保持するローテーション済みログの世代数 |
パスは設定ファイルのあるディレクトリを基準に解決されるため、デーモンが作業ディレクトリを変更した後も有効です。
セクション [access] — アクセス制御
| キー | 型 | 既定値 | 説明 |
|---|
restrict_relay | boolean | false | 許可リストの公開鍵のみ投稿可能 |
blocked_kinds | array of integers | [] | 拒否する kind |
allowed_kinds | array of integers | [] | kind 許可リスト。空でない場合はこれらの kind のみ受け入れ |
blocked_ips | array of strings | [] | 接続時に拒否する IP アドレス |
method_grants | table: pubkey → array of strings | {} | 非管理者公開鍵への NIP-86 メソッド許可(実行時は assignmethod で管理) |
公開鍵の許可/拒否リストは設定キーではありません — リレーデータベース(LMDB)に格納され、実行時に管理します:
nostrfy relay allow npub1...
nostrfy relay deny npub1...
nostrfy relay list
- restrict_relay = true — 許可リストの公開鍵のみが投稿できますが、読み取りは全員に開放されたままです
(どのクライアントも購読・取得できます)。
- 拒否された公開鍵は、投稿時は常に拒否され、読み取り時にも決して提供されません。
- method_grants — 非管理者公開鍵への NIP-86 メソッド許可(公開鍵 → メソッド名。例:モデレーターに
banevent と listbannedevents を許可)。初回起動時に設定から投入し、以後は NIP-86 の assignmethod/unassignmethod で実行時に管理します(listmethodassignees で確認)。付与可能なのはモデレーション系と読み取り系メソッドのみです —
権限・ロール・招待・リレー識別情報の管理は管理者のみで、BAN 済み公開鍵は許可があっても拒否されます。詳しくは 管理 API を参照してください。
セクション [blossom] — Blossom ファイルサーバー
| キー | 型 | 既定値 | 説明 |
|---|
host | string | "" | Blossom サーバーのホスト名(空 = 無効) |
storage | string | "local" | バックエンド:"local"(local_path)または "s3"(S3 互換バケット) |
local_path | string | "/var/lib/nostrfy/images" | メディアファイルのローカルストレージルート |
max_upload_bytes | integer | 20971520 (20 MB) | メディアファイルの最大サイズ |
min_free_bytes | integer | 33554432 (32 MB) | これを下回るとアップロードを拒否する空き容量 |
s3_endpoint | string | "" | S3 互換エンドポイント(例: R2) |
s3_region | string | "" | S3 リージョン(R2 は "auto") |
s3_bucket | string | "" | S3 バケット名 |
s3_access_key | string | "" | S3 アクセスキー |
s3_secret_key | string | "" | S3 シークレットキー |
restrict_uploads | boolean | false | 許可リストの公開鍵のみアップロード可能 |
実行時のリロード(SIGHUP)
ファイルを編集して kill -HUP $(cat nostrfy.pid) を送ると、設定を再起動なしでリロードします。
ほとんどの設定は即時に反映されますが、一部は起動時に固定されます:
| SIGHUP で適用 | 再起動が必要 |
|---|
| relay.name, description, pubkey, contact, icon, post_policy, public_url | relay.private_key |
| reject_ephemeral, enabled_git, enabled_nip78_auth | relay.livekit_*, enabled_nips / disabled_nips |
| [limits] のほとんど | api_host, trusted_proxies, metrics_enabled, ws_paths, database.*, daemon サイズ, 上限値, blossom.* |
[access] はリロードでは適用されません — リストは起動時に一度だけ投入され、以後は NIP-86 経由で実行時に管理します。
再起動が必要な設定が変更された場合はログに警告が出ますが、起動時に取り込んだ一部設定はリロードのチェック対象外です。
| 間違い | 修正 |
|---|
| public_url 未設定 | wss://... を設定 |
| host が 127.0.0.1 のまま | 外部クライアントは接続できません |
| NIP-29 で private_key 未設定 | nostrfy genkey を実行+再起動 |
| restrict_relay が true で許可リストが空 | 全員締め出しになります |
| 再起動専用キーを変更して SIGHUP のみ送信 | nostrfy restart を使用 |