Zweep is a Zabbix media type with its own server and Android app. Zabbix sends alarms to the Zweep media type as it does with e-mail or SMS; the media type hands them to your self-hosted Zweep server, which delivers them to the Zweep app on the operators' phones: a notification with the sound of its severity, the open problems of the operator's perimeter, and acknowledgements from the phone, recorded in Zabbix.
You use it like any other media type: alone, together with e-mail, or as one step of an escalation in Zabbix Actions. Who is notified, and when, stays in Zabbix.
Delivery you can rely on. Zweep answers the media type only after the alarm is stored, the phone confirms every alarm it receives, and after a network loss it receives what it missed, once and in order. If Zweep cannot accept an alarm, the media type fails like any other: Zabbix retries it, and an escalation goes on with its next step.
- Acknowledge from the phone: take charge of a problem with a message, recorded in Zabbix; as usual, acknowledging stops the escalation.
- A quick look, not a second frontend: the open problems of your perimeter with the Recent, Problems and History views, filters and search, to correlate on the fly. The full analysis stays in the Zabbix frontend.
- No Zabbix or domain credentials on the phone: operators activate the app with a QR code from the Zweep dashboard (or a Zweep account, separate from Zabbix and from the domain); the app never connects to Zabbix. In Zabbix they need a user only as the recipient of the media type, without frontend access.
- On-premises, nothing in between: the Android app connects only to your Zweep server, next to Zabbix: no cloud, no third-party push service (not even Google's).
- Works without internet: with the server and the Android app, on the company network alone (Wi-Fi, VPN) alarms keep arriving even when the internet connection is down, which is often exactly when they matter. Services in the cloud and push notifications need the internet.
- Zweep Web, if you want it: an optional plugin for iPhone, iPad and computers. Its notifications are push notifications, so it is the one part of Zweep that needs the internet (see below).
- No costs: no subscription, no per-message fees, no SMS gateway. Free software.
- An app only for monitoring: alarms do not mix with the chats of Telegram, WhatsApp or Teams, where they are easily muted or ignored; every severity and channel has its own sound.
| What it gives | Limits for alerting | |
|---|---|---|
| E-mail / SMS from Zabbix | built in | no problem list, no acknowledgement from the phone; SMS costs, e-mail is easy to miss |
| Telegram, WhatsApp, Teams, Slack | quick to set up | alarms mixed with chats; they need the internet and leave your network through a third party; delivery is not confirmed back to Zabbix |
| Cloud incident platforms | rich on-call features | subscription, alarm data in the cloud, a second place where escalations are defined |
Zabbix, the Zweep server and the Android app: everything stays in your network, and alarms arrive without the internet. Phones can also reach the server over the internet (VPN, or Zweep published with HTTPS, chapter 5.7): always a direct connection to your server, never through a third party.
For iPhone, iPad and computers, the Zweep Web plugin offers the same screens in a browser. It is a
second service of the same image (Compose profile web), off until you turn it on. Its notifications
go through the push service of the browser vendor (Apple, Google, Mozilla, Microsoft), so this
scenario needs the internet: outbound HTTPS from the plugin, and a public HTTPS address for the
plugin. Only the browser can read a notification: the push service carries it encrypted. The
Android app does not change and stays the reliable way (chapter 13).
- Reliable delivery: every alarm is stored, numbered and confirmed by the phone; after a network loss or a restart the phone receives what it missed, once, in order.
- Problems and acknowledgements: the problems of the operator's perimeter (sources, host groups, severities) with the Recent, Problems and History views of Zabbix; acknowledge with a message from the phone, recorded in Zabbix.
- Several Zabbix instances (7.0 and later) on one server; the phone never connects to Zabbix and holds no Zabbix credentials.
- Channels and sounds: one channel per severity plus custom channels (hosts, host groups, tags), reminders, Do Not Disturb override for the channels you choose.
- Dashboard: users, user groups, perimeters, phones, deliveries, alarms, test messages and announcements, audit log, backups, HTTPS. Roles admin and manager, optional two-step verification.
- HTTPS your way: Let's Encrypt, company ACME CA, uploaded certificate, self-signed with key pinning in the activation QR code, or behind your reverse proxy.
- Zweep Web (optional plugin, off by default): the same screens in a browser for iPhone, iPad and computers, with Web Push notifications, which need the internet; a separate small service next to the server. The Android app remains the reliable way.
- App updates from your server: the signed APK is in the image; phones are offered new versions.
- Small and hardened: one Go binary in a distroless container, non-root, read-only; PostgreSQL is the only dependency. Metrics for Prometheus and Zabbix, encrypted daily backups, SBOM.
- English and Italian.
Requirements: Docker with Compose on Linux, a Zabbix 7.0+ server that can reach Zweep, Android 10+ phones, a DNS name for Zweep (needed for a trusted certificate).
Before you start, check Docker on the server:
docker --version && docker compose version # Docker Engine with the Compose plugin, not the old docker-composeIf the server is itself a system container (LXC and similar), its host must allow nested containers.
Run the commands below as root (sudo -i first, if you use sudo: with a plain sudo the >
redirections fail).
git clone https://github.com/N1k0droid/zweep.git /opt/zweep && cd /opt/zweep
cp .env.example .env # then edit it: ZWEEP_SERVICE_URLS is the address phones and Zabbix use
mkdir -p secrets backups
head -c 32 /dev/urandom > secrets/master.key # master key: encrypts the secrets and the backups
openssl rand -hex 24 > secrets/postgres-password # password of the database of the stack
printf 'postgres://zweep:%s@db:5432/zweep?sslmode=disable' "$(cat secrets/postgres-password)" > secrets/database-url
chmod 600 secrets/* # readable by their owner only
chown 65532:65532 backups secrets/master.key secrets/database-url # the user of the container
docker compose up -d⚠ Copy secrets/master.key to a safe place now, away from the backups. It encrypts every secret
Zweep stores (Zabbix API tokens, webhook secrets, two-step verification, certificate keys) and every
backup: without it neither can be read, and whoever has both the key and a backup can read everything
(chapter 3.2).
Check the first start:
docker compose ps # zweep and db become "healthy" in a few seconds
curl -s http://127.0.0.1:8080/v1/health # {"healthy":true}
docker compose logs zweep | grep -o 'zws_[A-Za-z0-9_-]*' | tail -1 # one-time setup token for the first adminhttp://<server>:8080/v1/health must answer from another PC too: if it answers only on the server, a
firewall is in the way. The setup token is valid for one hour; docker compose restart zweep prints
a new one as long as no admin exists.
Then:
- First admin: the dashboard listens only on the loopback of the Docker host. From your PC open
an SSH tunnel,
ssh -N -L 8081:127.0.0.1:8081 user@<server>(it stays open and shows nothing), then openhttp://127.0.0.1:8081/admin/and enter the setup token. Create a second admin before you turn on two-step verification. To reach the dashboard from the LAN instead, or if the tunnel is refused, see chapter 3.6. - HTTPS: Dashboard → Settings → HTTPS (manual, chapter 5). Behind a
reverse proxy choose No HTTPS here and set
ZWEEP_TRUSTED_PROXIES. - Zabbix: create a source, import the media type from Dashboard → Download, add an action with escalation; then the service user for the Problems tab and the acknowledgements (chapter 6).
- Phones: create the operators, scan the download QR code to install the app, then the activation QR code (chapters 7 and 8).
- Monitor Zweep: import the Zabbix template of Dashboard → Download and notify its problems by e-mail or SMS, not through Zweep (chapter 10.1).
Images: ghcr.io/n1k0droid/zweep and the mirror docker.io/n1k0droid/zweep (linux/amd64,
linux/arm64). The signed APK is also attached to every release.
| From → to | Port | What for |
|---|---|---|
| Zabbix server → Zweep | public port (ZWEEP_PUBLIC_PORT, 8080 or 443) |
media type webhook |
| Phones → Zweep | public port | alarms (WebSocket), app API, app download |
| Zweep → Zabbix frontend | 80 / 443 | problem list and acknowledgements (Zabbix API) |
| Your PC → Docker host | SSH, then 127.0.0.1:8081 |
dashboard (not published by default) |
| Zabbix server → Zweep (optional) | metrics port, e.g. 9464 | monitoring of Zweep (template in Download) |
| Zweep → Internet (optional) | 443 | Let's Encrypt or your ACME CA; DNS provider API for DNS-01 |
| Internet → Zweep (optional) | 80 | Let's Encrypt HTTP-01 challenge only |
| Browsers → Zweep Web plugin (optional) | 443, public HTTPS address (reverse proxy) | Zweep Web pages and actions |
| Zweep Web plugin → Zweep (optional) | public port | the plugin's connection to the server |
| Zweep Web plugin → Internet (optional) | 443 | push services of Apple, Google, Mozilla, Microsoft (chapter 13.3) |
Phones accept a certificate from a public or company CA, or a self-signed one whose key is pinned in the activation QR code; plain HTTP is for labs only (chapter 5).
cd /opt/zweep
docker compose exec -T zweep zweep-server backup -out - > zweep-$(date +%F).zwbk # or use the daily backup in ./backups
git pull # compose.yaml and .env.example of the new version; .env and your override stay yours
diff .env .env.example # new settings of the version, if any (read the CHANGELOG)
nano .env # ZWEEP_IMAGE=ghcr.io/n1k0droid/zweep:<new version>
docker compose pull
docker compose up -dThe database is migrated at start; downgrades are not supported: restore the backup instead (chapter 10). Phones are offered the new app by your server.
To try Zweep on a PC with Docker Desktop (Windows, macOS or Linux) before a real deployment:
- Do the same steps as above, with these differences in
.env:ZWEEP_SERVICE_URLS=http://<IP of the PC on your network>:8080andZWEEP_IMAGEas published. Thechownis not needed with Docker Desktop. - Open
http://127.0.0.1:8081/admin/, create the admin, then an operator and its activation QR code. - Install the app from Dashboard → Download (QR code), scan the activation QR code: the app warns that the connection is not encrypted (plain HTTP is accepted only after your confirmation).
- Send alarms from Dashboard → Test, without Zabbix; connect a Zabbix test instance when ready.
Do not use this setup for real alarms: no HTTPS, and the PC must stay on.
The manual covers installation, configuration, HTTPS, Zabbix, users and channels, the app, the dashboard, operations, troubleshooting, the reference (command line, admin API, webhook, metrics) and the web client. Security and regulatory mapping (NIS2, ISO/IEC 27001, CRA, AI Act): docs/COMPLIANCE.md. Changes: CHANGELOG.md.
make build # server binary in dist/
make docker # container image (put the signed APK in apk/ first)
make check # gofmt, vet, race tests, govulncheck, gosec
make sbom # CycloneDX SBOM in dist/Database tests need ZWEEP_TEST_DATABASE_URL (a PostgreSQL where the tests may create schemas).
The Android app is in android/: see android/signing/README.md
for release builds. An app signed with another key cannot update the official one.
| Path | Content |
|---|---|
cmd/zweep-server |
command line: serve, healthcheck, admin |
cmd/zweep-web |
the Zweep Web plugin (optional) |
internal/ |
server: API, dashboard, delivery, store (PostgreSQL), Zabbix API, HTTPS, backups; webclient and webpush: the Zweep Web plugin and its push notifications |
zabbix/ |
Zabbix media type (script and importable YAML) |
android/ |
Android app (Kotlin, Jetpack Compose) |
docs/ |
manual and compliance |
Please report vulnerabilities privately: see SECURITY.md.
Zweep is designed and developed by N1k0droid. If Zweep is useful to you, a ⭐ on this repository and a follow help the project grow.
Developed with the help of an AI coding assistant: see docs/COMPLIANCE.md.
Zweep is free software under the GNU Affero General Public License v3.0 only (LICENSE,
SPDX AGPL-3.0-only). If you run a modified Zweep for users over a network, you must offer them the
source code of your version (AGPL §13). Third-party components and their licenses:
THIRD_PARTY_NOTICES.md.
Zweep is a client for Zabbix; it is not affiliated with or endorsed by Zabbix LLC. Zabbix is a trademark of Zabbix LLC.



