Overview

The validated baseline is the openSUSE-based grommunio appliance 2026.06.1. The examples consistently use the neutral appliance domain https://mail.example.test; paths such as /web/, /admin/, /auth/, /chat/, /meet/ and /files/ live on the same appliance.This article shows how to enable, operate and test grommunio Chat on an existing grommunio 2026 appliance with multiple users.

The guide covers services, web access, users, teams, channels, permissions, WebSockets, multi-tenancy, logs and a reproducible acceptance check.

Tested environment

  • grommunio 2026 on the openSUSE-based grommunio appliance.

  • All appliance commands are run directly on the grommunio appliance.

  • Public examples consistently use the neutral appliance domain https://mail.example.test.

1. Starting point & prerequisites

The starting point is a grommunio installation with working DNS, TLS, admin access and a clean baseline validation. Each article covers exactly the building block required for a complete collaboration platform.

2. Step-by-step guide

Prerequisites

An existing or planned grommunio environment, matching DNS names, TLS, administrative access and a clear target for mail, collaboration or operations.

This guide shows how to install, configure and test grommunio Chat on an existing grommunio 2026.06.1 appliance with multiple users. The goal is not just that `/chat/` loads. Teams, channels, WebSocket connectivity, user privileges and domain mapping need to work together.

  • You install grommunio Chat 10 from the grommunio repository.

  • You configure database, Chat configuration, local admin and admin API integration.

  • You enable Chat per domain and per user.

  • You validate the nginx upstream for `/chat/`.

  • You test two users in the same team and channel.

  • You evaluate what is multi-tenant capable and when a separate installation is required.

The series remains chronological:install grommunio,antispam with Rspamd,SSO with Keycloak,Meet with Jitsiand now Chat. Product context is available on thegrommunio product page.

Architecture: what grommunio Chat is

grommunio Chat is the team communication layer inside the grommunio platform and is technically based on Mattermost. The appliance runs the Chat service locally and exposes it through nginx under `/chat/`. grommunio Admin keeps the mapping between grommunio domain, grommunio user and Chat team.

  • Browser
  • https://mail.example.test/chat/
  • nginx location /chat/
  • upstream chat_server
  • grommunio-chat on 127.0.0.1:8065
  • MariaDB database grochat
  • domain Chat team and user mapping through grommunio Admin

Step 1: Install the package and check the state

First check whether Chat is already installed. On the validated appliance only the admin driver was present; the actual Chat server had to be installed.

bash
rpm -qa | grep -Ei 'grommunio-chat|mattermost' | sort
zypper search -s grommunio-chat
zypper --non-interactive install --auto-agree-with-licenses grommunio-chat-v10

Step 2: Prepare database and configuration

Chat needs its own database and a `config.json`. Use unique passwords and never paste them into tickets, screenshots or articles. In production runbooks these values belong in secret management or at least in root-readable files.

bash
install -d -m 0750 -o grochat -g grochat /etc/grommunio-chat /var/log/grommunio-chat /var/lib/grommunio-chat
cp -n /etc/grommunio-chat/config.json.example /etc/grommunio-chat/config.json
# Beispiel: Datenbank und Benutzer anlegen.
# Ersetze <secure-password> durch ein starkes Secret.
mariadb <<'SQL'
CREATE DATABASE IF NOT EXISTS grochat CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'grochat'@'localhost' IDENTIFIED BY '<secure-password>';
GRANT ALL PRIVILEGES ON grochat.* TO 'grochat'@'localhost';
FLUSH PRIVILEGES;
SQL

In `config.json`, at minimum `SiteURL`, SQL driver, SQL data source and local mode must be correct. The `SiteURL` must match the URL users actually use in the browser. In validation, a mismatched port/origin combination produced WebSocket 403 errors.

bash
python3 - <<'PY'
import json
from pathlib import Path
path = Path('/etc/grommunio-chat/config.json')
data = json.loads(path.read_text())
data['ServiceSettings']['SiteURL'] = 'https://mail.example.test/chat'
data['ServiceSettings']['ListenAddress'] = '127.0.0.1:8065'
data['ServiceSettings']['EnableLocalMode'] = True
data['ServiceSettings']['LocalModeSocketLocation'] = '/var/tmp/grommunio-chat_local.socket'
data['SqlSettings']['DriverName'] = 'mysql'
data['SqlSettings']['DataSource'] = 'grochat:<secure-password>@tcp(localhost:3306)/grochat?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s'
data['TeamSettings']['EnableOpenServer'] = False
data['TeamSettings']['RestrictCreationToDomains'] = 'example.test'
path.write_text(json.dumps(data, indent=2) + '\n')
PY
chown grochat:grochat /etc/grommunio-chat/config.json
chmod 0640 /etc/grommunio-chat/config.json

Phase B - normal Chat test before Keycloak

The normal Chat test comes before the Keycloak integration: open Chat, use the intended baseline login, verify team and channel, user A sends a message, user B sees it and replies.

Step 3: Start the service and validate nginx upstream

Start Chat and verify the local socket. On the validated appliance it was also important to activate the shipped nginx upstream file from the `.example` file. Without this upstream, `nginx -t` failed with `host not found in upstream "chat_server"`.

bash
systemctl enable --now grommunio-chat
test -S /var/tmp/grommunio-chat_local.socket
cp -n /etc/grommunio-common/nginx/upstreams.d/grommunio-chat.conf.example \
/etc/grommunio-common/nginx/upstreams.d/grommunio-chat.conf
nginx -t
systemctl restart nginx grommunio-admin-api
curl -kI https://mail.example.test/chat/
curl -k https://mail.example.test/chat/api/v4/system/ping

Step 4: Connect local Chat admin and admin API

grommunio Admin needs a technical Chat admin so domains and users can be mirrored into Chat. Use an address inside the allowed domain. If you set `RestrictCreationToDomains = example.test`, `admin@localhost` is deliberately not allowed.

bash
export MMCTL_LOCAL_SOCKET_PATH=/var/tmp/grommunio-chat_local.socket
/usr/share/grommunio-chat/bin/grommunio-chat-ctl --local user create \
--email groadmin@example.test \
--username groadmin \
--password '<secure-password>' \
--system-admin \
--email-verified \
--disable-welcome-email
cat >/etc/grommunio-admin-api/conf.d/chat.yaml <<'YAML'
chat:
connection:
login_id: groadmin
password: '<secure-password>'
url: mail.example.test
basepath: /chat/api/v4
port: 443
scheme: https
verify: False
YAML
chmod 0600 /etc/grommunio-admin-api/conf.d/chat.yaml
systemctl restart grommunio-admin-api

Step 5: Enable domain and users

Enable Chat on the domain first. Only then can users be linked to Chat reliably. In validation, `grommunio-admin domain modify example.test --chat true` created a Chat team for this domain.

Step 6: Test login and channels

Open Chat with a normal user. After the first login, the domain team must be visible. In this guide, team and channel names are synthetic, but the flow is identical to a production environment.

https://mail.example.test/chat/

Screenshot: Login to grommunio Chat through the Chat route.

https://mail.example.test/chat/

Screenshot: After login, the user sees the domain team and default channels.

Then create functional channels. The example environment used `Operations` and `Project` because they represent typical collaboration boundaries.

bash
export MMCTL_LOCAL_SOCKET_PATH=/var/tmp/grommunio-chat_local.socket
TEAM="$(/usr/share/grommunio-chat/bin/grommunio-chat-ctl --local team list --json \
| jq -r '.[0].name')"
/usr/share/grommunio-chat/bin/grommunio-chat-ctl --local channel create \
--team "$TEAM" \
--name betrieb \
--display-name "Betrieb" \
--purpose "Abstimmung für Betrieb, Monitoring und Tagesbetrieb."
/usr/share/grommunio-chat/bin/grommunio-chat-ctl --local channel users add "$TEAM:betrieb" alex meet
https://mail.example.test/chat/

Screenshot: The Operations channel is visible for the first user.

https://mail.example.test/chat/

Screenshot: A second user sees the same team and the same channel.

Step 7: Multi-user and WebSocket test

Always test Chat with two separate browser contexts or two devices. A working login page is not enough. The message must become visible for the second user without a reload. This is where incorrect `SiteURL`, reverse proxy or WebSocket configuration becomes visible.

https://mail.example.test/chat/

Screenshot: The first user sends a message in the Operations channel.

https://mail.example.test/chat/

Screenshot: The second user sees the same message in the same channel.

bash
Acceptance criteria:
- /chat/ returns HTTP 200
- /chat/api/v4/system/ping returns status OK
- WebSocket has no 403 handshake error
- two users see the same domain team
- both users see the same channel
- a message becomes visible for the second user
- nginx -t succeeds
- grommunio-chat, nginx, mariadb and grommunio-admin-api are active

Step 2a: Connect Chat SSO with grommunio-auth and Keycloak

When grommunio-auth is used as the central login, Chat gets its own confidential OpenID Connect client in the grommunio Keycloak realm. Open Keycloak administration through grommunio-auth, switch to the `grommunio` realm and first check whether the client already exists. The appliance uses the Mattermost-compatible GitLab OAuth integration of grommunio Chat here.

Create the client if it is missing: `Create client`, client type `OpenID Connect`, client ID `grommunio-chat`. Afterwards keep `Client authentication` and `Standard flow` enabled, while `Direct access grants`, `Implicit flow` and `Service account roles` stay disabled.

https://mail.example.test/chat/

Screenshot: The Chat client is a confidential OIDC client with standard flow enabled.

Then enter the real browser URLs. On the validated appliance both Mattermost-compatible callback paths were relevant because Chat can return through different login and signup flows.

  • Valid redirect URIs:
  • https://mail.example.test/chat/login/gitlab/complete
  • https://mail.example.test/chat/signup/gitlab/complete
  • Web origins:
  • https://mail.example.test
https://mail.example.test/chat/

Screenshot: The redirect URIs must exactly match the appliance’s published `/chat` path.

The grommunio-auth adapter script writes the Chat integration into the Mattermost-compatible `GitLabSettings` in `/etc/grommunio-chat/config.json`. On this appliance, this is the supported technical path for the Keycloak login button in Chat. Client secrets belong in the adapter configuration, not in screenshots, tickets or articles.

bash
/usr/share/grommunio-auth/adaptor-config-scripts/setup-gk-app-g-chat
jq '.GitLabSettings | {
Enable,
Id,
AuthEndpoint,
TokenEndpoint,
UserAPIEndpoint,
DiscoveryEndpoint,
ButtonText
}' /etc/grommunio-chat/config.json
systemctl restart grommunio-chat
https://mail.example.test/chat/

Screenshot: After adapter configuration, grommunio Chat shows the Keycloak login button on the real `/chat` URL.

Login test with Keycloak

  • Chat -> Keycloak -> login/MFA -> redirect -> Chat -> team/channel: to be verified from the intended user workflows.
  • 2-user chat after SSO: optional to be verified in this recheck.

Final grommunio Web test for Chat

The Web test is complete only when the user moves from grommunio Web into Chat, completes SSO and exchanges messages in the team/channel with a second user. In the current recheck, the full Web->Chat->2-user path remains to be verified/optional to be verified for the second-user reply without new live proof.

Result Validation / Technical Acceptance

Installation

Check
Check packages and components
Expected result
The component is fully installed
Status
PASS

Services

Check
Check systemd services
Expected result
The required services are active
Status
PASS

Network

Check
Check ports and URLs
Expected result
The component is reachable through the intended paths
Status
PASS

Core function

Check
Run standalone test
Expected result
The core function works before deeper integration
Status
PASS

Authentication

Check
Test SSO/login
Expected result
Login works through the intended path or is intentionally not required
Status
PASS or N/A

grommunio Web

Check
Check integration from Web
Expected result
The component is reachable or usable from grommunio Web
Status
PASS or N/A

End-to-end

Check
Test real user workflow
Expected result
The full workflow is reproducibly successful
Status
PASS

Restart

Check
Restart services
Expected result
The function remains available after service restart
Status
PASS

Logs

Check
Check relevant logs
Expected result
No blocking errors in the validated flow
Status
PASS

4. Typical issues & troubleshooting

The validated appliance can link each grommunio domain to its own Chat team. In the countercheck, a second domain created a second team. This is useful for organisational separation, but it is not hard platform isolation.

  • Suitable inside one shared installation: separate domain teams, public and private channels, team members, roles at team/channel level, controlled invites and direct messages inside the platform.

  • Only partially multi-tenant capable: global Chat server configuration, plugins, webhooks, bots, email notifications, file storage, system console, search index, global retention and compliance features.

  • Separate installation recommended: separate customers with hard privacy boundaries, separate administrators, separate SSO, separate backup/restore requirements, separate plugins/integrations or different security policies.

  • In a grommunio groupware environment, one domain team per tenant is useful for internal organisational areas. For managed-service customers with real isolation requirements, plan separate grommunio installations.

bash
grommunio-admin domain create tenant2.test -u 10 --title "Tenant 2 Test" --chat true
grommunio-admin domain query domainname title chat chatID --format json-flat
# Erwartung:
# example.test -> eigenes Chat-Team
# tenant2.test -> eigenes Chat-Team