Production-like monitoring stack deployed via Docker, automated with CI/CD, and integrated into a multi-VM network with NAT routing.
This project implements a centralized monitoring platform with:
- π Metrics β Prometheus
- π Visualization β Grafana
- π Logs β Loki + Promtail
- π¨ Alerts β Alertmanager
- π Reverse proxy β Nginx
- βοΈ Automation β GitHub Actions + Ansible
- π Networking β NAT + nftables + jump host
- TLS termination via Nginx (HTTPS entrypoint)
- Infrastructure as Code (Ansible / Terraform)
- Centralized secrets management
- Automated backup strategy
- Self-hosted CI/CD (GitHub Actions + Runner)
- Docker / Docker Compose
- Prometheus
- Grafana
- Loki + Promtail
- Alertmanager
- Nginx
- Ansible
- GitHub Actions (CI/CD)
- nftables (NAT + firewall)
Internet β Bastion β Nginx β Services
Prometheus β Node Exporters (VMs)
Promtail β Loki
Prometheus β Alertmanager
GitHub β Actions β Runner β SSH β Docker Deploy
monitoring-deploy/
β
βββ docker/
β βββ docker-compose.yml
β βββ nginx/
β β βββ nginx.conf
β βββ prometheus/
β β βββ prometheus.yml
β β βββ alerts.yml
β βββ alertmanager/
β β βββ alertmanager.yml
β βββ promtail/
β β βββ promtail-config.yaml
β βββ loki/
β βββ local-config.yaml
β
βββ ansible/
β βββ inventory.ini
β βββ playbook.yml
β
βββ .github/workflows/
β βββ deploy.yml
β
βββ README.md
git clone https://github.com/YOUR_USERNAME/monitoring-deploy.git
cd monitoring-deploycd docker
docker-compose up -dPush changes:
git add .
git commit -m "deploy update"
git pushGitHub Actions will:
- SSH into monitoring VM
- Pull latest code
- Restart Docker stack
Depending on your setup:
http://<routerVM_IP>:3000 β Grafana
http://<routerVM_IP>:9090 β Prometheus
http://<routerVM_IP>:9093 β Alertmanager
http://<routerVM_IP>/grafana/
http://<routerVM_IP>/prometheus/
http://<routerVM_IP>/alertmanager/
GitHub Actions performs:
- SSH into monitoring VM
- Pull latest repo
- Stop old containers
- Deploy updated stack
bind: address already in use
Cause: Old services (systemd or Docker) still running.
Fix:
docker-compose down
docker rm -f $(docker ps -aq)container name "/grafana" is already in use
Cause: Manual container existed outside docker-compose.
Fix:
docker rm -f grafanaconfig.yaml is a directory
Cause:
Wrong file name (.yml vs .yaml)
Fix: Ensure correct file:
promtail-config.yaml
Everything worked on VM but not from host.
Cause: Broken NAT / firewall rules.
Cause: Interface-specific rule:
iif "enp1s0"
Traffic came from another interface.
Fix: Remove interface restriction:
dnat without iifiptables: No chain DOCKER
Cause: nftables restart wiped Docker rules
Fix:
systemctl restart dockerRequest reached container but response never returned.
Cause: Missing masquerade for external network.
Fix:
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADEdestination path already exists
Fix:
rm -rf ~/monitoring
git clone ...- Docker modifies system networking (iptables/nftables)
- NAT requires both DNAT and SNAT
- Interface-specific rules can silently break routing
- Always verify packet flow with tcpdump
- CI/CD must clean previous state
- HTTPS (Let's Encrypt)
- Reverse proxy routing (single domain)
- Alertmanager β Telegram integration
- Multi-node monitoring
- High availability setup
DevOps / Linux enthusiast focused on automation, infrastructure, and monitoring systems.
