Self-managed GitLab can do everything gitlab.com does with Slack, but the paths differ in who has to do the work and what has to talk to what. Before you pick a method, settle two questions: does an administrator have to set it up once for the whole instance, and does anything outside your network need to reach in? Those two answers decide the rest.
The 60-second version
- The native GitLab for Slack app works on self-managed since 16.2 (per-instance GA in 17.8), but an administrator has to create the Slack app from a manifest and enable it first.
- The reachability rule is the crux: notifications only need the instance to reach slack.com outbound; slash commands need Slack to reach your instance inbound.
- DIY webhooks need a receiver your instance can reach; an internal receiver may require allowing webhook requests to the local network.
- A read-only tool connects with your GitLab URL and a
read_apitoken, no admin Slack-app install required.
Option 1: the native GitLab for Slack app on self-managed
The GitLab for Slack app is GitLab's own app, and it supports self-managed instances since 16.2, with per-instance support generally available in 17.8. The catch on self-managed is that it isn't a per-project toggle you can flip alone. An administrator has to enable the integration for the instance first: create the Slack app from GitLab's manifest (Admin, then Settings, General, GitLab for Slack app, Create Slack app), enter the app credentials back in GitLab, and tick the enable checkbox. Only then can projects configure their channels.
The part that actually causes support tickets is network reachability. GitLab's docs split it cleanly:
- For notifications, the GitLab instance must be able to send requests to
https://slack.com. That's outbound only. - For slash commands and other interactive features, the GitLab instance must be able to receive requests from
https://slack.com. That's inbound, from the public internet.
So an instance locked behind a VPN with no inbound path can still send Slack notifications, but its slash commands won't work — Slack has nowhere to deliver the command to. If you only want merge request and pipeline notifications, outbound is enough; if you want the ChatOps side, you're opening an inbound route, which is a security conversation with whoever owns the network.
Option 2: DIY with GitLab webhooks
You can skip the app and wire GitLab project webhooks into Slack yourself. On self-hosted the moving parts are the same as anywhere, with one extra wrinkle: the receiver has to be reachable from your GitLab instance. If your relay service runs on the same internal network as GitLab, an administrator may need to allow webhook requests to the local network, which is blocked by default to prevent server-side request forgery.
Two operational facts to plan around:
- A Slack incoming webhook only creates messages. A single updating message per MR or threaded comments need the
chat.updateWeb API with a bot token and stored message state — a real service, not a config. - GitLab disables a webhook that fails four consecutive times (temporarily, backing off up to 24 hours) and permanently after 40. On an internal receiver that reboots or moves, this is easy to hit and easy to miss.
Option 3: a read-only tool that connects to your instance
A third-party notifier connects to your self-hosted GitLab over the API instead of asking an administrator to install a Slack app on the instance. The access model is the thing to check. A read-only tool authenticates with your GitLab URL and a personal access token scoped to read_api, and can post to Slack without ever being able to change anything in GitLab. Tools that let you merge or comment back from Slack need write-capable access, which is more power and more blast radius.
Full disclosure: we make PRFlow, which takes the read-only path. You connect a self-hosted instance with its URL and a read_api token; it polls automatically, and you can add a webhook for near-instant delivery. No admin has to install a Slack app on your GitLab. Here's the honest comparison with the native GitLab for Slack app, including where the native app is the better fit.
Which one should you pick?
- Want the official app and can commit admin time plus an inbound route for slash commands? The native GitLab for Slack app.
- Only need notifications, no slash commands? Either the native app (outbound only) or a read-only tool — pick on whether you want per-event messages or one message per MR.
- Have specific routing needs and engineering time? DIY webhooks, with the local-network and auto-disable caveats in mind.
- Don't want an admin installing anything on the instance? A read-only tool that connects over the API with a
read_apitoken.
Bottom line
Self-hosted GitLab Slack notifications aren't hard once you separate outbound from inbound. Notifications are cheap; slash commands cost you an inbound route and a security review. Decide which you need, keep the token scoped to the minimum, and monitor whatever receives the events so a silent disable doesn't take your channel offline. For the full set of connection methods, see the GitLab Slack integration guide or the GitLab integration overview.