Answers "should we stop creating an admin/pass on start" with the split the catalog actually has, rather than one way for everything. Ten apps need it: adguard, authelia, bookstack, matrix, nextcloud, owncloud, pihole, rocketchat, stalwart, speedtest and headscale either pass the generated password into the container or hand it to an install hook that creates the account. There the password IS the working credential — dropping it would lock you out. Left alone. Three do not create an account at all: gitea, invidious and mattermost seed no user (the first one comes from their own signup flow or the Create Account tool), so the password minted at install named nothing. The WebUI credentials card showed a password that could not log in. They now match linkding — an empty, unslotted ADMIN_PASSWORD the auth adapter fills when the operator makes the first admin, and keeps in step on later resets. Unslotted because the slot number marks a value the installer generates. mattermost's adapter also had linkding's bug: it persists ADMIN_PASSWORD but the config declared only ADMIN_EMAIL, so the write was a no-op. WebUI: rocketchat's generated admin password had no field mapping, so the card could not show it. Added, plus a generic ADMIN_USER entry — six apps record an admin username the card had no way to display. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
114 lines
6.8 KiB
YAML
114 lines
6.8 KiB
YAML
networks:
|
|
DOCKER_NETWORK_DATA: #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
external: true
|
|
|
|
services:
|
|
rocketchat-service: #LIBREPORTAL|SERVICE_TAG_1|rocketchat-service
|
|
container_name: rocketchat-service
|
|
image: rocketchat/rocket.chat:8.7.0 #LIBREPORTAL|ROCKETCHAT_VERSION_TAG|8.7.0
|
|
# The image runs as uid 65533 and writes uploads into /app/uploads, so
|
|
# it hits the same rootless bind-mount ownership problem as vikunja and
|
|
# mattermost. USER_TAG resolves to whoever actually owns the mounts.
|
|
user: "USER_DATA" #LIBREPORTAL|USER_TAG|USER_DATA
|
|
# Rocket.Chat exits — rather than waits — when Mongo has no elected
|
|
# primary, and on a fresh install the replica set is only initiated by
|
|
# the post-start hook. `unless-stopped` is what carries it through those
|
|
# first few seconds of crash-looping.
|
|
restart: unless-stopped
|
|
# GLUETUN_OFF_BEGIN
|
|
ports:
|
|
- "PORTS_DATA_1" #LIBREPORTAL|PORTS_TAG_1|PORTS_DATA_1
|
|
# GLUETUN_OFF_END
|
|
volumes:
|
|
- ./uploads:/app/uploads
|
|
environment:
|
|
- TZ=TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
|
|
- PORT=PORT_INTERNAL_DATA_1 #LIBREPORTAL|PORT_INTERNAL_TAG_1|PORT_INTERNAL_DATA_1
|
|
# ROOT_URL is what Rocket.Chat puts in invite links, OAuth redirect
|
|
# URLs and the websocket origin check. Get it wrong and the client
|
|
# loads but never connects.
|
|
- ROOT_URL=APP_URL_DATA #LIBREPORTAL|APP_URL_TAG|APP_URL_DATA
|
|
# ?replicaSet=rs0 is mandatory, not decorative: Rocket.Chat tails
|
|
# the Mongo oplog for realtime updates, and the oplog only exists on
|
|
# a replica set. Single-node is fine — it just has to be a set.
|
|
- MONGO_URL=mongodb://rocketchat-db:27017/rocketchat?replicaSet=rs0
|
|
- MONGO_OPLOG_URL=mongodb://rocketchat-db:27017/local?replicaSet=rs0
|
|
- DEPLOY_METHOD=docker
|
|
# Seed the first admin instead of leaving a setup wizard for someone
|
|
# to click through. These are honoured only while no admin exists, so
|
|
# they are inert on every boot after the first — and marking the
|
|
# wizard completed is what stops Rocket.Chat asking anyway.
|
|
#
|
|
# It also gives LibrePortal a credential to drive the REST API with,
|
|
# which is what the Tools tab needs; without a seeded admin there is
|
|
# no account to authenticate as.
|
|
- OVERWRITE_SETTING_Show_Setup_Wizard=completed
|
|
- ADMIN_USERNAME=ROCKETCHAT_ADMIN_USERNAME_DATA #LIBREPORTAL|ROCKETCHAT_ADMIN_USERNAME_TAG|ROCKETCHAT_ADMIN_USERNAME_DATA
|
|
- ADMIN_PASS=ROCKETCHAT_ADMIN_PASSWORD_1_DATA #LIBREPORTAL|ROCKETCHAT_ADMIN_PASSWORD_1_TAG|ROCKETCHAT_ADMIN_PASSWORD_1_DATA
|
|
- ADMIN_EMAIL=ROCKETCHAT_ADMIN_EMAIL_DATA #LIBREPORTAL|ROCKETCHAT_ADMIN_EMAIL_TAG|ROCKETCHAT_ADMIN_EMAIL_DATA
|
|
depends_on:
|
|
- rocketchat-db
|
|
labels:
|
|
libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA
|
|
libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA
|
|
libreportal.backup.db: "mongo:rocketchat-db:mongo_data:"
|
|
libreportal.backup.files: "rocketchat-service:/app/uploads:uploads"
|
|
traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA
|
|
# TRAEFIK_PORT_1_BEGIN
|
|
traefik.http.routers.rocketchat-service.entrypoints: web,websecure
|
|
traefik.http.routers.rocketchat-service.rule: Host(`DOMAINSUBNAME_DATA_1`) #LIBREPORTAL|DOMAINSUBNAME_TAG_1|DOMAINSUBNAME_DATA_1
|
|
traefik.http.routers.rocketchat-service.tls: true
|
|
traefik.http.routers.rocketchat-service.tls.certresolver: production
|
|
traefik.http.services.rocketchat-service.loadbalancer.server.port: PORT_INTERNAL_DATA_1 #LIBREPORTAL|PORT_INTERNAL_TAG_1|PORT_INTERNAL_DATA_1
|
|
traefik.http.routers.rocketchat-service.middlewares: MIDDLEWARE_DATA_1 #LIBREPORTAL|MIDDLEWARE_TAG_1|MIDDLEWARE_DATA_1
|
|
# TRAEFIK_PORT_1_END
|
|
traefik.docker.network: DOCKER_NETWORK_DATA #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
healthcheck:
|
|
disable: HEALTHCHECK_DATA #LIBREPORTAL|HEALTHCHECK_TAG|HEALTHCHECK_DATA
|
|
# GLUETUN_OFF_BEGIN
|
|
networks:
|
|
DOCKER_NETWORK_DATA: #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
ipv4_address: IP_DATA_1 #LIBREPORTAL|IP_TAG_1|IP_DATA_1
|
|
# GLUETUN_OFF_END
|
|
# GLUETUN_ON_BEGIN
|
|
# network_mode: "container:gluetun-service"
|
|
# GLUETUN_ON_END
|
|
|
|
# Official mongo image rather than bitnami/mongodb (which upstream's own
|
|
# compose uses): Bitnami moved its catalog behind a paid registry in 2025
|
|
# and the free tags are no longer dependable for a long-lived install. The
|
|
# cost is that the replica set is not auto-initiated, so
|
|
# rocketchat_install_post_start runs rs.initiate() once, by hand.
|
|
#
|
|
# No authentication: enabling it on a replica set additionally requires a
|
|
# shared keyfile for member-to-member auth, which is a lot of moving parts
|
|
# for a database that is never published outside the docker network. The
|
|
# backup driver's mongo path works either way — it adds credential flags
|
|
# only when MONGO_INITDB_ROOT_USERNAME is set.
|
|
#
|
|
# No `user:` override: the entrypoint starts as root, chowns /data/db and
|
|
# then drops to the mongodb user. Under rootless Docker container-root is
|
|
# the install user on the host, which owns the bind mount, so that works.
|
|
rocketchat-db: #LIBREPORTAL|SERVICE_TAG_2|rocketchat-db
|
|
image: mongo:8.0 #LIBREPORTAL|ROCKETCHAT_MONGO_VERSION_TAG|8.0
|
|
container_name: rocketchat-db
|
|
restart: unless-stopped
|
|
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
|
|
volumes:
|
|
- ./mongo_data:/data/db
|
|
- ./mongo_config:/data/configdb
|
|
environment:
|
|
- TZ=TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
|
|
# Required on Linux 6.19 and newer. The TCMalloc bundled with
|
|
# MongoDB 8.x registers restartable sequences in a way the newer
|
|
# kernel rejects; mongod then aborts on startup with "Linux kernel
|
|
# versions 6.19 and newer has a known incompatibility"
|
|
# (SERVER-121912). Letting glibc own the rseq registration avoids
|
|
# the conflict. Harmless once upstream ships a patched TCMalloc —
|
|
# this only sets a glibc tunable — so it can be dropped then rather
|
|
# than urgently.
|
|
- GLIBC_TUNABLES=glibc.pthread.rseq=1
|
|
networks:
|
|
DOCKER_NETWORK_DATA: #LIBREPORTAL|DOCKER_NETWORK_TAG|DOCKER_NETWORK_DATA
|
|
ipv4_address: IP_DATA_2 #LIBREPORTAL|IP_TAG_2|IP_DATA_2
|