A self-hosted team chat
Group chat where the history lives on your own disk, not in someone’s SaaS that can read it, price you up, or disappear. Mattermost or Rocket.Chat both do the job.
Mattermost is a single Go binary with a PostgreSQL database behind it. That makes it light — it runs comfortably where GitLab would not — and easy to keep alive as a systemd service.
The parts
- The server binary, run as its own unprivileged user
- PostgreSQL for messages and metadata — see running PostgreSQL
- A directory (or object storage) for uploaded files
- nginx in front for TLS and websockets
Websockets through the proxy
Chat is live, so the reverse proxy must pass websocket upgrades or messages arrive only on refresh. In nginx that means forwarding Upgrade and Connection headers on the API location. If presence and typing indicators do not work, this is almost always why — see a reverse proxy in front.
File storage
By default uploads land in ./data. Give that its own volume, or point it at S3-compatible object storage if you expect a lot of images and files. Either way it grows without limit unless you set a retention policy.
Push notifications
Mobile push on the public apps goes through a hosted push proxy — the message title and body can be kept off it, but the fact of a notification does traverse it. If that matters for your use case, run the push proxy yourself; the payload then never leaves your network.
Back up both halves
As with any database-plus-files application, a backup is the PostgreSQL dump and the data directory, taken close together. See backups that actually restore.
Still stuck? Mail support@novogara.com — an engineer answers, at any hour. Back to the knowledge base