Référence de configuration

Référence complète pour nostrfy.toml : chaque clé, son type, sa valeur par défaut et exactement ce qu’elle fait — limites, base de données, démon, contrôle d’accès et Blossom.

Bases

La configuration est un fichier TOML, par défaut nommé nostrfy.toml. Créez-le avec init :

sh
nostrfy --config nostrfy.toml init

Validez-le (recommandé avant chaque démarrage) :

sh
nostrfy --config nostrfy.toml check

Chaque commande accepte --config <path> (par défaut nostrfy.toml).

Syntaxe générale :

toml
[section]
key = "string"
key = 8080
key = [1, 2]
key = true

Sections de configuration

SectionObjet
[relay]Identité, URLs et interrupteurs NIP
[server]Liaison réseau, séparation API, métriques
[rpc]RPC de gestion NIP-86 (auth, limite de corps)
[limits]Toutes les limites et protections contre la surcharge
[database]Stockage LMDB, index de recherche, plafonds de file
[daemon]Fichiers PID, journal et statistiques, et rotation
[access]Listes de contrôle d’accès initiales (modifiables à l’exécution)
[blossom]Serveur de fichiers Blossom (hébergement média)

Chaque clé est optionnelle ; une clé manquante utilise sa valeur par défaut.

Section [relay] — identité du relais

CléTypeDéfautDescription
namestring"nostrfy"Nom du relais affiché aux clients via NIP-11
descriptionstring"A minimal and stable Nostr relay"Description du relais (NIP-11)
pubkeystring (64 hex)""Clé publique de l’administrateur (champ pubkey NIP-11)
contactstring""URI de contact de l’administrateur (mailto: ou https://)
iconstring""URL de l’image d’icône du relais
post_policystring""URL pointant vers la politique de publication du relais
private_keystring (64 hex)""Clé secrète propre au relais ; requise pour les groupes NIP-29
public_urlstring""URL publique, p. ex. wss://relay.example.com
livekit_urlstring""URL du serveur LiveKit pour les salons audio/vidéo NIP-29
livekit_api_keystring""Clé API LiveKit
livekit_api_secretstring""Secret API LiveKit (utilisé pour signer les JWT)
enabled_nipsarray of integers[]Liste d’autorisation NIP explicite
disabled_nipsarray of integers[]NIPs à désactiver (ignoré quand enabled_nips est non vide)
reject_ephemeralbooleanfalseRejeter les événements éphémères NIP-01 (kinds 20000–29999)
enabled_gitbooleanfalseAccepter les événements git NIP-34 (kinds 1617–1633, 30617/30618)
require_powinteger0Preuve de travail requise en bits zéro initiaux
new_pubkey_min_age_secsinteger0Refuser les événements des pubkeys plus jeunes que cette valeur (secondes ; 0 = désactivé)
max_events_per_min_per_pubkeyinteger0Limite de débit de publication par pubkey (par minute ; 0 = sans limite)
max_groupsinteger1000Plafond du magasin de groupes NIP-29 en mémoire
require_authbooleanfalseExiger l’authentification NIP-42 pour REQ/EVENT/COUNT/NEG
send_auth_challengebooleantrueEnvoyer le défi AUTH à la connexion
enabled_nip78_authbooleantrueExiger AUTH NIP-42 avant d’accepter les événements kind 78/30078
enabled_command_eventsbooleanfalseExécuter les commandes opérateur kind:1 rédigées par la pubkey admin

Détails des clés

  • private_key — clé secrète propre au relais, utilisée pour signer les événements générés par le relais : métadonnées de groupes NIP-29 (39000–39005) et événements de rôles/membres NIP-43. Générez-la avec nostrfy genkey ; gardez-la secrète. Elle est lue une fois au démarrage, donc toute modification exige un redémarrage.
  • public_url — utilisée pour valider les tags porteurs d’URL des clients : AUTH NIP-42, vanish NIP-62 et auth admin NIP-98. Quand elle est vide, le relais se replie sur host:port, qui ne correspond jamais à une vraie URL client lors de la liaison à 0.0.0.0 ou 127.0.0.1 (un avertissement est journalisé). Définissez-la toujours.
  • enabled_nips vs disabled_nips — la liste d’autorisation l’emporte : quand enabled_nips est non vide, seuls ses NIPs sont annoncés et disabled_nips est ignoré. Les deux exigent un redémarrage.
  • reject_ephemeral — les kinds 20000–29999 sont rejetés, mais les kinds exemptés que les NIPs exigent de relayer sont toujours transmis : 22242, 27235, 28934/28935/28936, 24133, 23194/23195, 24242 et 21059. S’applique sur SIGHUP.
  • enabled_git — opt-in NIP-34 : accepte les kinds 1617–1633 et 30617/30618 et annonce NIP-34. Désactivé par défaut car les charges de patch peuvent être volumineuses. S’applique sur SIGHUP.

Section [server] — paramètres serveur

CléTypeDéfautDescription
hoststring"127.0.0.1"Adresse de liaison ; 0.0.0.0 accepte les connexions de partout
portinteger8080Port (1–65535) ; le port 80 exige root
api_hoststring""Nom d’hôte dédié à l’API REST
metrics_enabledbooleantrueServir les métriques Prometheus sur /metrics
ws_pathsstring"root"Chemins des points de terminaison WebSocket : root, inbox-outbox ou all
inbox_write_policystring"any"Qui peut écrire sur /inbox : « any » ou « relay » (les événements doivent toujours porter un tag p)
outbox_write_policystring"any"Qui peut écrire sur /outbox : « any » (propres événements de la pubkey authentifiée NIP-42) ou « relay »
trusted_proxiesarray of strings[]Adresses/CIDRs de reverse-proxy dont le X-Forwarded-For est de confiance (vide = aucun proxy de confiance)

Détails des clés

  • host — 0.0.0.0 lie toutes les interfaces IPv4 ; 127.0.0.1 est local uniquement.
  • port — 1–65535 ; le port 80 exige root. Ce port unique sert ensemble le relais WebSocket, le document NIP-11, l’API REST et le RPC NIP-86.
  • api_host — dédie l’API REST à un seul nom d’hôte pour que l’API et le relais puissent partager un port derrière un reverse-proxy. Figé au démarrage — exige un redémarrage.
  • ws_paths — root sert uniquement /, inbox-outbox sert uniquement /inbox et /outbox, all sert les deux. Figé au démarrage — exige un redémarrage.
  • trusted_proxies — listez uniquement les propres adresses du proxy (loopback pour nginx/Caddy sur le même hôte, plage source de l’équilibreur dans le cloud). Si défini, l’IP client est dérivée de la dernière entrée X-Forwarded-For non de confiance pour les plafonds par IP, la limite de débit, blockip et les logs. N’ajoutez jamais une adresse joignable directement par les clients — ils pourraient falsifier l’en-tête et contourner les limites par IP. Figé au démarrage — exige un redémarrage.

Section [rpc] — gestion NIP-86

CléTypeDéfautDescription
management_tokenstring""Jeton Bearer pour les API de gestion
admin_pubkeystring (64 hex)""Pubkey administrateur pour l’auth de gestion NIP-98
max_admin_body_bytesinteger65536Limite de corps pour le RPC de gestion NIP-86

Le RPC NIP-86 est monté sur les routes publiques POST / du relais — il n’y a pas de port de gestion séparé. management_token et admin_pubkey apparaissent parfois sous [server] dans les anciens guides ; ces orthographes sont des alias historiques de ces clés [rpc].

Section [limits] — limites et protections

Connexions et messages

CléTypeDéfautDescription
max_connectionsinteger10000Connexions simultanées maximales
max_connections_per_ipinteger64Max. de connexions par IP source
max_ws_message_bytesinteger1048576Max. d’octets par message/frame WebSocket
socket_recv_buffer_kbinteger64Tampon de réception noyau par connexion (Kio)
max_out_queue_bytesinteger262144Plafond de file sortante par connexion (octets)
ws_idle_timeout_secsinteger300Fermer les connexions inactives après ce délai
http_read_timeout_secsinteger30Délai d’en-tête de requête HTTP (défense slow-loris)
max_connections_per_sec_per_ipinteger0Max. de nouvelles connexions par seconde par IP source

Abonnements et requêtes

CléTypeDéfautDescription
max_filtersinteger20Max. de filtres par REQ
max_subscriptionsinteger20Max. d’abonnements par connexion
max_limitinteger500Plafond pour la limite REQ
max_countinteger2000Plafond pour les résultats COUNT
max_sub_id_leninteger64Longueur max. d’id d’abonnement (caractères, pas octets)
max_sub_bytesinteger1048576Total d’octets de filtres d’abonnement par connexion
max_req_response_bytesinteger33554432 (32 Mo)Plafond pour le total d’octets qu’une seule réponse REQ peut envoyer

Événements

CléTypeDéfautDescription
max_content_bytesinteger65536Longueur max. du contenu d’événement en caractères
max_tagsinteger2000Max. de tags par événement
max_tag_value_bytesinteger1024Max. d’octets par valeur de tag
max_created_at_future_secsinteger3600Écart futur toléré de created_at
group_late_publish_secsinteger3600Retard toléré pour les événements admin de groupes NIP-29 (secondes)
max_neg_itemsinteger100000Max. d’enregistrements par synchronisation negentropy NIP-77

Alias historiques : limits.require_pow, limits.new_pubkey_min_age_secs et limits.max_indexed_words sont toujours acceptés comme alias de relay.require_pow, relay.new_pubkey_min_age_secs et database.max_indexed_words.

API REST

CléTypeDéfautDescription
max_api_concurrentinteger8Max. de requêtes /api/v1 simultanées
max_api_limitinteger5000Plafond pour le paramètre limit de l’API
max_api_offsetinteger50000Plafond pour le paramètre offset de l’API
max_api_fetchinteger55001Fenêtre de sur-récupération max. pour les requêtes offset — doit couvrir max_api_offset + max_api_limit + 1 (0 = sans borne)
max_api_search_bytesinteger2048Max. d’octets du paramètre search de l’API

Diffusion live

CléTypeDéfautDescription
live_batch_interval_msinteger20Fréquence de vidage des événements live (ms)
live_batch_sizeinteger32Max. d’événements par lot live
live_bufferinteger65536Taille de la file de diffusion live

Section [database] — base de données

CléTypeDéfautDescription
pathstring"./data"Répertoire de la base de données (LMDB)
max_dbsinteger32Max. de bases nommées LMDB
max_readersinteger128Max. de lecteurs simultanés LMDB
map_sizeinteger1073741824 (1 Go)Plancher pour la taille du memory map (octets)
max_map_sizeinteger1099511627776 (1 TB)Plafond du memory-map (octets)
purge_interval_secsinteger300Intervalle de purge NIP-40 (secondes)
search_indexbooleantrueActiver l’index de mots NIP-50
reader_threadsinteger2Threads de scan dédiés
max_indexed_wordsinteger32Mots du contenu de chaque événement indexés pour la recherche
meta_indexbooleantrueÉcrire l’en-tête de métadonnées par événement utilisé par le préfiltre de scan
disabled_fsyncbooleanfalseIgnorer le vidage disque synchrone après chaque lot d’écriture
db_buffer_sizeinteger2048Tampon WebSocket initial par connexion (octets)
db_request_timeout_secsinteger30Durée d’attente possible d’une requête base avant échec
max_db_queue_msgsinteger4096Max. de messages en attente avant échec rapide
max_db_queue_eventsinteger262144Max. d’événements dans les lots en attente avant échec rapide
max_db_queue_bytesinteger268435456 (256 MiB)Max. d’octets de requêtes base en file avant échec rapide (0 = sans plafond d’octets)

Détails des clés

  • map_size — le plancher pour le memory map : la map est toujours ouverte au moins à cette taille.
  • max_map_size — le plafond, ouvert comme réservation virtuelle éparse : le disque physique ne croît qu’avec les données réellement écrites. Augmentez-le en cas de database map is full.
  • search_index = false — la recherche fonctionne toujours (correspondance de mots entiers dans le contenu) mais les scans sont plus lents ; sur un petit VPS cela divise la base par deux. Recommandé sur les petites instances.
  • disabled_fsync — échange la durabilité contre le débit : les écritures sont validées dans le cache de pages OS et une coupure de courant peut perdre les écritures les plus récentes.

Section [daemon] — démon

CléTypeDéfautDescription
pid_filestring"./nostrfy.pid"Chemin du fichier PID
log_filestring"./nostrfy.log"Chemin du fichier log
stats_filestring"./nostrfy.stats.json"Chemin du fichier de statistiques
stats_interval_secsinteger5Intervalle d’écriture des statistiques (secondes)
max_log_size_bytesinteger52428800 (50 Mo)Taille de rotation des logs (0 = sans rotation)
max_log_filesinteger5Générations de logs pivotés à conserver

Les chemins sont résolus par rapport au répertoire du fichier de configuration, donc ils restent valides après que le démon change son répertoire de travail.

Section [access] — contrôle d’accès

CléTypeDéfautDescription
restrict_relaybooleanfalseSeules les pubkeys autorisées peuvent publier
blocked_kindsarray of integers[]Kinds à rejeter
allowed_kindsarray of integers[]Liste d’autorisation de kinds ; seuls ces kinds sont acceptés quand elle est non vide
blocked_ipsarray of strings[]Adresses IP refusées au moment de la connexion
method_grantstable: pubkey → array of strings{}Octrois de méthodes NIP-86 pour les pubkeys non-admin (gérés à l’exécution avec assignmethod)

Les listes d’autorisation/refus de pubkeys ne sont pas des clés de config — elles vivent dans la base du relais (LMDB) et sont gérées à l’exécution :

sh
nostrfy relay allow npub1...
nostrfy relay deny npub1...
nostrfy relay list
  • restrict_relay = true — seules les pubkeys autorisées peuvent publier, tandis que la lecture reste ouverte à tous (tout client peut toujours s’abonner et récupérer).
  • Une pubkey refusée est toujours rejetée à la publication et jamais servie à la lecture.
  • method_grants — octrois de méthodes NIP-86 pour les pubkeys non-admin (pubkey → noms de méthodes, p. ex. un modérateur autorisé avec banevent et listbannedevents). Initialisés depuis la config au premier lancement, puis gérés à l’exécution avec NIP-86 assignmethod/unassignmethod (inspectés avec listmethodassignees). Seules les méthodes de modération et de lecture sont octroyables — la gestion des permissions, rôles, revendications d’invitation et identité du relais reste réservée à l’admin, et une pubkey bannie est refusée même avec des octrois. Voir l' API de gestion.

Section [blossom] — serveur de fichiers Blossom

CléTypeDéfautDescription
hoststring""Nom d’hôte pour le serveur Blossom (vide = désactivé)
storagestring"local"Backend : « local » (local_path) ou « s3 » (bucket compatible S3)
local_pathstring"/var/lib/nostrfy/images"Racine de stockage local pour les fichiers média
max_upload_bytesinteger20971520 (20 Mo)Taille max. de fichier média
min_free_bytesinteger33554432 (32 Mo)Espace disque sous lequel les téléversements sont refusés
s3_endpointstring""Point de terminaison compatible S3 (p. ex. R2)
s3_regionstring""Région S3 (R2 utilise « auto »)
s3_bucketstring""Nom du bucket S3
s3_access_keystring""Clé d’accès S3
s3_secret_keystring""Clé secrète S3
restrict_uploadsbooleanfalseSeules les pubkeys autorisées peuvent téléverser

Rechargement à l’exécution (SIGHUP)

Modifier le fichier et envoyer kill -HUP $(cat nostrfy.pid) recharge la configuration sans redémarrage. La plupart des réglages prennent effet immédiatement ; quelques-uns sont figés au démarrage :

S’applique sur SIGHUPExige un redémarrage
relay.name, description, pubkey, contact, icon, post_policy, public_urlrelay.private_key
reject_ephemeral, enabled_git, enabled_nip78_authrelay.livekit_*, enabled_nips / disabled_nips
la plupart des limitesapi_host, trusted_proxies, metrics_enabled, ws_paths, database.*, tailles du démon, plafonds de limites, blossom.*

[access] n’est pas appliqué par un rechargement — les listes sont initialisées une fois au démarrage puis gérées à l’exécution via NIP-86. Le log avertit quand un réglage exigeant un redémarrage a changé, et quelques réglages capturés au démarrage ne sont pas vérifiés par le rechargement.

Erreurs fréquentes
ErreurCorrectif
public_url non définidéfinissez wss://...
host laissé à 127.0.0.1les clients externes ne peuvent pas se connecter
private_key non définie avec NIP-29exécutez nostrfy genkey + redémarrage
restrict_relay true avec allowlist videtout le monde est verrouillé
clés exigeant un redémarrage modifiées avec seulement un SIGHUPutilisez nostrfy restart