Extend the provisioned Telegram proxy fleet selector with visible host name 02-tekhnohim-docker while retaining the existing Agent 2 technical identity Fedora Kirochnaya.\n\nMake the collector read Prometheus metrics from 127.0.0.1:9090 inside the Telemt network namespace. This avoids dependence on host port 9092 and preserves the existing source-restricted metrics publication.\n\nValidated the dashboard with jq, the collector with bash -n, and the deployed Agent 2 keys on Client 02. The unrelated .DS_Store changes remain unstaged.
6.2 KiB
Internal logging stack
Portainer Git stack for outline (10.0.0.6). It replaces only the logging
part of the manual mktxp-stack:
lokistores syslog in the persistent host path/mnt/containers/logging/loki-data;syslog-ngaccepts and normalizes the fleet's mixed/raw syslog formats;alloyreplaces Promtail and sends normalized RFC5424 to Loki;grafanaprovides the MikroTik Loki dashboard and a Telemt fleet dashboard backed by the internal DEPOT Zabbix server.
The retired stack's mktxp, Prometheus, and Promtail services are not part of
this stack. syslog-ng remains because real DEPOT RouterOS traffic includes raw
messages that Alloy's strict RFC3164 parser rejects.
Portainer settings
- Repository:
https://git.it-depot.ru/depot/docker-infrastructure - Branch:
master - Compose path:
logging/docker-compose.yaml - Required environment variables:
GRAFANA_ADMIN_PASSWORDZABBIX_API_TOKEN— token for a read-only Zabbix API user; it is passed into Grafana's provisioned datasource and must not be committed.
Do not deploy the new stack before completing the cutover below: the current
containers still own names loki and grafana and host ports 3000, 3100, 514,
and 601.
Host files
The Git-backed compose file intentionally bind-mounts stable host paths. Before deployment, the repository files must be copied to:
/mnt/containers/logging/
├── alloy-config/config.alloy
├── alloy-data/
├── grafana-config/
│ ├── dashboards/mikrotik-loki-logs.json
│ ├── dashboards/telemt-proxy-fleet.json
│ └── provisioning/
│ ├── dashboards/dashboards.yaml
│ └── datasources/{loki,zabbix}.yaml
├── grafana-data/
├── loki-config/config.yaml
├── loki-data/
└── syslog-ng-config/syslog-ng.conf
SELinux is enforcing. The compose mounts use :Z; do not remove those flags.
The persistent data directories should be owned by the container users:
Loki 10001:10001, Grafana 472:0, and Alloy 0:0.
Cutover
The live Loki history is inside the old container at /tmp/loki. Do not merge
a newer WAL over an older rescue WAL: the resulting non-contiguous segment
sequence makes Loki fail with segments are not sequential. Instead, move the
seed aside and copy the stopped container's complete data directory as one
generation:
cd /mnt/containers/mktxp/mktxp-stack
# Record a last pre-cutover query and stop all writers cleanly.
curl -fsS http://127.0.0.1:3100/ready
docker compose stop
# Preserve the seed separately; never overlay WAL generations.
mv /mnt/containers/logging/loki-data \
/mnt/containers/logging/loki-data-rescue-seed-2026-07-30
docker cp -a loki:/tmp/loki /mnt/containers/logging/loki-data
chown -R 10001:10001 /mnt/containers/logging/loki-data
# Removes containers and the old network, but NOT the old named Grafana and
# Prometheus volumes. Do not add --volumes.
docker compose down
Now deploy the Portainer Git stack. Expected interruption is the time between
docker compose stop and the new stack becoming ready.
Verification
docker ps --filter name=loki --filter name=alloy --filter name=grafana
curl -fsS http://127.0.0.1:3100/ready
curl -fsS http://127.0.0.1:3000/api/health
ss -lnup | grep ':514'
ss -lntp | grep -E ':(601|3000|3100)\b'
Confirm both history and new ingestion:
START=$(date -u -d '24 hours ago' +%s%N)
curl -fsSG http://127.0.0.1:3100/loki/api/v1/query_range \
--data-urlencode 'query={job="syslog"}' \
--data-urlencode "start=$START" \
--data-urlencode 'limit=1'
logger --server 127.0.0.1 --udp --port 514 \
--rfc3164 --tag depot-cutover-test 'alloy ingestion test'
In Grafana, the provisioned Network / Mikrotik Loki Logs dashboard should
list existing routerboard values and show both pre-cutover and post-cutover
entries.
Telemt / Zabbix monitoring
The Zabbix server is 10.0.0.11 internally. The DEPOT router at 10.0.0.1
publishes TCP 185.108.4.158:10051 only for the four proxy-host egress
addresses, allowing Zabbix Agent 2 active checks without exposing the trapper
to the whole internet.
Create the following Zabbix hosts. The technical Host name must match the
Agent 2 Hostname; Grafana selects the Visible name shown below.
| Client | Zabbix Host name | Visible name |
|---|---|---|
| 00-xserver | 00-xserver-fedora-xxx |
00-xserver-fedora-xxx |
| 02-tekhnohim | Fedora Kirochnaya |
02-tekhnohim-docker |
| 11-nevafud | 11-nevafud-fedora |
11-nevafud-fedora |
| 19-nutrilent | 19-nutrilent-docker |
19-nutrilent-docker |
Import zabbix-template-telemt-active.yaml, link Telemt proxy by active
agent to all four hosts, and ensure each host is in the Linux servers
group. All four send active checks to 185.108.4.158. Client 02 should have no
DEPOT passive-agent interface; its existing local Zabbix server continues to
perform the host's passive Linux checks independently.
The matching host-side collector is in zabbix-agent/. It enters only the
Telemt container network namespace for the control API, discards links and
secrets, caches the active-IP list and Prometheus values, and exposes
read-only Agent 2 keys. The active-IP list retains one day of history; the
numeric count and other counters retain 31 days.
After redeploying Grafana with a valid ZABBIX_API_TOKEN, verify:
docker exec grafana grafana cli plugins ls
curl -fsS http://127.0.0.1:3000/api/health
The provisioned Network / Telegram proxy fleet dashboard selects one of the four visible host names above and mirrors the Telemt section of the client-02 dashboard: current IP count, active/total connections, IP list, traffic, and uptime.
Rollback
Remove the new Portainer stack, then recreate the old stack with its Loki data
bound back into /tmp/loki:
cd /mnt/containers/mktxp/mktxp-stack
cp docker-compose.yaml docker-compose.rollback.yaml
Add this second volume to the loki service in
docker-compose.rollback.yaml:
- /mnt/containers/logging/loki-data:/tmp/loki:Z
Then run:
docker compose -f docker-compose.rollback.yaml up -d
curl -fsS http://127.0.0.1:3100/ready
Do not restore the old Loki without that bind mount: its original writable layer is deleted when the old stack is taken down.