Environment variables are used to manage how the relay works.
.env.example
contains complete list of possible settings with their default values
Some settings are used for deployment, i.e. database URL or number of processes for application server.
Some settings are used to control business logic and supported NIPs.
First let's discuss business logic settings.
Variable | Description | Default value | Notes |
---|---|---|---|
HEARBEAT_INTERVAL | amount of time connections are allowed to be idle | 1200 | seconds |
RATE_LIMITING_SLIDING_WINDOW | requests are counted during this amount of time | 60 | seconds |
RATE_LIMITING_MAX_REQUESTS | so many requests are available during time window | 300 | per IP address |
WS_DEFLATE_ENABLED | whether to enable websockets permessage deflate extension | true | |
WS_DEFLATE_LEVEL | compression level | 9 | |
WS_DEFLATE_MAX_WINDOW_BITS | sliding window bits | 15 | |
LATEST_EVENTS_WINDOW | how old (in days) events are considered latest | 7 | bigger value may lead to better query performance but more memory required for indexes |
DEFAULT_ERRORS_FORMAT | other option is JSON or "as is" | TEXT | experimental |
AUTHORIZATION_TIMEOUT | when NIP-43 min auth_level > 0 connection is blocked until authorization request is processed. This value defines timeout in seconds | 10 | seconds |
FORCED_MIN_AUTH_LEVEL | Authorization is implemented in levels, see here for more details | 0 | |
REQUIRED_AUTH_LEVEL_FOR_REQ | min auth_level to execute REQ events |
0 | same applies to CLOSE events |
REQUIRED_AUTH_LEVEL_FOR_EVENT | min auth_level to execute EVENT events |
0 | |
REQUIRED_AUTH_LEVEL_FOR_COUNT | min auth_level to execute COUNT events |
0 | |
MAILER_DEFAULT_FROM | system emails will be sent on behalf of this address | [email protected] | |
DEFAULT_FILTER_LIMIT | If filters in REQ event do not have limit this values applies |
100 | |
VALIDATE_ID_ON_SERVER | whether to validate payload matches id on the server |
true | This is already checked by WebsocketServer and is time-consuming but for consistency it is enabled by default |
VALIDATE_SIG_ON_SERVER | whether to validate sig matches id on the server |
true | This is already checked by WebsocketServer and is time-consuming but for consistency it is enabled by default |
NIP_04_NIP_42_ENFORCE_KIND_4_AUTHENTICATION | If enforced, kind-4 events will only be sent by relay to those subscribers who are authenticated and have pubkey matching event's author pubkey or event's p-tag | true | |
NIP_11_MAX_FILTER_LIMIT | see NIP-11 | 1000 | |
NIP_11_RELAY_NAME | see NIP-11 | ||
NIP_11_DESCRIPTION | see NIP-11 | ||
NIP_11_PUBKEY | see NIP-11 | ||
NIP_11_CONTACT | see NIP-11 | ||
NIP_11_RELAY_COUNTRIES | see NIP-11 | UK UA US | |
NIP_11_LANGUAGE_TAGS | see NIP-11 | en en-419 | |
NIP_11_TAGS | see NIP-11 | ||
NIP_11_POSTING_POLICY | see NIP-11 | ||
NIP_11_MAX_SUBSCRIPTIONS | see NIP-11 | 20 | |
NIP_11_MAX_FILTERS | see NIP-11 | 100 | |
NIP_11_MAX_EVENT_TAGS | see NIP-11 | 100 | |
NIP_11_MAX_CONTENT_LENGTH | see NIP-11 | 8196 | |
NIP_11_MAX_MESSAGE_LENGTH | see NIP-11 | 16384 | |
NIP_12_MAX_SEARCHABLE_TAG_VALUE_LENGTH | single letter tags with values longer than this value won't be indexed | 1000 | |
NIP_13_MIN_POW | validate event's id has minimum difficulty |
0 | |
NIP_22_CREATED_AT_IN_PAST | oldest event to be persisted | 31556952 | seconds (default is 1 year) |
NIP_22_CREATED_AT_IN_FUTURE | the most futuristic event to be persisted | 7889238 | seconds (default is 3 months) |
NIP_42_RESTRICT_CHANGE_AUTH_PUBKEY | should it be possible to send different kind-22242 singed by different keys to change already authenticated pubkey | false | if disabled, clients should reconnect to authenticate other pubkey |
NIP_42_CHALLENGE_WINDOW_SECONDS | how much time NIP-42 auth challenge is valid for in seconds | 600 | |
NIP_43_FAST_AUTH_WINDOW_SECONDS | how much time client has between generating kind-22242 event and using it for authentication | 80 | |
NIP_42_43_SELF_URL | this should be equal to what users will add to their clients | ws://localhost:3000 | in fact, only host name is used for validation but this should be a valid URL |
NIP_45_COUNT_COST_THRESHOLD | PostgreSQL cost at which COUNT queries will calculate approximate result |
0 | higher number may lead to performance issues; set this value to 0 to always get exact results; accuracy of approximate result depends on many factors of how PostgreSQL is configured and maintained |
NIP_50_DEFAULT_LANGUAGE | PostgreSQL stemming dict to use by default | simple | details: https://www.postgresql.org/docs/current/textsearch-dictionaries.html |
NIP_50_CONTENT_SEARCHABLE_KINDS | Which content types should be searchable by full text | 0 1 30023 | space separated list of kinds |
NIP_65_KINDS_EXEMPT_OF_AUTH | consider min auth_level=4 enforced for EVENT commands but we still want NIP-65 events to pass through. Here we define space delimited kinds we allow processing without authorization |
10002 | in case FORCED_MIN_AUTH_LEVEL > 0, it won't work because connection won't even be established (space delimited list) |
ADMIN_EMAIL | if specified, user with this email will be created as admin who can sign in using UI to view admin dashboard | only works once | |
ADMIN_PASSWORD | password for this user | only works once | |
TRUSTED_PUBKEYS | list of pubkeys that will have highest auth_level=4 |
space delimited list, only works once | |
SHOULD_LOG_FILTERS | log every REQ command filters | false |
Here lets review configuration related to payments:
Variable | Description | Default value | Notes |
---|---|---|---|
DEFAULT_INVOICE_AMOUNT | The value users see filled on the first page load | 6000 | sats |
DEFAULT_INVOICE_PERIOD | The value users see filled on the first page load | 30 | days |
PRICE_PER_DAY | Subscription daily price | 200 | sats |
PROVIDER_API_KEY_OPEN_NODE | Integration secret key | ||
INVOICE_TTL | How much time users have to pay the invoice | 1200 | seconds |
Now let's briefly review general app settings:
Variable | Description | Default value |
---|---|---|
POSTGRES_USER | DB username | postgres |
POSTGRES_PASSWORD | DB user password | |
POSTGRES_HOST | DB host | localhost |
POSTGRES_DATABASE | DB name | saltivka |
POSTGRES_PORT | DB port | 5432 |
POSTGRES_POOL | number of connections in the pool. Usually must match RAILS_MAX_THREADS |
5 |
REDIS_URL | URL of RedisStack service for WebsocketServer | redis://localhost:6379 |
SIDEKIQ_REDIS_URL | URL of Redis service Sidekiq worker components | redis://localhost:63790 |
REDIS_POOL_TIMEOUT | Timeout for RedisStack connections pool wait time (seconds) | 5 |
RAILS_MAX_THREADS | max number of threads per puma worker. Must be tuned responsibly but usually anything greater than 5 doesn't mean profits for puma. But keep in mind, Sidekiq worker also depends on this variable so it should be adjusted accordingly | 5 |
RAILS_MIN_THREADS | min number of threads per puma worker. With stable traffic its better to have min === max , with burst traffic min should be lower than max |
5 |
PORT | application port | 3000 |
PIDFILE | path to pidfile | tmp/pids/server.pid |
WEB_CONCURRENCY | number of puma workers (processes). Usually should match number of CPU cores but on practice should be determined based on the workload and resources | 2 |
RAILS_ENV | environment to run application, most of the time should be left default | production |
RAILS_SERVE_STATIC_FILES | Make Rails serve static file in /public directory. Most of the time Rails should run behind reverse proxy with this parameter set to false and reverse proxy to serve static assets |
|
RAILS_LOG_TO_STDOUT | logs destination | |
RAILS_LOG_LEVEL | logs level | warn |
ACTIVE_RECORD_SLOW_QUERIES_THRESHOLD | determines which queries are slow and should be logged (ms) | 1000 |
ACTIVE_RECORD_LOG_SLOW_QUERIES | whether to log slow queries or not (true/false) | false |
SECRET_KEY_BASE | some random secret string for sessions and other stuff | |
SENTRY_DSN | Sentry integration | |
NEW_RELIC_LICENSE_KEY | Newrelic integration | |
NEW_RELIC_APP_NAME | Newrelic app name | |
NEW_RELIC_LOG_LEVEL | Newrelic logs level | |
CI | run full tests suite on CI | |
RUBY_YJIT_ENABLE | enable YJIT for Ruby, its Docker-image-dependent, usually should be left default | true |