Case study 06
DevOps & Infrastructure

The challenge
- A multi-tenant ERP platform needed separate control-plane, tenant and provisioning roles, running consistently across dev, staging and production.
- Separately, everyday work meant installing, upgrading, separating and backing up several ERP instances on Linux servers and in Docker.
My analysis and approach
- Build once, configure per role and per environment. Keep secrets out of images.
- Make the reverse proxy responsible for the security edge: TLS, rate limits and blocked admin paths.
Technical implementation
- Docker Compose topology from one image:
- A control-plane service.
- Replicated tenant workers running multiple workers each.
- A provisioner with no HTTP.
- PostgreSQL on named volumes.
- A backup sidecar:
pg_dump -Fcplus SHA-256, with 30-day retention. - Entrypoint role switch: sets the db filter, HTTP on or off, and cron threads per role.
odoo.confis rendered from environment variables withenvsubst. - Nginx:
- HTTP→HTTPS 301, HSTS, HTTP/2, and wildcard TLS (Let's Encrypt DNS-01).
limit_reqzones on signup, login and API.- Host-based routing between master and tenants, with websocket upstreams.
- The database manager is blocked, and internal agent paths are restricted to private ranges.
- Server operations:
- A parameterised Linux bootstrap script: system user, PostgreSQL role, Python venv, a systemd unit, an Nginx site checked with
nginx -t, and ufw rules. - systemd restart policies and file limits; worker and memory limits in the Odoo config.
- Certbot webroot issuance for a Dockerised Nginx.
- Separating two client projects on one host: per-project configs, an ops kit with a version-mismatch guard, and db filters.
Verified result
- The platform runs in development, and its configuration is documented per environment.
- Project separation was verified on database copies.
- Not claimed: no uptime, latency or load figures exist in the evidence, so none are stated.
← AI Integration (Python + LLM APIs)Troubleshooting & Performance Engineering →