ChatOps is the habit of making the systems talk in the same place the people do. It works when the notifications are trustworthy and the noise is low, and it works best when the chat server is yours, so a webhook URL is not a secret you hand to a third party. This post follows a developer building that on MassiveGRID PaaS, which is built on Virtuozzo Application Platform, formerly Jelastic, with Mattermost as the hub.
The developer maintains the internal tools of a 40-person product team we will call Halden Digital. The team runs Mattermost and a GitLab server as two environments on the same PaaS account, and deploys its application to a third environment. The goal is a single channel, #ops, that shows pipelines, deployments and infrastructure health without anyone opening a dashboard.
Mattermost speaks Slack, which is the whole trick
Mattermost's incoming webhooks accept the same JSON payload that Slack's do: a text field, optional attachments with colours and fields, and a channel override. Any tool that can post to a Slack webhook can post to Mattermost by swapping the URL. The developer creates one incoming webhook per source in Mattermost's integrations panel (each webhook is a distinct URL, so a leaked one can be revoked without touching the others) and locks each to the #ops channel.
Because both Mattermost and GitLab are on the same platform account, the developer also puts them in one environment group and lets them talk over the internal network, which carries no traffic charge and never leaves the data centre. The webhook URLs use the internal hostnames.
Source one: GitLab pipelines and merge requests
GitLab has a native Mattermost notifications integration, so this source needs no glue at all. In the project's integrations settings the developer enables Mattermost notifications, pastes the webhook URL, and selects the events worth a message: pipeline failed, pipeline fixed, merge request opened, deployment. She deliberately leaves out push and pipeline succeeded. The team learned early that a channel which announces every green pipeline is a channel people mute.
The GitLab server itself is the marketplace package, which runs GitLab CE in a Docker Engine container alongside an auto-scaling runner layer, so a burst of merge requests on release day does not queue pipelines. The Mattermost side receives them at the same rate the runners finish.
Source two: platform deployment hooks
The application environment deploys from its Git repository through the platform's Deployment Manager. The Deployment Manager supports hooks: scripts that run before and after a deployment on the application server. The developer adds a post-deploy hook that posts to Mattermost with the environment name, the commit and the time. Because the hook runs on the node that was just deployed, it can also include something a CI system cannot: the result of a local health check against the freshly deployed code.
#!/bin/bash
STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://localhost/healthz)
curl -s -X POST -H 'Content-Type: application/json' \
-d "{\"text\": \"Deployed to production, health check returned $STATUS\"}" \
http://mattermost-node.internal/hooks/your-webhook-id
With the layer set to sequential deployment, a two-node application posts twice, once per node, thirty seconds apart, which is exactly the rhythm the on-call engineer wants to see: node one healthy, node two healthy, done.
Source three: platform load alerts
The platform sends load alerts by email when a node crosses a resource threshold for a set time: RAM, CPU, disk, inodes, network or IOPS. Email is fine for a monthly review but not for a channel. The marketplace has a Load Alerts to Slack add-on that forwards those alerts to a Slack webhook, and because Mattermost accepts Slack's format, the developer installs it on each environment and gives it a Mattermost webhook URL. The alert message arrives with the environment, node, resource and percentage, which is enough to decide whether to raise a cloudlet limit from a phone.
| Source | Mechanism | Events kept | Events dropped |
|---|---|---|---|
| GitLab | Native Mattermost notifications integration | Pipeline failed or fixed, MR opened, deployment | Push, pipeline succeeded, comments |
| Deployments | Deployment Manager post-deploy hook | Each node's deploy with its health check | Nothing |
| Infrastructure | Load Alerts to Slack add-on, Slack-compatible webhook | RAM or CPU above 80% for 10 minutes, disk above 85% | Recovery notices below 50% |
Making the channel actionable, not just informative
Notifications are half of ChatOps. The other half is doing something from the chat. The developer adds two Mattermost slash commands backed by a small internal service. /env status production calls the platform's CLI to fetch the environment's node list and current cloudlet usage and posts a summary; /env scale production 24 raises the dynamic cloudlet limit on the application layer. The service holds the platform API token, not the chat users, and only members of the #ops channel can invoke the commands, which is a reasonable authorisation boundary for a 40-person team.
The platform's CLI and API cover the same operations the dashboard does, so the commands are thin wrappers, not reimplementations. Anything more complex, like cloning an environment for a hotfix test, stays a dashboard task on purpose.
Why self-hosting matters for this pattern
Every webhook URL in this setup is a credential that lets its holder post into the company's operations channel, and every slash command is a route into infrastructure control. On a hosted chat service those URLs traverse the public internet and live in someone else's database. Here they stay on the internal network of one PaaS account, Mattermost logs every webhook post with its source, and rotating a URL is a click. Halden's security review took an afternoon, mostly because there was nothing to review outside its own account.
Frequently Asked Questions
Does the Load Alerts to Slack add-on really work with Mattermost?
Yes. It posts a Slack-format JSON payload to the webhook URL you provide. Mattermost's incoming webhooks accept that format, including attachments, so the message renders correctly. Create the webhook in Mattermost, paste its URL into the add-on's settings, and send a test alert.
Can I use Mattermost's official GitLab plugin instead of webhooks?
You can. The Mattermost GitLab plugin adds two-way features such as subscribing channels to repositories and receiving personal to-do reminders. It requires OAuth configuration on the GitLab server. Webhook notifications are simpler and one-directional; many teams start there and add the plugin later.
How do I keep the webhook traffic off the public internet?
Place the Mattermost, GitLab and application environments in one environment group on the same account and use the nodes' internal hostnames in the webhook URLs. Internal traffic between environments on the platform is free and does not leave the data centre. If you enable network isolation on the group, only environments inside it can reach those hostnames.
Put your operations channel on your own server
Install Mattermost and a GitLab server side by side on MassiveGRID PaaS, connect them over the free internal network and forward platform alerts with the Load Alerts to Slack add-on. Pay per cloudlet-hour, 100% uptime SLA. Free 14-day trial.
Mattermost on MassiveGRID PaaS