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