The boring choices, defended
Docker Compose over Kubernetes. 12-Factor as the service baseline. MDXF on every message. Every choice is one we’d stand by in a postmortem. Here’s the reasoning.
Everything below the waterline so your team can stay above it.
Container image hierarchy
Every container starts from the same Debian Linux base. The Microcelium AI image adds common tooling, agent support, controls and monitoring and security hardening. Stemcell images provide language-specific runtimes: Laravel for PHP services, Python for ML and ingestion, Rust for performance-critical services and Java with Spring for enterprise microservices. Application images add service code.
This hierarchy ensures consistency, reduces image sizes and simplifies security patching — update the base, and everything rebuilds.
Docker Compose over Kubernetes
Microcelium uses Docker Compose for container orchestration. This is intentional, not a limitation. When scale demands it, Microcelium deployments can migrate to Kubernetes. The architecture is container-native by design. Docker Compose is the default because it is right for 90% of engagements. Kubernetes is available when it is not.
Operational simplicity
Docker Compose is understandable. Engineers can read the compose files, debug issues and reason about the system without Kubernetes certification.
Cargo Servers run the containers
Each Cargo Server is a micro-machine — a VM whose storage, networking and firewall rules are defined as code, with Docker Engine on top. Containers run here.
micro-glue lands the stacks
Ansible-powered micro-glue renders the target environment's Docker Compose file (services, networks, secrets, Traefik rules) and pushes it to the Cargo Server. Docker brings the stack up; health checks gate the promotion.
No lock-in: the environment running your production stack runs on a developer's laptop too — same services, same networks, same secrets-rendering. At the end of the day it's a docker-compose.yaml file. No custom runtime, no Kubernetes operator, no proprietary orchestrator. Take your compose file somewhere else whenever you want.
Multi-protocol connectivity
The Provider Network is Microcelium's integration backbone. Each provider implements a consistent interface while supporting protocol-specific features.
AMQP
Enterprise messaging via RabbitMQ. Topic exchanges, durable queues, dead letter handling, message acknowledgements. Primary backbone for inter-service communication.
MQTT
Lightweight publish/subscribe for IoT. QoS levels, retained messages, last will and testament. Powers Air/Sylph edge device communication.
REST
HTTP-based API integration. Rate limiting, retry policies, circuit breakers, response caching. Connects to external web services and third-party APIs.
MCP
AI agent integration protocol (Anthropic-originated). Enables Pandora ML models and external AI systems to participate in the agentic fabric.
SSH
Secure shell automation. Remote command execution, file transfer, tunnel management. Service Engine uses SSH for stack access.
SAMBA
SMB file sharing for Windows and legacy system integration. Network storage and shared file access.
Syncthing
Decentralised peer-to-peer file synchronisation. No central server dependency. Encrypted, versioned file distribution.
Email (SMTP/IMAP)
Inbound and outbound email processing. Invoice ingestion, notification delivery, automated correspondence handling.
No lock-in: every protocol above is an open standard backed by an open-source implementation. Native shared-folder access for Windows clients runs over SMB — no per-seat client licensing, no proprietary file-share gateway, no enterprise productivity-suite dependency.
MDXF — one format, three patterns
MDXF — Microcelium Data eXchange Format — is a single standardised JSON envelope for every inter-service message on the bus. Language-agnostic. Optional HMAC-SHA256 signing. Identity travels as a raw JWT when a message acts on behalf of a user.
Async request — with identity
{
"version": "1.0",
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"reply_to": "service-a.incoming",
"timestamp": "2026-01-15T10:30:00+00:00",
"ttl": 60,
"source_service": "service-a",
"type": "request",
"identity": "eyJhbGciOiJSUzI1NiIs...jwt...",
"signature": "a1b2c3...hmac-sha256-hex...",
"payload": { /* service-specific */ }
}
Sender sets reply_to to its own .incoming queue. Consumer processes, then publishes a type: "response" message back with the same correlation_id. The sender uses one queue for both incoming requests and responses, distinguishing by type.
Response — success or error
{
"version": "1.0",
"message_id": "660e8400-e29b-41d4-a716-446655440001",
"correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"timestamp": "2026-01-15T10:30:01+00:00",
"source_service": "service-b",
"type": "response",
"status": "error",
"error": {
"code": "SIGNATURE_INVALID",
"message": "HMAC verification failed"
},
"payload": {}
}
Standard error codes: MESSAGE_EXPIRED, SIGNATURE_MISSING, SIGNATURE_INVALID, INVALID_PAYLOAD, PROCESSING_FAILED, UNSUPPORTED_VERSION. Services may define their own in addition.
Async (default)
reply_to points at the sender's own <service>.incoming queue. Responses arrive on the same queue as new work; matched by correlation_id.
Synchronous RPC
Sender creates an exclusive temporary queue, blocks waiting for the response, tears the queue down when done. Standard AMQP RPC over MDXF.
Fire-and-forget
reply_to omitted. Consumer processes, ACKs, sends no response. For scheduled jobs, batch triggers and notify-only events.
Signing: HMAC-SHA256 over canonical JSON (keys sorted recursively, no whitespace), shared secret via RELAY_HMAC_SECRET. Reference implementations in Python (pika), Node.js (amqplib), and PHP (php-amqplib).
No lock-in: MDXF is an open, MIT-licensed format — JSON over standard AMQP. Spec and reference implementations are public. If you move away from Microcelium, your messages remain standard JSON payloads on a standard message broker — nothing proprietary at the transport layer.
Boring is a feature
The API layer runs on Laravel (PHP). The AI and data processing services run on Python. This is deliberate.
Laravel / PHP — The API Layer
Laravel is one of the most widely deployed web frameworks in the world. Mature, well-documented, with a massive ecosystem. Our API layer (Prism API) handles authentication, RBAC, business logic, and client-facing services. It's the same framework powering the £125M+ litigation-funding platform Axisops operates on Microcelium for 100+ law firms.
We choose technologies for production reliability, hiring pool depth and long-term maintainability — not conference hype cycles.
Python — AI & Data Services
AI/ML workloads run on Python via dedicated microservices. OpenAI SDKs, tokenizers, prompt evaluation, data pipelines — Python's ecosystem is unmatched for this work. Each AI service is containerised and communicates via the message bus, keeping the AI layer swappable without touching the core platform.
12-Factor as the service baseline
12-Factor is our service design checklist — what each containerised microservice looks like on the inside. It's not a modern platform standard by itself. Microcelium fills the gaps: observability, GitOps delivery, identity, container orchestration and supply-chain provenance all come with the platform.
Git-based, single codebase per service
Container-based isolation, explicit declaration
Environment variables at runtime; secrets delivered through a dedicated secret store, never baked into images or committed env files
Attached resources via service discovery
CI/CD pipeline separation, immutable releases
Stateless services, state in backing services
Traefik ingress, isolated Docker networks, port-based routing
Container-based horizontal scaling
Fast startup, graceful shutdown, health checks
Identical environments via micro-glue IaC
Event streams, Loki aggregation, structured logging
Containerised one-off tasks, same environment
What the platform handles, so services don't have to
12-Factor defines the service. Microcelium defines everything around it — observability, delivery, identity, orchestration, supply chain and managed state — so service code stays focused on business logic.
Observability, not just logs
Medusa — Prometheus metrics, Grafana dashboards, Loki log aggregation, Tempo distributed traces. Built in from day one. 12-Factor stops at log streams; Microcelium takes you to metrics, traces, and SLOs.
GitOps delivery
micro-glue renders the target environment's Docker Compose file from Ansible templates; GitLab CI drives the pipeline. Config changes land through merge requests, not SSH sessions.
Identity + access, platform-wide
Authentik SSO + RBAC, with the access model expressed once in Organisation as Code. 12-Factor leaves identity to the app; Microcelium centralises it. Short-lived, platform-issued workload credentials (no long-lived tokens baked into images) are on the roadmap — today services authenticate via Authentik-issued tokens bound to the OaC-defined access model.
Container orchestration
Cargo Servers are the micro-machines that run containers; micro-glue lands docker-compose stacks on them. Container runtime and IaC for the hosts, handled.
Supply-chain provenance
Trivy vulnerability scans gate every image, SBOMs are generated in CI alongside each build, and images are signed with cosign so deployed containers carry verifiable provenance end-to-end. Stemcell image hierarchy adds upstream traceability on top.
Managed state, included
RabbitMQ, MySQL / PostgreSQL, TimescaleDB, Garage, Ceph, Meilisearch — deployed, monitored and backed up by the platform. 12-Factor treats backing services as someone else's problem; we ship them.
From commit to production
Every change follows the same path: GitLab CI runs tests and security scans, Docker builds the image on top of the stemcell, micro-glue generates the target environment's compose file and the stack lands on a Cargo Server (a micro-machine running Docker). Health checks gate every deployment.
Across every stage
Same pipeline, same image, same compose file — across dev, staging and production.
Cargo Servers + micro-glue
Cargo Servers are the runtime hosts — micro-machines configured as code. micro-glue is the IaC tool that targets them with application stacks.
1. Cargo Server provisioning
Ansible carves Substrate (hypervisor, network, NFS) into micro-machines — VM, logical storage, VLAN, firewall rules — and brings each one up with Docker Engine, hardening baseline, monitoring agents, and SSH access in the same known-good state.
2. micro-glue: compose generation
Ansible templates render the target environment's Docker Compose file with service definitions, networks, volumes, secrets, and Traefik ingress (Let's Encrypt SSL).
3. micro-glue: stack deployment
Compose file lands on the target Cargo Server; Docker pulls images and runs the stack.
4. Operational readiness
Health checks gate the rollout; restart policies, log aggregation, and Medusa monitoring come online.
Questions about implementation?
We're happy to discuss the engineering decisions in detail. No pitch — just a technical conversation.