Loïc DEMANOU
Français
Cloud & DevOps · Featured

Cleaning

Inventory management application with a full DevOps stack

Inventory management web application for an industrial cleaning company, deployed with a production-grade DevOps stack: Docker containerization, automated GitLab CI/CD, three-pillar observability (logs/metrics/traces), multi-severity alerting and automated load testing.

About

Project: Inventory management platform for the industrial cleaning sector, delivered with a production-grade DevOps stack: three-pillar observability, SRE alerting and load testing.


Stack
LaravelPHP 8.2MySQLDockerDocker ComposeNginxPHP-FPMGitLab CI/CDPrometheusAlertmanagerGrafanaLokiPromtailTempoOpenTelemetrycAdvisormysqld-exporterk6


My contributions
Designed the application architecture
Full Docker containerization (multi-stage PHP-FPM + Nginx, 2 isolated networks, healthchecks)
GitLab CI/CD pipeline: test stage (PHPUnit) + SSH deploy stage restricted to main
Three-pillar observability stack: Loki + Promtail (logs), Prometheus + cAdvisor + mysqld-exporter (metrics), OTel Collector + Tempo (traces)
6 Prometheus alerting rules with tiered Alertmanager routing and per-component inhibition
k6 load tests (smoke / load / stress) with shared SLO thresholds

Context

An industrial cleaning company needed to track all of its equipment going out to and coming back from client sites: equipment, consumables, safety thresholds, inventory discrepancies, and permissions tailored to each job profile. The challenge wasn't only about the application — the solution also had to prove it ran reliably in production, with observable metrics and operational alerting.

Results & metrics

6

Prometheus alerting rules

critical + warning, per component

< 1.5s

SLO p95

verified with k6 up to 200 VUs

13

Stack containers

app + monitoring on 2 isolated networks

Production screenshots

Live Grafana dashboards and the GitLab CI/CD pipeline — click an image to enlarge it.

Key achievements

  • End-to-end Laravel → stdout → Promtail → Loki → Grafana pipeline running in production.
  • Zero-code OpenTelemetry auto-instrumentation for Laravel (traces via the PHP extension).
  • 6 alerts following SRE principles (symptom-based rather than cause-based, with a for: clause to prevent flapping).
  • Slack notifications via webhook, with the secret never committed.

Tech stack

Backend & frontend

  • PHP 8.2 / Laravel 9 (Eloquent, Spatie Permissions)
  • MySQL 8.0 (UUIDs, soft-deletes)

Containerization & runtime

  • Docker / Docker Compose (separate local / prod setups)
  • Custom multi-stage image: PHP-FPM 8.2 + Nginx
  • PHP extensions: APCu, OpenTelemetry, Xdebug, OPcache, GD, MySQLi, BCMath
  • Named volumes for persistence
  • Isolated Docker networks (app / monitoring), with the api service attached to both
  • MySQL healthcheck + ordered dependencies (service_healthy)

CI/CD — GitLab CI

  • Two-stage pipeline (test → deploy), Docker runner
  • Test stage: php:8.2-cli + PHPUnit (on develop and main)
  • Deploy stage: alpine + SSH to the VPS (main only)
  • GitLab production environment linked to the live URL
  • Secrets stored in GitLab CI/CD Variables

Observability — 3 pillars

  • Logs — Loki 3.1 + Promtail 3.1 (Docker SD)
  • Metrics — Prometheus 2.53 + cAdvisor + mysqld-exporter, Laravel /metrics via promphp + APCu
  • Traces — OpenTelemetry Collector 0.102 + Tempo 2.5 (zero-code PHP auto-instrumentation)
  • Visualization — Grafana 10.4 (provisioned datasources and dashboard)

Alerting — Alertmanager 0.27

  • 6 Prometheus rules organized by severity (critical / warning) and component (api / database / infra)
  • Slack webhook injected at runtime via a custom entrypoint

Architecture

Overview — Application + Observability + CI/CD

Overall architecture: from the developer's push to the production VPS, through the GitLab CI pipeline (test → SSH deploy) and the observability chain.

Loading diagram...

CI/CD pipeline — GitLab

Test stage on develop and main, deploy stage on main only through a needs: dependency. Deployment over SSH (key stored as a base64 GitLab variable), then pull + build + up + prune on the VPS.

Loading diagram...