Skip to main content
Version: Unreleased

Installation Guide

Welcome to the Installation Guide! This page will help you set up and configure the system using Docker, Podman, Quadlet, or Kubernetes.

Upgrading from a Previous Version

If you are upgrading from a previous version of Monitor, please refer to the Migration Guides before proceeding with the installation. These guides contain important steps to ensure a smooth upgrade process.

Installation Methods:

  • Docker Setup: Quick and easy containerized installation.
  • Podman Setup: Docker-compatible, rootless containers.
  • Quadlet Setup: systemd-native Podman, no compose required.
  • Kubernetes Setup: For scalable, production-grade deployments.

To install using Docker:

  1. Download the provided docker-compose.yml file below.
  2. Pull the container image from the registry: docker pull registry.frafos.net/abc/mon:<tag>
  3. Update your docker-compose.yml to use the registry image:
    image: registry.frafos.net/abc/mon:<tag>
  4. Run: docker-compose up -d
  5. Access the dashboard at http://localhost:445
note

Fresh installations use plain HTTP only, as nginx and self-signed certificates are not included by default.

Container images are available at: Frafos Container Registry

Possible CAPs to be used during runtime

  • CAP_NET_BIND_SERVICE: Needed to give the container access to open a port for receiving syslog messages.
Show example docker-compose.yml

⬇️ Download docker-compose.yml

docker-compose.yml
# Example Docker Compose file for Frafos monitoring stack
# Each service below represents a containerized application.

services:
ccm:
# Call Control Manager (CCM) service
image: registry.frafos.net/abc/ccm:5.6
container_name: ccm
ports:
- "443-444:443-444" # Expose ports 443 and 444
networks:
- monitoring # Connect to monitoring network
- signaling # Connect to signaling network
restart: always # Always restart on failure
volumes:
- ccm-data:/data # Persist data in named volume
cap_add:
- AUDIT_CONTROL # Add audit control capability
- AUDIT_WRITE # Add audit write capability
- CAP_NET_BIND_SERVICE # Allow binding to low-numbered ports

elastic:
# Elasticsearch service for log and metric storage
image: docker.elastic.co/elasticsearch/elasticsearch:9.1.5
container_name: elastic
ports:
- "9200:9200" # HTTP API
- "9300:9300" # Transport protocol
environment:
- discovery.type=single-node # Run as single node
- xpack.ml.enabled=false # Disable ML features
- network.host=_local_,_site_ # Bind to local and site interfaces
- path.repo=/usr/share/elasticsearch/snapshots # Path for snapshots
#- thread_pool.search.queue_size=10000 # (optional) Increase search queue size
#- http.max_initial_line_length=16kb # (optional) Increase max HTTP header size
#- cluster.max_shards_per_node=166 # (optional) Increase max shards
#- indices.lifecycle.history_index_enabled=false # (optional) Disable ILM history

# 1. FOR PLAIN HTTP USE THE FOLLOWING VARIABLES -----
- xpack.security.enabled=false # Disable security
- xpack.security.http.ssl.enabled=false # Disable HTTP SSL
# 1.2 OR ENABLE SECURITY --- (default user = elastic) ---
# - xpack.security.enabled=true
# - ELASTIC_PASSWORD=Test1234 # curl -u elastic:Test1234 http://localhost:9200/

# 2. FOR SSL USE THE FOLOWING VARIABLES -------------
# - xpack.security.enabled=true
# - xpack.security.http.ssl.enabled=true
# - xpack.security.http.ssl.certificate=certs/server.crt
# - xpack.security.http.ssl.key=certs/server.key
# - xpack.security.transport.ssl.enabled=true
# - xpack.security.transport.ssl.certificate=certs/server.crt
# - xpack.security.transport.ssl.key=certs/server.key
# - xpack.security.transport.ssl.verification_mode=certificate
# - xpack.security.transport.ssl.certificate_authorities=certs/ca.crt
# 2.2 --- ANONYMOUS AUTH --- (not recommended for production, but can be useful for development and testing purposes)
# - xpack.security.authc.anonymous.username=anonymous
# - xpack.security.authc.anonymous.roles=superuser
# - xpack.security.authc.anonymous.authz_exception=false
# 2.3 --- OR ---
# - ELASTIC_PASSWORD=Test1234 # curl --cacert ./path/to/certs/ca.crt -u elastic:Test1234 https://localhost:9200/
networks:
- monitoring
restart: always
ulimits:
nofile:
soft: 65536
hard: 65536
memlock:
soft: -1
hard: -1
deploy:
resources:
limits:
memory: 4g
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:9200/ || exit 1"]
interval: 15s
timeout: 5s
retries: 20
start_period: 30s
volumes:
- es-data:/usr/share/elasticsearch/data # Data volume
- es-snapshots:/usr/share/elasticsearch/snapshots # Snapshots volume
#- ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro # (optional) Custom config
# - ./path/to/certs:/usr/share/elasticsearch/config/certs:ro

chrome:
# Headless Chrome for PDF generation or browser automation
image: zenika/alpine-chrome:124
#image: registry.frafos.net/contrib/alpine-chrome:latest # (alternative image)
container_name: chrome
#shm_size: "1gb" (optional) not required - zenika/alpine-chrome uses --disable-dev-shm-usage by default.
networks:
- monitoring
expose:
- "9222" # Expose remote debugging port
command:
- "--no-sandbox"
- "--remote-debugging-address=::"
- "--remote-debugging-port=9222"
restart: always
depends_on:
monitor:
condition: service_healthy
healthcheck:
test:
["CMD", "wget", "-q", "--spider", "http://localhost:9222/json/version"]
interval: 30s
timeout: 10s
retries: 3

monitor:
# Monitoring service (MONITOR)
image: registry.frafos.net/abc/mon:10.2
container_name: monitor
restart: always
ports:
- "445:445" # SERVER_PORT (445 on host, 445 in container)
- "514:514/udp" # VECTOR_SYSLOG_PORT (default VECTOR_SYSLOG_TRANSPORT_PROTOCOL is UDP)
- "514:514/tcp" # VECTOR_SYSLOG_PORT (when VECTOR_SYSLOG_TRANSPORT_PROTOCOL is TCP)
- "5044:5044" # VECTOR_SOCKET_PORT
- "5045:5045" # VECTOR_SOCKET_TLS_PORT
- "3042:3042" # UPLOAD_API_PORT
- "873:873" # UPLOAD_API_RSYNC_PORT
environment:
- BROWSER_URL=http://chrome:9222/
- PDF_RENDER_URL=http://monitor:445
#- CCM=ccm # (optional) CCM service name
#- ES=http://elastic:9200 # (optional) ES endpoint
#- REPORT_URL=http://localhost:445/report # (optional) Report URL (use localhost or bracketed IPv6 like http://[::1]:445/report)
#- ES_USERNAME=monitor # (optional) ES user
#- ES_PASSWORD=password # (optional) ES password
#- ADVANCED_ALERTS=true # (optional) Enable Advanced Alerts
#- ADVANCED_ALERTS_URL=http://alerts:80 # (optional) Advanced Alerts URL
volumes:
- monitor-data:/data:U # Persist MONITOR data
# (optional) needed by the bundled SQLite I/O collector below, to
# attribute disk I/O to the sqlite db file itself instead of the
# whole disk. Both mounts are required on Docker too, not just
# Podman: this bpftrace version looks for tracefs at
# /sys/kernel/tracing specifically, not /sys/kernel/debug/tracing -
# mounting only /sys/kernel/debug leaves it unable to find
# kprobe_events at all, regardless of container engine.
- /sys/kernel/debug:/sys/kernel/debug:rw
- /sys/kernel/tracing:/sys/kernel/tracing:rw
networks:
- monitoring
mem_limit: 1.5G
cpus: 1.0
cap_add:
- CAP_NET_BIND_SERVICE
- CAP_SYS_ADMIN # (optional) lets the bundled SQLite I/O collector attribute disk I/O to the db file itself instead of the whole disk
security_opt:
# (optional, paired with CAP_SYS_ADMIN above) Docker's default
# seccomp profile blocks perf_event_open, which bpftrace's
# kprobes need to attach - without this, bpftrace starts but
# immediately fails with "perf_event_open: Function not
# implemented" / "ERROR: Failed to open perf buffer", confirmed on
# Docker (not just Podman, where the same profile issue exists but
# is documented separately in the Quadlet setup notes).
- seccomp:unconfined
deploy:
resources:
limits:
memory: 1.5G
cpus: "1.0"
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://localhost:445/').then(r=>{process.exit(r.ok?0:1)}).catch(()=>process.exit(1))\""]
interval: 15s
timeout: 5s
retries: 20
start_period: 30s
tty: true # Enable TTY
stdin_open: true # Keep STDIN open

node-exporter:
image: prom/node-exporter:v1.11.1
container_name: node-exporter
ports:
- "9100:9100"
privileged: true
command: ["--path.rootfs=/hostfs"]
restart: always
volumes:
- /:/hostfs:ro,rslave
networks:
- monitoring
profiles:
- monitoring
- serverClientPrometheus

alerts:
image: registry.frafos.net/fril/alerts:10.2
container_name: alerts
restart: always
environment:
REDIS_HOST: "redis"
elasticConfigUrl: "http://elastic:9200/"
cap_add:
- AUDIT_CONTROL
- NET_RAW
- AUDIT_WRITE
ports:
- "80:80"
networks:
- monitoring
depends_on:
elastic:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test:
[
"CMD-SHELL",
"curl -fsS 'http://localhost:80/api/alertapi/help' || exit 1",
]
interval: 15s
timeout: 5s
retries: 20
start_period: 15s

redis:
image: registry.frafos.net/fril/redis-stack-server:latest
container_name: redis
restart: always
expose: ["6379"]
security_opt: ["no-new-privileges:true"]
cap_drop: [MKNOD, NET_RAW, AUDIT_WRITE]
networks:
- monitoring
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 20
start_period: 10s

rq2rest:
image: registry.frafos.net/fril/rq2rest:latest
container_name: rq2rest
command:
[
"-c",
"/etc/rq2rest.ini",
"-d",
"5",
"--redis_url=redis:6379",
"--http_url=http://alerts:80/ingestion/http/00000000-0000-0000-0000-000000000000",
]
restart: always
tty: true
networks:
- monitoring
depends_on:
redis:
condition: service_healthy
alerts:
condition: service_healthy

volumes:
es-data:
es-snapshots:
monitor-data:
ccm-data:

networks:
monitoring:
driver: bridge
enable_ipv6: true
signaling:
driver: bridge
enable_ipv6: true
note

Docker is the recommended way for quick setup and easy updates.


Chrome Service​

The Chrome service provides headless browser capabilities for generating PDF reports in Auto Trigger. It is pre-configured and starts automatically with the stack.

Configuration:

VariableDefaultDescription
BROWSER_URLhttp://chrome:9222/Connection URL for Chrome service
PDF_RENDER_URLhttp://monitor:5000URL Chrome uses to render reports

Update PDF_RENDER_URL if your monitor service uses a different name or port.

Troubleshooting:

# Verify Chrome is running and healthy
docker ps | grep chrome

# View logs
docker logs chrome

If Chrome crashes frequently, increase shared memory:

chrome:
shm_size: '2gb'
tip

shm_size is not required when using zenika/alpine-chrome — the image already uses --disable-dev-shm-usage by default, which bypasses Docker's 64MB shared memory limit.