Microservices Demo¶
Three-service microservice architecture demonstrating internal service discovery, replicas, and custom health checks.
Overview¶
| Tech Stack | Node.js / Express (all services) |
| Services | 3 (gateway + auth-service + data-service) |
| Database | PostgreSQL |
| Pattern | Microservices, internal discovery, replicas |
The appmecca.yaml¶
containers:
- name: gateway
dockerfile: gateway/Dockerfile
context: gateway/
- name: auth-service
dockerfile: auth/Dockerfile
context: auth/
- name: data-service
dockerfile: data/Dockerfile
context: data/
deploy:
- name: gateway
container: gateway
port: 8080
health_check:
path: /health
interval: 15
timeout: 3
healthy_threshold: 3
unhealthy_threshold: 2
environment:
AUTH_URL: "${service:auth-service:internal}"
DATA_URL: "${service:data-service:internal}"
- name: auth-service
container: auth-service
port: 8081
health_check:
path: /health
- name: data-service
container: data-service
port: 8082
replicas: 2
health_check:
path: /health
resources:
memory: "256m"
database:
enabled: true
Key Concepts¶
Service discovery (${service:name})¶
${service:auth-service} resolves at deploy time to that service's public
HTTPS URL, e.g. https://microservices-demo-auth-service.dev.yourdomain.io.
The gateway calls its siblings by name and never hardcodes a host.
Use the plain ${service:X} form
There is also a ${service:X:internal} form that resolves to a private
DNS name on the platform network. It is currently unreliable — the
private record points at the host's private IP paired with a
dynamically-allocated host port, and that port is reassigned when the
callee is redeployed. The URL baked into the caller therefore goes stale
from the callee's second deploy onward and the connection is refused.
Until that is fixed, use the plain ${service:X} form everywhere. It
costs one extra hop through the platform router and is always correct.
Replicas¶
replicas: 2 on data-service runs two container instances on two different
hosts. The platform router load-balances across them and takes an instance
out of rotation when it stops passing its health check.
The maximum is 3 — replicas is validated to the range 1-3.
Custom Health Check Settings¶
The gateway uses custom health check parameters:
interval: 15-- check every 15 secondstimeout: 3-- 3-second timeout per checkhealthy_threshold: 3-- need 3 consecutive successes to be healthyunhealthy_threshold: 2-- 2 failures marks it unhealthy
Threshold minimums
healthy_threshold and unhealthy_threshold both have a minimum of 2.
1 is rejected at validation time. Both cap at 10.
A note on resources¶
resources.memory sets a hard limit on the container and requires a unit
suffix — 256m, 1g. A bare number is interpreted as bytes, and
256mb is not a recognised form.
resources.cpu is accepted by the schema but currently has no effect —
no CPU limit is applied at deploy time. Leave it out.
Step-by-Step Deployment¶
1. Register the app¶
2. Build¶
3. Deploy¶
4. Verify¶
curl https://microservices-demo-gateway.dev.yourdomain.io/health
curl -X POST https://microservices-demo-gateway.dev.yourdomain.io/api/auth/login \
-H 'Content-Type: application/json' -d '{"username": "test"}'
What's Next¶
- Flask + Vue Fullstack -- Simpler multi-container pattern
- Inter-Service Communication -- How service discovery works