Files
Haven/.env.example

188 lines
8.9 KiB
Bash

# Server Config
PORT=3000
HOST=0.0.0.0
# Display name for this server (shown in multi-server sidebar)
SERVER_NAME=Haven
# Secret key for JWT tokens. CHANGE THIS to a long random string!
# (Auto-generated on first boot if left as default)
JWT_SECRET=change-me-to-something-random-and-long
# Your admin username (register with this name first to get admin powers)
ADMIN_USERNAME=admin
# Optional: HTTPS (required for voice chat over the internet)
# Paths are relative to the data directory:
# Windows: %APPDATA%\Haven\
# Linux/macOS: ~/.haven/
#
# Using Let's Encrypt or certbot? Point this at fullchain.pem, NOT at their
# cert.pem. Their cert.pem holds only your own certificate, without the
# intermediate one above it, and a server that hands out just the leaf gets
# rejected by curl, by most automated link checkers, and by some mobile and
# API clients. Browsers usually hide the problem by fetching the missing
# piece themselves, so the site looks fine in Chrome while other things fail
# against it. Haven's own setup-ssl script already copies fullchain.pem into
# certs/cert.pem, so the default path below is fine.
# SSL_CERT_PATH=/etc/letsencrypt/live/YOUR.DOMAIN/fullchain.pem
#
# SSL_CERT_PATH=./certs/cert.pem
# SSL_KEY_PATH=./certs/key.pem
# Force HTTP mode (useful behind a reverse proxy like Caddy, nginx, etc.)
# Set to true to skip SSL even if certificates exist.
# FORCE_HTTP=false
# Public-facing URL for OAuth/OpenID callbacks.
# Set this when the server cannot determine its own external address,
# for example Docker port mapping (8080→3000), reverse proxies that strip
# the port, or Cloudflare Tunnels. Must include the scheme (https://).
# Example: PUBLIC_URL=https://haven.example.com:8443
# PUBLIC_URL=
# Steam Web API Key: required for Steam rich presence (game activity display).
# Get yours at https://steamcommunity.com/dev/apikey (any domain name works).
# Once set, users can link their Steam account in Settings → Connections.
# STEAM_API_KEY=
# Optional: Override the data directory location
# HAVEN_DATA_DIR=
# Optional: let bot callback URLs point at private or local addresses.
# By default Haven refuses to call back to 10.x, 172.16-31.x, 192.168.x,
# localhost, .local and .internal, so a webhook can't be used to probe the
# network the server sits on. Set this to true if your bot genuinely runs
# on the same LAN or in a sibling Docker container. The same goes for push
# notification endpoints, such as a self-hosted ntfy for UnifiedPush that
# resolves to a private address from inside Haven's container. Cloud metadata
# addresses (169.254.x.x) stay blocked either way.
# HAVEN_ALLOW_PRIVATE_CALLBACKS=true
# Optional: send outgoing requests through a proxy (link previews, the media
# proxy, bot callbacks, push notifications, update and DDNS checks). Only
# http:// proxy addresses are supported. Hosts in no_proxy connect directly.
# Haven checks each name itself and sends the proxy to the checked address.
# A name Haven cannot resolve itself is refused, unless
# OUTBOUND_PROXY_RESOLVES_NAMES=true passes it to the proxy unchecked. With
# that set, the proxy's own rules decide where those requests can go, so
# restrict it to the destinations Haven needs. See "Outgoing Proxy" in GUIDE.md.
# https_proxy=http://proxy.example:3128
# http_proxy=http://proxy.example:3128
# no_proxy=localhost,127.0.0.1
# OUTBOUND_PROXY_RESOLVES_NAMES=true
# Optional: Override STUN servers for voice/WebRTC.
# Default: stun.stunprotocol.org + stun.nextcloud.com
# Comma-separated list of STUN URIs. Set this to point at your own coturn
# or any STUN server for fully self-hosted voice with no external dependencies.
# STUN_URLS=stun:your-server.com:3478,stun:backup-server.com:3478
# Optional: TURN server for voice/screen sharing across the internet.
# Without TURN, voice only works on the same network (LAN).
# Recommended: run coturn on the same box or a cheap VPS.
#
# Option A: Shared secret (coturn --use-auth-secret, recommended):
# TURN_URL=turn:your-server.com:3478
# TURN_SECRET=your-coturn-static-auth-secret
# A value with a # in it needs quotes (TURN_SECRET="ab#cd"); without them
# everything from the # on is ignored.
#
# Option B: Static credentials:
# TURN_URL=turn:your-server.com:3478
# TURN_USERNAME=haven
# TURN_PASSWORD=your-password
# GIF search: GIPHY (https://developers.giphy.com/). A supported provider.
# GIPHY_API_KEY=
# GIF search: KLIPY (https://klipy.com/developers). A supported provider.
# KLIPY_API_KEY=
# Legacy only: Tenor is no longer supported for new setup. Still read if no other key is set.
# TENOR_API_KEY=
# Which provider to use when more than one key is set: klipy, giphy, or tenor.
# If unset or invalid, falls back to GIPHY, then KLIPY, then Tenor.
# PREFERRED_GIF_SEARCH=
# ── Dynamic DNS auto-updater ─────────────────────────────
# Keeps a DNS record pointed at this server's current public IP so your
# domain (e.g. anchaven.duckdns.org) never goes stale when your ISP
# rotates your IP. Disabled unless DDNS_PROVIDER is set.
#
# DuckDNS:
# DDNS_PROVIDER=duckdns
# DDNS_DOMAINS=your-subdomain (no .duckdns.org, comma-separated for multiple)
# DDNS_TOKEN=your-duckdns-token (from https://www.duckdns.org/)
#
# Cloudflare:
# DDNS_PROVIDER=cloudflare
# DDNS_CF_API_TOKEN=... (token with Zone:DNS:Edit on the zone)
# DDNS_CF_ZONE_ID=...
# DDNS_CF_RECORD_ID=...
# DDNS_CF_RECORD_NAME=haven.example.com
#
# Generic (anything that takes the IP in a URL):
# DDNS_PROVIDER=generic
# DDNS_URL=https://example.com/update?host=h&ip={ip}
#
# Common:
# DDNS_INTERVAL_MINUTES=5 (how often to re-check; default 5)
# Checks unicode.org every month for a new emoji standard and automatically regenerates the built-in emojis in Haven based on that standard
# If you choose to leave this feature disabled, Haven will default to Unicode standard 16.0 which is bundled with the server
# Uncomment to enable this feature
# UNICODE_EMOJI_AUTO_UPDATE=true
# Your client secret as defined by your OIDC provider. The client secret must be set as an env var if using OIDC.
# OIDC_CLIENT_SECRET=changeme-client-secret
# Disk headroom kept free on the data volume, in MB (default 512).
# Uploads are refused once accepting the largest allowed file would cut into
# this, so a full disk can never leave admins unable to delete the files that
# filled it (deleting a row is itself a database write, and that needs space).
# HAVEN_DISK_RESERVE_MB=512
# Full text search tokenizer. Controls how message text is matched.
# Takes effect on restart; changing it triggers a one time reindex.
# trigram Matches text anywhere inside words, so apple finds apple,
# applesauce and pineapple. Most flexible for partial matches.
# Largest index (about 3 to 4x the message text) and needs
# queries of at least 3 characters.
# unicode61 Whole word and prefix matching, so apple finds apple and
# apple* but not applesauce. Smallest, fastest index with the
# best relevance ranking.
# porter Like unicode61 plus English stemming, so run also finds
# running and ran. Small index, English focused, still no
# substring matches.
# Default is unicode61, the closest match to how Discord search behaves.
# HAVEN_SEARCH_TOKENIZER=unicode61
# ── Reverse proxy ─────────────────────────────────────────
# Whose X-Forwarded-For header to believe for the visitor's real address.
# Unset: a proxy on this same machine only (in Docker or Podman, also the
# container network). If your reverse proxy runs on another machine, put its
# address here, or 1 for one hop (Cloudflare's proxy). Haven logs a [proxy]
# line naming the address to use when it sees an untrusted proxy.
# TRUST_PROXY=192.168.1.20
# ── External media storage (S3) ───────────────────────────
# Keep uploads (attachments, avatars, emoji, stickers, sounds, badge and role
# icons, the server icon) in an S3-compatible bucket instead of the uploads
# folder: Garage, MinIO, RustFS, SeaweedFS or AWS. Haven still serves every
# file itself, so the bucket stays private, and it refuses to start if the
# bucket cannot be reached. Moving an existing server: see "External Media
# Storage" in GUIDE.md.
# HAVEN_EXTERNAL_STORAGE=true
# HAVEN_S3_ENDPOINT=http://garage:3900
# HAVEN_S3_BUCKET=haven-media
# Must match the store's own region (Garage: s3_region in garage.toml).
# Default us-east-1.
# HAVEN_S3_REGION=garage
# HAVEN_S3_ACCESS_KEY=
# HAVEN_S3_SECRET_KEY=
# Optional folder inside the bucket, for sharing one bucket, e.g. haven/
# HAVEN_S3_PREFIX=
# Garage, MinIO and RustFS need this; set false for AWS virtual-host URLs.
# HAVEN_S3_FORCE_PATH_STYLE=true
# While moving: also serve files still in the uploads folder.
# HAVEN_S3_LOCAL_FALLBACK=true