One container per role -- engine, worker, ui, notifier, sink --
sharing one log server, all in one stack. This is the shape Choose your
deployment points at for Docker Compose split by role.
Topologies, section 2.2, is the mechanism.
1. Prerequisites
Docker with the compose plugin (docker compose version).
2. Install
Nothing to install beyond Docker; the stack pulls the jaque image on
first up. See Docker for what the image is built on
and how every flag maps to a JAQUE_<FLAG> environment variable.
3. The log server
The log service in the stack below is the shared log server every
role points -eventlog, -coordination and -queue at. There is
nothing to run separately; docker compose up brings it up with the
rest.
4. The files
The canonical copy of both files below is
deploy/compose/distributed/docker-compose.yml and
deploy/compose/distributed/jaque.cue in the repository. Every role but
worker mounts jaque.cue read-only; engine runs
-notify-delivery external because notifier is also running.
# deploy/compose/distributed/docker-compose.yml
services:
log:
image: nats:2.10-alpine
command: ["-js", "-sd", "/data"]
volumes:
- jaque-log-data:/data
engine:
image: ${JAQUE_IMAGE:-jaque:latest}
environment:
JAQUE_TARGET: engine
JAQUE_CONFIG: /etc/jaque/config.cue
JAQUE_LISTEN: 0.0.0.0:8080
JAQUE_EVENTLOG: nats://log:4222
JAQUE_COORDINATION: nats://log:4222
JAQUE_QUEUE: nats://log:4222
JAQUE_NOTIFY_DELIVERY: external
volumes:
- ./jaque.cue:/etc/jaque/config.cue:ro
depends_on:
- log
restart: unless-stopped
worker:
image: ${JAQUE_IMAGE:-jaque:latest}
environment:
JAQUE_TARGET: worker
JAQUE_LISTEN: 0.0.0.0:8080
JAQUE_QUEUE: nats://log:4222
JAQUE_ZONES: default
depends_on:
- log
restart: unless-stopped
ui:
image: ${JAQUE_IMAGE:-jaque:latest}
environment:
JAQUE_TARGET: ui
JAQUE_CONFIG: /etc/jaque/config.cue
JAQUE_LISTEN: 0.0.0.0:8080
JAQUE_EVENTLOG: nats://log:4222
JAQUE_COORDINATION: nats://log:4222
volumes:
- ./jaque.cue:/etc/jaque/config.cue:ro
ports:
- "8080:8080"
depends_on:
- log
restart: unless-stopped
notifier:
image: ${JAQUE_IMAGE:-jaque:latest}
environment:
JAQUE_TARGET: notifier
JAQUE_CONFIG: /etc/jaque/config.cue
JAQUE_LISTEN: 0.0.0.0:8080
JAQUE_EVENTLOG: nats://log:4222
JAQUE_COORDINATION: nats://log:4222
volumes:
- ./jaque.cue:/etc/jaque/config.cue:ro
depends_on:
- log
restart: unless-stopped
sink:
image: ${JAQUE_IMAGE:-jaque:latest}
environment:
JAQUE_TARGET: sink
JAQUE_CONFIG: /etc/jaque/config.cue
JAQUE_LISTEN: 0.0.0.0:8080
JAQUE_EVENTLOG: nats://log:4222
JAQUE_COORDINATION: nats://log:4222
volumes:
- ./jaque.cue:/etc/jaque/config.cue:ro
depends_on:
- log
restart: unless-stopped
volumes:
jaque-log-data: {}
// deploy/compose/distributed/jaque.cue
hosts: {
self: {
address: "127.0.0.1"
check: {type: "icmp", host: "127.0.0.1"}
}
}
Only ui publishes a port; every other role is reached over the compose
network by the other services, the same way a Prometheus scrape config
would reach them.
5. Start
cd deploy/compose/distributed
docker compose up -d
6. Verify
docker compose exec ui /jaque version
curl http://localhost:8080/status.json
The dashboard is at http://localhost:8080/. jaque_membership_size is
0 on ui -- it never joins engine membership -- so it has to be read
from engine instead, which has no published port. Point your metrics
stack at engine:8080/metrics on the compose network, the same way it
would reach it in production; with one engine replica the value is
1.
7. Add a worker zone
Add a second worker service (or scale the existing one with docker compose up -d --scale worker=2) and set JAQUE_ZONES to the zone name
your hosts in jaque.cue carry; a check only runs on a worker serving
its object's zone. See Topologies, section 3.
8. Where things live
Config is the mounted jaque.cue, read-only, on every role but
worker. State is the jaque-log-data volume, owned by the log
service; no other role keeps local state. Logs go to docker compose logs <service>.
9. Upgrade
docker compose pull
docker compose up -d
Set JAQUE_IMAGE to pin a specific tag instead of latest. The event
log on log's volume survives the upgrade.
10. Next steps
CUE in practice adds services and
contacts to jaque.cue.
Contacts and policies
wires a hard state to a person, delivered by the notifier role.
Cluster and coordination is what
adding a second engine service buys.
11. Security considerations
Only ui's port is published; every other role stays on the compose
network. Cluster and coordination,
section 7, states what access to the log server's subjects amounts to
-- treat that network the same as the dashboard's.