Rocket.Chat gets the full five — create, list, reset password, set admin,
deactivate — over its REST API. Two supporting changes make that possible:
- The first admin is now seeded at install from CFG_ROCKETCHAT_ADMIN_*, and
the setup wizard is marked completed. Previously the install left a wizard
for someone to click through, and, more to the point, left no account for
the tools to authenticate as. Rocket.Chat honours those env vars only while
no admin exists, so they are inert on every later boot.
- Calls go out with curl from the host rather than from inside the container.
The image ships node but no curl, and the base URL is read from the deployed
compose's ROOT_URL, which the APP_URL tag has already resolved to whatever
this install actually serves on.
Stoat gets three — list, disable, enable — and the adapter says plainly why it
stops there. Password reset would mean reimplementing its argon2 hashing in
bash, where being subtly wrong writes a hash nothing can verify and locks the
account out with no error at the time. "Make admin" would misrepresent the
model: Stoat's permissions are per-server bitfields on server_members, not a
global flag. Its service containers are distroless with no shell and it has no
admin CLI, so the database is the only durable handle.
Deactivate rather than delete in both, and the destructive actions refuse to
touch the account the tools authenticate as.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
102 lines
5.8 KiB
Plaintext
102 lines
5.8 KiB
Plaintext
#
|
|
# =============================================================================
|
|
# GENERAL CONFIGURATION
|
|
# =============================================================================
|
|
# APP_NAME = name of application for use in scripts
|
|
# REQUIRES = comma-separated install prerequisites (see scripts/checks/requirements/check_app_install.sh)
|
|
# COMPOSE_FILE = default for no app_name in docker-compose file name, app if there is
|
|
# BACKUP = if true, include this application in backup operations
|
|
# UPDATE_TYPE = auto: new image builds are applied automatically (a recovery snapshot is taken first), manual: only when you press Update
|
|
# HEALTHCHECK = if true, default docker health checks for that container will be enabled
|
|
# AUTHELIA = if true, use Authelia authentication, if false turned off.
|
|
# HEADSCALE = options : false, local, remote (see general config). e.g false or local,remote
|
|
# ENABLE_VIDEO = if true, allow camera and screen sharing (needs an HTTPS origin to work in a browser)
|
|
# MONITORING = if true, export this app's metrics to Prometheus + Grafana (needs both apps installed)
|
|
#
|
|
CFG_STOAT_APP_NAME=stoat
|
|
# No prerequisites. Stoat bakes its public URL into the client bundle, but that
|
|
# URL can just as well be http://<lan-ip>:<port> — text chat, channels, roles
|
|
# and uploads all work that way over a LAN or WireGuard tunnel. Only camera and
|
|
# microphone need an HTTPS origin, because browsers refuse getUserMedia outside
|
|
# a secure context; a VPN does not change that, since the check is on the URL
|
|
# scheme. Any HTTPS satisfies it, including a self-signed Traefik certificate.
|
|
CFG_STOAT_REQUIRES=""
|
|
CFG_STOAT_BACKUP=true
|
|
CFG_STOAT_BACKUP_STRATEGY=auto
|
|
# Manual, deliberately. This is a sixteen-service stack whose components are
|
|
# released together and expect matching versions; letting them roll forward
|
|
# unattended and independently is how you end up with an API talking to an
|
|
# incompatible events service.
|
|
CFG_STOAT_UPDATE_TYPE=manual
|
|
CFG_STOAT_COMPOSE_FILE=default
|
|
CFG_STOAT_HEALTHCHECK=true
|
|
# Stoat's own accounts back its clients, and /api must stay reachable without a
|
|
# forward-auth redirect in the way.
|
|
CFG_STOAT_AUTHELIA=false
|
|
CFG_STOAT_HEADSCALE=false
|
|
CFG_STOAT_ENABLE_VIDEO=true
|
|
CFG_STOAT_MONITORING=false
|
|
# Service credentials fed to the compose via #LIBREPORTAL|STOAT_<KEY>_TAG|.
|
|
# Generated on first install and preserved across reinstalls: RabbitMQ writes
|
|
# its user into ./data/rabbit on first boot and ignores the env afterwards, so a
|
|
# regenerated password would leave the broker unreachable. MinIO's root password
|
|
# is shared by the object store and the bucket-creation job, which have to agree.
|
|
CFG_STOAT_RABBITMQ_PASSWORD_1=RANDOMIZEDPASSWORD1
|
|
CFG_STOAT_MINIO_PASSWORD_1=RANDOMIZEDPASSWORD2
|
|
#
|
|
# =============================================================================
|
|
# METADATA
|
|
# =============================================================================
|
|
# CATEGORY = application category for grouping
|
|
# TITLE = display name for the application
|
|
# DESCRIPTION = short description of the application
|
|
# LONG_DESCRIPTION = detailed description of the application
|
|
# URL = source repository or documentation URL
|
|
# ACTIONS = available actions for this application
|
|
# REQUIRES_SERVICE = name of another LibrePortal app that must be installed before this one can be configured
|
|
#
|
|
CFG_STOAT_CATEGORY="communication"
|
|
CFG_STOAT_TITLE="Stoat"
|
|
CFG_STOAT_DESCRIPTION="Discord-style Chat"
|
|
CFG_STOAT_LONG_DESCRIPTION="The closest open-source match to Discord — servers, channels, roles, and LiveKit voice and video. Heavy (16 containers) and does not federate"
|
|
CFG_STOAT_URL="https://github.com/stoatchat/self-hosted"
|
|
CFG_STOAT_ACTIONS="configure|install|restart|shutdown|uninstall"
|
|
#
|
|
# =============================================================================
|
|
# NETWORK CONFIGURATION
|
|
# =============================================================================
|
|
# DOMAIN = number of domain from the general config, useful when using multiple domains
|
|
# WHITELIST = if true only allow whitelisted ips (see general config), if false allow all
|
|
#
|
|
CFG_STOAT_DOMAIN=1
|
|
CFG_STOAT_WHITELIST=false
|
|
CFG_STOAT_NETWORK=default
|
|
#
|
|
# =============================================================================
|
|
# PORT CONFIGURATION
|
|
# =============================================================================
|
|
# PORT_ = port configuration: app|name|external:internal|access|protocol|login|traefik|webui|description
|
|
# - app: application name
|
|
# - name: service identifier (webui, dns, ssh, etc.)
|
|
# - external:internal: port mapping (external can be 'random' for auto-allocation)
|
|
# - access: 'public' (internet accessible), 'private' (local network only), 'disabled' (not running)
|
|
# - protocol: 'tcp' or 'udp'
|
|
# - login: if true, this port requires basic-auth via Traefik (only meaningful when traefik=true)
|
|
# - traefik: if true, Traefik handles this port (reverse proxy)
|
|
# - webui: if true, this port serves the main web interface
|
|
# - description: human-readable description of the service
|
|
#
|
|
# Only one HTTP port: Caddy fronts the entire stack internally, so /api, /ws,
|
|
# /autumn and the rest all arrive on this single host.
|
|
CFG_STOAT_PORT_1="stoat-caddy|webui|random:80|public|tcp|false|true|true|Web Interface||stoat"
|
|
# LiveKit's TCP fallback. Pinned rather than random on purpose: LiveKit
|
|
# advertises this exact port number to clients from livekit.yml, so a randomised
|
|
# external port would be advertised wrongly and voice would fail to connect.
|
|
# Not Traefik-managed — WebRTC is not HTTP.
|
|
CFG_STOAT_PORT_2="stoat-livekit|voice-tcp|7881:7881|public|tcp|false|false|false|LiveKit voice/video (TCP fallback)|"
|
|
|
|
# AUTH_PROFILE = capability tier for the WebUI auth tools (single_password | user_password | multi_user)
|
|
# Stoat exposes no safe way to set a password or grant a role from outside the
|
|
# app, so these tools list and enable/disable only — see scripts/stoat_auth.sh.
|
|
CFG_STOAT_AUTH_PROFILE=multi_user
|