mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
335 lines
16 KiB
Bash
335 lines
16 KiB
Bash
# Every variable docker-compose.yml reads from this file is named here:
|
|
# uncommented when it has no default, commented with its default when it has one.
|
|
# A name absent from this file is one Compose does not forward, and it reaches a
|
|
# service only through a Compose override file that adds it to that service's
|
|
# environment. packages/config/src/__tests__/DeployEnvCoverage.test.ts fails when
|
|
# a Compose edit forgets the matching line here. Compose expands this file from
|
|
# top to bottom, so a line written with ${...} has to sit below every name it
|
|
# reads.
|
|
|
|
FLUXER_DOMAIN=chat.example.com
|
|
FLUXER_PUBLIC_SCHEME=https
|
|
FLUXER_PUBLIC_PORT=443
|
|
|
|
# The three lines above are the address browsers use, and every endpoint the
|
|
# services advertise carries the port from FLUXER_PUBLIC_PORT. They do not move
|
|
# what the host publishes. FLUXER_HTTP_PORT and FLUXER_HTTPS_PORT further down
|
|
# do that, and a non-default port needs the matching one set as well. Both
|
|
# complete recipes are written out beside them.
|
|
|
|
# How browsers reach this instance.
|
|
#
|
|
# Default: Fluxer binds 80 and 443 and gets its own Let's Encrypt certificate.
|
|
# Point DNS at this host and there is nothing else to configure.
|
|
#
|
|
# Behind your own reverse proxy (nginx, Traefik, HAProxy, Cloudflare Tunnel,
|
|
# another Caddy): uncomment COMPOSE_FILE below. Fluxer then serves plain HTTP on
|
|
# 127.0.0.1:8080 instead, and your proxy forwards everything to it. Keep
|
|
# FLUXER_PUBLIC_SCHEME and FLUXER_PUBLIC_PORT describing the PUBLIC address your
|
|
# proxy serves, not this local port.
|
|
#COMPOSE_FILE=docker-compose.yml:docker-compose.proxy.yml
|
|
|
|
# Where the plain-HTTP port binds when the proxy overlay is in use. Leave it on
|
|
# loopback when the proxy runs on this host. Use 0.0.0.0:8080 only when the proxy
|
|
# is on another machine, and firewall the port to that machine.
|
|
#FLUXER_EDGE_BIND=127.0.0.1:8080
|
|
|
|
# Which upstream hops may set X-Forwarded-For. Fluxer rewrites the header from
|
|
# this to the real client address, so IP bans, rate limits and abuse detection
|
|
# see the caller rather than the proxy. The default covers proxies on private or
|
|
# loopback addresses, which is every same-host setup. Set it to your proxy's
|
|
# address if it reaches Fluxer from a public IP.
|
|
#FLUXER_EDGE_TRUSTED_PROXIES=private_ranges
|
|
|
|
# The origin browsers see, without a trailing slash. Leave it unset and each
|
|
# service builds one from the three values at the top of this file. Set it and it
|
|
# wins: every service reads the host, the scheme and the port out of it and
|
|
# ignores those three names. Use it when browsers reach the instance on a host
|
|
# FLUXER_DOMAIN does not name. It has to be a bare origin, a scheme and a host
|
|
# and an optional port and nothing after them, or the services refuse to start.
|
|
# It does not move the edge listener or the published ports either, so set the
|
|
# publish below to the port written here.
|
|
#FLUXER_PUBLIC_ORIGIN=https://chat.example.com
|
|
|
|
# Overrides the address the edge listens on inside its container. Compose builds
|
|
# it from FLUXER_PUBLIC_SCHEME and FLUXER_DOMAIN with no port, and the edge keeps
|
|
# its container ports at 80 and 443 whatever the public port is. Caddy matches a
|
|
# site by host and ignores the port in the Host header, so a request arriving on
|
|
# a non-default published port still lands on this site. Put a port in this value
|
|
# only if you also publish that same container port below, or nothing will be
|
|
# listening where the publish points. Honoured in the default mode only:
|
|
# docker-compose.proxy.yml sets the literal :8080 and tunnel.compose.yml the
|
|
# literal :80, and Compose lets the last file win, so a value here is discarded
|
|
# under either overlay with no warning. Set it for an unusual default-mode
|
|
# layout, such as serving several hostnames. Write the scheme into it: a bare
|
|
# hostname means automatic HTTPS on 443 whatever FLUXER_PUBLIC_SCHEME says.
|
|
#FLUXER_EDGE_SITE_ADDRESS=https://chat.example.com
|
|
|
|
# The old name for the value above. It is read only when
|
|
# FLUXER_EDGE_SITE_ADDRESS is unset, so an existing .env keeps the listener
|
|
# it already had. Rename it to FLUXER_EDGE_SITE_ADDRESS at your convenience.
|
|
#FLUXER_CADDY_SITE_ADDRESS=
|
|
|
|
# Host side of the edge's publishes, and the only two names that decide which
|
|
# host ports Fluxer binds. The container side is fixed. Container 80 carries the
|
|
# HTTP to HTTPS redirect and the Let's Encrypt HTTP challenge under an https
|
|
# scheme, and the site itself under an http one. Container 443 carries the TLS
|
|
# site. FLUXER_HTTPS_PORT moves the TCP and the UDP publish together, because
|
|
# HTTP/3 needs both on the same port. Both take an optional bind address in front
|
|
# of the port, and 127.0.0.1 keeps the publish off every public interface. Give
|
|
# them different host ports: the same host port on both is two publishes of one
|
|
# port and the edge refuses to start.
|
|
#FLUXER_HTTP_PORT=80
|
|
#FLUXER_HTTPS_PORT=443
|
|
#FLUXER_HTTP_PORT=127.0.0.1:80
|
|
#FLUXER_HTTPS_PORT=127.0.0.1:443
|
|
|
|
# HTTPS on 8443, complete. Host 80 stays published and still answers the ACME
|
|
# challenge. Let's Encrypt only ever connects to the public 80 or 443, so the
|
|
# certificate is issued if a router in front forwards public 80 to this host and
|
|
# is not issued otherwise. Serve your own certificate from the Caddyfile when it
|
|
# cannot.
|
|
#FLUXER_PUBLIC_PORT=8443
|
|
#FLUXER_HTTPS_PORT=8443
|
|
|
|
# Plain HTTP on 19080, complete. The port 80 publish moves to 19080, so nothing
|
|
# binds host 80. Under an http scheme nothing listens on container 443, so the
|
|
# last line parks that publish on loopback for a host that wants 443 for
|
|
# something else. Drop it and 443 is published and idle, which is what earlier
|
|
# releases did.
|
|
#FLUXER_PUBLIC_SCHEME=http
|
|
#FLUXER_PUBLIC_PORT=19080
|
|
#FLUXER_HTTP_PORT=19080
|
|
#FLUXER_HTTPS_PORT=127.0.0.1:443
|
|
|
|
# A tunnel or another proxy in front of the stack needs no HTTPS publish at all.
|
|
# tunnel.compose.yml ships beside this file and replaces Caddy's published ports
|
|
# with a single loopback HTTP publish, so nothing binds 443, and points the edge
|
|
# at plain HTTP on that publish so it stops redirecting to https. FLUXER_HTTP_PORT
|
|
# still moves that one publish. Set the line below and plain docker compose
|
|
# commands pick the file up, or add it to your own -f flags if you pass any. The
|
|
# file uses the !override tag, which needs Compose 2.24.4 or newer.
|
|
#COMPOSE_FILE=docker-compose.yml:tunnel.compose.yml
|
|
|
|
FLUXER_REGISTRY_OWNER=fluxerapp
|
|
FLUXER_REGISTRY=ghcr.io/${FLUXER_REGISTRY_OWNER}
|
|
FLUXER_IMAGE_TAG=v1
|
|
|
|
POSTGRES_PASSWORD=CHANGE_ME
|
|
MEILI_MASTER_KEY=CHANGE_ME
|
|
FLUXER_S3_ACCESS_KEY=fluxer
|
|
FLUXER_S3_SECRET_KEY=CHANGE_ME
|
|
|
|
FLUXER_SUDO_MODE_SECRET=CHANGE_ME
|
|
FLUXER_CONNECTION_INITIATION_SECRET=CHANGE_ME
|
|
FLUXER_GATEWAY_RPC_AUTH_TOKEN=CHANGE_ME
|
|
FLUXER_ERLANG_COOKIE=CHANGE_ME
|
|
FLUXER_MEDIA_PROXY_SECRET_KEY=CHANGE_ME
|
|
FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64=CHANGE_ME
|
|
FLUXER_ADMIN_SECRET_KEY_BASE=CHANGE_ME
|
|
FLUXER_ADMIN_OAUTH_CLIENT_SECRET=CHANGE_ME
|
|
|
|
# The token every service sends to NATS. The bundled NATS runs without
|
|
# authentication, so this stays empty unless a Compose override points the stack
|
|
# at an external NATS that requires a token. Compose forwards the name to every
|
|
# container that connects.
|
|
#FLUXER_NATS_AUTH_TOKEN=
|
|
|
|
FLUXER_VAPID_PUBLIC_KEY=CHANGE_ME
|
|
FLUXER_VAPID_PRIVATE_KEY=CHANGE_ME
|
|
|
|
# The VAPID contact address defaults to admin@ followed by FLUXER_DOMAIN. Set it
|
|
# only if that mailbox does not exist.
|
|
#[email protected]
|
|
|
|
# Passkeys follow FLUXER_DOMAIN by default. Set these only if browsers reach the
|
|
# instance on a different host, and note that changing FLUXER_PASSKEY_RP_ID
|
|
# invalidates every passkey already registered against the old value.
|
|
#FLUXER_PASSKEY_RP_ID=chat.example.com
|
|
#FLUXER_PASSKEY_RP_NAME=Fluxer
|
|
#FLUXER_PASSKEY_ADDITIONAL_ALLOWED_ORIGINS=https://chat.example.com
|
|
#FLUXER_PASSKEY_ADDITIONAL_ALLOWED_ORIGINS=http://chat.example.com:19080
|
|
|
|
# Extra Content-Security-Policy sources, appended to the built-in ones. Set these
|
|
# only when a browser must reach an origin the defaults do not cover, such as a
|
|
# voice server hosted on a domain other than FLUXER_DOMAIN. Separate several
|
|
# sources with spaces or commas. Every one of them is empty by default, and the
|
|
# three carrying a value below are illustrations, not defaults.
|
|
#FLUXER_CSP_EXTRA_DEFAULT_SRC=
|
|
#FLUXER_CSP_EXTRA_CONNECT_SRC=wss://livekit.example.com:7881
|
|
#FLUXER_CSP_EXTRA_IMG_SRC=https://cdn.example.com
|
|
#FLUXER_CSP_EXTRA_MEDIA_SRC=
|
|
#FLUXER_CSP_EXTRA_FONT_SRC=
|
|
#FLUXER_CSP_EXTRA_SCRIPT_SRC=https://analytics.example.com
|
|
#FLUXER_CSP_EXTRA_STYLE_SRC=
|
|
#FLUXER_CSP_EXTRA_FRAME_SRC=
|
|
#FLUXER_CSP_EXTRA_WORKER_SRC=
|
|
#FLUXER_CSP_EXTRA_MANIFEST_SRC=
|
|
|
|
# One report-uri for Content-Security-Policy violation reports. Empty leaves the
|
|
# directive off the header.
|
|
#FLUXER_CSP_REPORT_URI=
|
|
|
|
# Allow the SSO identity provider to resolve to a private or internal address.
|
|
# Off by default: the API refuses to call non-public addresses so a misconfigured
|
|
# provider URL cannot be used to reach internal services. Turn it on only when the
|
|
# provider genuinely lives on your own network, such as split-horizon DNS or a LAN
|
|
# identity provider, and only when you trust everyone who can configure SSO.
|
|
#FLUXER_SSO_ALLOW_PRIVATE_ADDRESSES=true
|
|
|
|
# Both reach LiveKit as LIVEKIT_KEYS and the webhook signing key, and the API as
|
|
# FLUXER_LIVEKIT_API_KEY and FLUXER_LIVEKIT_API_SECRET. Change them together.
|
|
LIVEKIT_API_KEY=fluxer
|
|
LIVEKIT_API_SECRET=CHANGE_ME
|
|
|
|
# The URL browsers use for voice signalling. Compose builds it from
|
|
# FLUXER_PUBLIC_ORIGIN, or from FLUXER_PUBLIC_SCHEME, FLUXER_DOMAIN and
|
|
# FLUXER_PUBLIC_PORT, as that origin followed by /livekit. The client rewrites a
|
|
# leading http to ws itself. Set it only when LiveKit is served from another
|
|
# host.
|
|
#FLUXER_LIVEKIT_URL=
|
|
|
|
# Media ports. LiveKit advertises these in ICE candidates, so the host must
|
|
# forward the same numbers.
|
|
#FLUXER_LIVEKIT_TCP_PORT=7881
|
|
#FLUXER_LIVEKIT_UDP_PORT=7882
|
|
|
|
# LiveKit finds the address browsers dial by asking a STUN server. A host that
|
|
# cannot reach one over UDP stops with "could not resolve external IP", and the
|
|
# address is then set by hand: put it in FLUXER_LIVEKIT_NODE_IP and set
|
|
# FLUXER_LIVEKIT_USE_EXTERNAL_IP to false. Point the two STUN entries at another
|
|
# server to keep the lookup and leave Google out of it.
|
|
#FLUXER_LIVEKIT_USE_EXTERNAL_IP=false
|
|
#FLUXER_LIVEKIT_NODE_IP=203.0.113.10
|
|
#FLUXER_LIVEKIT_STUN_PRIMARY=stun.l.google.com:19302
|
|
#FLUXER_LIVEKIT_STUN_SECONDARY=stun1.l.google.com:19302
|
|
|
|
FLUXER_KLIPY_API_KEY=
|
|
|
|
FLUXER_EMAIL_ENABLED=false
|
|
FLUXER_EMAIL_PROVIDER=none
|
|
FLUXER_EMAIL_FROM_EMAIL=[email protected]
|
|
FLUXER_EMAIL_FROM_NAME=Fluxer
|
|
FLUXER_EMAIL_APP_BASE_URL=
|
|
FLUXER_EMAIL_SMTP_HOST=
|
|
FLUXER_EMAIL_SMTP_PORT=587
|
|
FLUXER_EMAIL_SMTP_USERNAME=
|
|
FLUXER_EMAIL_SMTP_PASSWORD=
|
|
FLUXER_EMAIL_SMTP_SECURE=true
|
|
|
|
FLUXER_CAPTCHA_ENABLED=false
|
|
FLUXER_CAPTCHA_PROVIDER=none
|
|
FLUXER_CAPTCHA_HCAPTCHA_SITE_KEY=
|
|
FLUXER_CAPTCHA_HCAPTCHA_SECRET_KEY=
|
|
FLUXER_CAPTCHA_TURNSTILE_SITE_KEY=
|
|
FLUXER_CAPTCHA_TURNSTILE_SECRET_KEY=
|
|
FLUXER_DISCOVERY_ENABLED=true
|
|
|
|
# Container memory. The 25 limits sum to 18.25 GiB, which is a sum of ceilings and
|
|
# not an allocation, so the defaults fit a host with 8 GB and are sized for 16 GB.
|
|
# The four reservations are cgroup memory.low, which biases the kernel away from
|
|
# reclaiming from the services whose death takes the whole instance down. They do
|
|
# not reserve anything. Lower the limits on a smaller host.
|
|
#FLUXER_CADDY_MEMORY_LIMIT=256mb
|
|
#FLUXER_POSTGRES_MEMORY_LIMIT=5gb
|
|
#FLUXER_POSTGRES_MEMORY_RESERVATION=3gb
|
|
#FLUXER_VALKEY_MEMORY_LIMIT=256mb
|
|
#FLUXER_NATS_MEMORY_LIMIT=256mb
|
|
#FLUXER_MEILISEARCH_MEMORY_LIMIT=768mb
|
|
#FLUXER_SEAWEEDFS_MEMORY_LIMIT=2gb
|
|
#FLUXER_SEAWEEDFS_INIT_MEMORY_LIMIT=128mb
|
|
#FLUXER_LIVEKIT_MEMORY_LIMIT=512mb
|
|
#FLUXER_API_MEMORY_LIMIT=2560mb
|
|
#FLUXER_API_MEMORY_RESERVATION=1gb
|
|
#FLUXER_WORKER_MEMORY_LIMIT=2560mb
|
|
#FLUXER_WORKER_MEMORY_RESERVATION=1gb
|
|
#FLUXER_GATEWAY_MEMORY_LIMIT=1gb
|
|
#FLUXER_GATEWAY_MEMORY_RESERVATION=384mb
|
|
#FLUXER_MEDIA_PROXY_MEMORY_LIMIT=512mb
|
|
#FLUXER_STATIC_PROXY_MEMORY_LIMIT=256mb
|
|
#FLUXER_APP_PROXY_MEMORY_LIMIT=256mb
|
|
#FLUXER_SNOWFLAKES_MEMORY_LIMIT=128mb
|
|
#FLUXER_SNOWFLAKES_SHARD_MEMORY_LIMIT=256mb
|
|
#FLUXER_USERS_MEMORY_LIMIT=128mb
|
|
#FLUXER_USERS_SHARD_MEMORY_LIMIT=256mb
|
|
#FLUXER_GIFS_MEMORY_LIMIT=128mb
|
|
#FLUXER_GIFS_SHARD_MEMORY_LIMIT=256mb
|
|
#FLUXER_MESSAGES_MEMORY_LIMIT=128mb
|
|
#FLUXER_MESSAGES_SHARD_MEMORY_LIMIT=256mb
|
|
#FLUXER_UNFURL_MEMORY_LIMIT=128mb
|
|
#FLUXER_UNFURL_SHARD_MEMORY_LIMIT=256mb
|
|
#FLUXER_ADMIN_MEMORY_LIMIT=256mb
|
|
|
|
# Meilisearch indexing memory. Keep it well under FLUXER_MEILISEARCH_MEMORY_LIMIT,
|
|
# which is the container ceiling the indexer shares with the search process.
|
|
#FLUXER_MEILISEARCH_MAX_INDEXING_MEMORY=384mb
|
|
|
|
# SeaweedFS heap ceiling. Go collects against this value instead of against the
|
|
# container limit, which it cannot see, so without it an upload burst grows the
|
|
# heap past FLUXER_SEAWEEDFS_MEMORY_LIMIT and the kernel OOM-kills the container
|
|
# mid-upload (exit 137). Keep it near three quarters of that limit, and raise both
|
|
# together: the peak is the parts of one upload in flight at once, which is 25 MB
|
|
# times 20 for a 500 MB attachment.
|
|
#FLUXER_SEAWEEDFS_GOMEMLIMIT=1536MiB
|
|
|
|
# Node sizes its own heap from the container memory limit by default, at roughly
|
|
# 55 percent of it, which always leaves room for the buffers and stacks that live
|
|
# outside the heap. Leave these unset unless you have a reason to pin the value.
|
|
# Any value set here must stay well below the container limit above: a heap ceiling
|
|
# above the container limit makes the kernel OOM-kill the container (exit 137, no
|
|
# diagnostics) instead of Node reporting a JavaScript heap out of memory error.
|
|
#FLUXER_API_NODE_HEAP_MB=1792
|
|
#FLUXER_WORKER_NODE_HEAP_MB=1792
|
|
|
|
# Bundled Postgres tuning. Keep these consistent with FLUXER_POSTGRES_MEMORY_LIMIT:
|
|
# budget roughly shared_buffers + (server max_connections x 12 MB) +
|
|
# (3 x autovacuum_work_mem) + 300 MB for page cache and WAL. Note this is the
|
|
# server setting, distinct from the per-service FLUXER_POSTGRES_MAX_CONNECTIONS
|
|
# pool sizes used by the api, worker and shards.
|
|
#FLUXER_POSTGRES_SERVER_MAX_CONNECTIONS=150
|
|
#FLUXER_POSTGRES_SHARED_BUFFERS=512MB
|
|
#FLUXER_POSTGRES_EFFECTIVE_CACHE_SIZE=2GB
|
|
#FLUXER_POSTGRES_WORK_MEM=8MB
|
|
#FLUXER_POSTGRES_MAINTENANCE_WORK_MEM=256MB
|
|
#FLUXER_POSTGRES_AUTOVACUUM_WORK_MEM=128MB
|
|
|
|
# The bundled Valkey holds durable state as well as cache. The bulk message
|
|
# deletion queue and the account deletion queue are sorted sets with no expiry,
|
|
# and nothing else stores the first of the two. It therefore runs with an
|
|
# append-only file on a named volume and with noeviction, so an over-limit write
|
|
# fails loudly instead of silently deleting queued work. Distributed locks all
|
|
# carry a TTL and are not what the durability is for. Only change the policy if
|
|
# you have moved that durable state elsewhere.
|
|
#FLUXER_VALKEY_MAXMEMORY=192mb
|
|
#FLUXER_VALKEY_MAXMEMORY_POLICY=noeviction
|
|
|
|
# The gateway derives its BEAM scheduler count from the container CPU quota,
|
|
# clamped to this range. The floor matters: a single scheduler lets one blocking
|
|
# operation stall every websocket on the node. The ceiling stops a large host
|
|
# from starting far more schedulers than the container can actually use.
|
|
#FLUXER_ERLANG_SCHEDULERS_MIN=2
|
|
#FLUXER_ERLANG_SCHEDULERS_MAX=16
|
|
|
|
# In-flight request ceiling for the four services Compose forwards it to: the
|
|
# users and messages routers and their shards. The Rust built-in defaults are 192
|
|
# for messages, 320 for snowflakes and 64 elsewhere, and they govern every service
|
|
# Compose does not forward this to.
|
|
#FLUXER_SVC_MAX_CONCURRENT_REQUESTS=20
|
|
|
|
# The api and the Rust services name their fixed Postgres statement shapes so the
|
|
# server can reuse their plans. Named prepared statements require a session that
|
|
# outlives the transaction, so set this to false if you put a transaction-pooling
|
|
# connection pooler such as PgBouncer in front of Postgres. One setting governs
|
|
# every service. The bundled compose talks to Postgres directly, where naming is
|
|
# a win and the default is correct.
|
|
#FLUXER_POSTGRES_PREPARED_STATEMENTS=true
|
|
|
|
# The api bounds how long a client may take to send a request. The header timeout
|
|
# covers the request line and headers only, while the request timeout covers the
|
|
# whole exchange, so a slow uploader is bounded by the second value and not by
|
|
# the first. Raise both if you front large uploads or serve clients on high
|
|
# latency links. The header timeout is clamped down to the request timeout, so
|
|
# raising it alone does nothing. Both are milliseconds, between 1000 and 3600000.
|
|
#FLUXER_API_HEADERS_TIMEOUT_MS=30000
|
|
#FLUXER_API_REQUEST_TIMEOUT_MS=120000
|