Skip to content

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 seconds
  • timeout: 3 -- 3-second timeout per check
  • healthy_threshold: 3 -- need 3 consecutive successes to be healthy
  • unhealthy_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

mecca register git@gitlab.com:appmecca-sample-apps/microservices-demo.git \
  -e dev

2. Build

mecca build trigger \
  -e dev \
  -g git@gitlab.com:appmecca-sample-apps/microservices-demo.git

3. Deploy

mecca app deploy -e dev microservices-demo

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