@@ -22,7 +22,7 @@ The default deployment is a public web backend plus a private HA
2222PostgreSQL service. Every workload CVM must pass attestation admission
2323before it receives Consul and Envoy credentials.
2424
25- ![ Default demo architecture] ( assets/demo-architecture.svg )
25+ ![ Default demo architecture] ( docs/ assets/demo-architecture.svg)
2626
2727Applications use stable names such as ` webdemo ` , ` postgres-master ` , and
2828` postgres-replica ` ; they do not need to know which CVM is currently
@@ -38,7 +38,7 @@ You need:
3838
3939``` bash
4040git clone https://github.com/Dstack-TEE/service-mesh.git
41- cd service-mesh/cluster-example
41+ cd service-mesh/clusters/patroni-demo
4242cp terraform.tfvars.example terraform.tfvars
4343export PHALA_CLOUD_API_KEY=phak_...
4444terraform init -upgrade
@@ -106,7 +106,7 @@ mesh path. The database is private; it exposes `postgres-master` and
106106
107107## Demo Inputs
108108
109- ` cluster-example /terraform.tfvars.example` contains the default demo
109+ ` clusters/patroni-demo /terraform.tfvars.example` contains the default demo
110110values. Edit the copied ` terraform.tfvars ` when you want to change
111111replica counts, cluster name, bootstrap endpoint, or image tags.
112112
@@ -119,6 +119,39 @@ Public gateway URLs are derived from the Phala Terraform provider's
119119` gateway_base_domain ` attribute, so this template does not require a
120120hardcoded gateway suffix.
121121
122+ ## Starter Template
123+
124+ Use ` clusters/starter ` when you want the smallest custom mesh to copy:
125+ one public API workload group and one private worker workload group.
126+ It deliberately has no database and no Patroni role tags.
127+
128+ ``` bash
129+ cd service-mesh/clusters/starter
130+ cp terraform.tfvars.example terraform.tfvars
131+ export PHALA_CLOUD_API_KEY=phak_...
132+ terraform init -upgrade
133+ terraform apply
134+
135+ API=$( terraform output -raw api_url)
136+ curl " $API /hello"
137+ curl " $API /worker"
138+ ```
139+
140+ ` /hello ` returns the API instance identity. ` /worker ` makes the API call
141+ ` http://worker:9090/hello ` through the private mesh.
142+
143+ ## Repository Layout
144+
145+ - ` clusters/patroni-demo ` : full demo cluster, including its Terraform
146+ definition and compose files.
147+ - ` clusters/starter ` : minimal API + worker cluster template.
148+ - ` components ` : reusable platform components built into the sidecar or
149+ support images.
150+ - ` workloads ` : demo workload images used by the Patroni demo.
151+ - ` support ` : helper services that are useful during bootstrap or local
152+ operation but are not a cluster definition.
153+ - ` docs ` : architecture, operations, and design notes.
154+
122155## Default Demo Topology
123156
124157This section describes the shipped demo only: a public web backend plus
@@ -181,15 +214,15 @@ flowchart LR
181214 coord -. admits .-> api2
182215```
183216
184- Declare workload groups, producer backends, and callable routes in
185- ` cluster-example/cluster.tf ` :
217+ The starter cluster in ` clusters/starter/cluster.tf ` is a small version
218+ of this shape :
186219
187220``` hcl
188221locals {
189222 workload_groups = {
190223 api = {
191224 replicas = 2
192- compose = "${path.module}/../ compose/api.yaml"
225+ compose = "${path.module}/compose/api.yaml"
193226 images = { API_IMAGE = var.api_image }
194227 secrets = {}
195228 backends = {
@@ -207,7 +240,7 @@ locals {
207240
208241 worker = {
209242 replicas = 5
210- compose = "${path.module}/../ compose/job- worker.yaml"
243+ compose = "${path.module}/compose/worker.yaml"
211244 images = { WORKER_IMAGE = var.worker_image }
212245 secrets = {}
213246 backends = {
@@ -233,7 +266,7 @@ starts an egress Envoy on every workload CVM so calls work even when the
233266caller does not host the target backend.
234267
235268Run each application container in its own group's compose file beside
236- the existing ` sidecar ` service. For example, ` compose/api.yaml ` would
269+ the existing ` sidecar ` service. For example, ` clusters/starter/ compose/api.yaml` would
237270contain:
238271
239272``` yaml
@@ -251,7 +284,7 @@ services:
251284 condition : service_healthy
252285` ` `
253286
254- ` compose/job- worker.yaml` would have the same sidecar and a `worker`
287+ ` clusters/starter/ compose/worker.yaml` would have the same sidecar and a `worker`
255288service that binds `127.0.0.1:9090`.
256289
257290After deployment, code in either workload group can call :
@@ -274,7 +307,7 @@ For a backend port listed in `workload_groups`, avoid binding `0.0.0.0:<port>`.
274307That also captures the local mesh address for the same port. Bind
275308` 127.0.0.1:<port>` for mesh traffic; if the same service is public
276309through the Phala gateway, also bind the host interface address. The
277- demo [`webdemo`](webdemo/main.go) shows that dual-bind pattern.
310+ demo [`webdemo`](workloads/ webdemo/main.go) shows that dual-bind pattern.
278311
279312# # Service Definition Reference
280313
@@ -335,7 +368,7 @@ identity `spiffe://<cluster>/api`.
335368The shipped backend-plus-database demo uses
336369` registration.owner = "workload"` for Postgres because runtime metadata
337370belongs to Patroni. The sidecar still creates a Connect-aware stub so
338- Envoy can start, but `patroni/entrypoint.sh` updates dynamic metadata
371+ Envoy can start, but `workloads/ patroni/entrypoint.sh` updates dynamic metadata
339372such as role tags and health checks. `postgres-master` and
340373`postgres-replica` are two routes to one Patroni/Postgres backend :
341374
@@ -344,7 +377,7 @@ locals {
344377 workload_groups = {
345378 postgres = {
346379 replicas = var.postgres_replicas
347- compose = "${path.module}/../ compose/postgres.yaml"
380+ compose = "${path.module}/compose/postgres.yaml"
348381 backends = {
349382 postgres = {
350383 port = 5432
@@ -367,7 +400,7 @@ locals {
367400
368401Both routes share `backend = "postgres"` and select the same parent
369402service, `var.cluster_name`. Patroni uses Consul for leader election,
370- and `patroni/entrypoint.sh` runs the role-watcher that publishes the
403+ and `workloads/ patroni/entrypoint.sh` runs the role-watcher that publishes the
371404current `master` or `replica` tag. The Consul resolver for each route
372405selects the matching tag, so clients keep dialing
373406` postgres-master:5432` and `postgres-replica:5432` across failovers.
@@ -416,31 +449,33 @@ design.
416449Validate Terraform :
417450
418451` ` ` bash
419- terraform -chdir=cluster-example init -upgrade
420- terraform -chdir=cluster-example validate
452+ terraform -chdir=clusters/patroni-demo init -upgrade
453+ terraform -chdir=clusters/patroni-demo validate
454+ terraform -chdir=clusters/starter init -upgrade
455+ terraform -chdir=clusters/starter validate
421456` ` `
422457
423458Run local Go tests :
424459
425460` ` ` bash
426- (cd admission-broker && go test ./...)
427- (cd signaling && go test ./...)
428- (cd webdemo && go test ./...)
461+ (cd components/ admission-broker && go test ./...)
462+ (cd components/ signaling && go test ./...)
463+ (cd workloads/ webdemo && go test ./...)
429464` ` `
430465
431466Some modules use Go 1.24. Run them through Docker if your host Go is
432467older :
433468
434469` ` ` bash
435- docker run --rm -v "$PWD:/src" -w /src/admission-client golang:1.24 go test ./...
436- docker run --rm -v "$PWD:/src" -w /src/bootstrap-secrets golang:1.24 go test ./...
437- docker run --rm -v "$PWD:/src" -w /src/mesh-conn golang:1.24 go test ./...
470+ docker run --rm -v "$PWD:/src" -w /src/components/ admission-client golang:1.24 go test ./...
471+ docker run --rm -v "$PWD:/src" -w /src/components/ bootstrap-secrets golang:1.24 go test ./...
472+ docker run --rm -v "$PWD:/src" -w /src/components/ mesh-conn golang:1.24 go test ./...
438473` ` `
439474
440475Build the sidecar image :
441476
442477` ` ` bash
443- docker build -t service-mesh-mesh-sidecar-check -f mesh-sidecar/Dockerfile .
478+ docker build -t service-mesh-mesh-sidecar-check -f components/ mesh-sidecar/Dockerfile .
444479` ` `
445480
446481# # More Docs
0 commit comments