# The cluster SPEC.md F-08 describes, shrunk onto one machine: several Nodes # behind one entry point, all serving the same shared directory and reaching # the same databases. x-node: &node build: . image: workers-rb environment: # A Tenant answers at `.workers.test` as well as at `/`, # so both routing forms can be shown without owning a real domain. WORKERS_BASE_DOMAIN: workers.test # Every Node reads and writes every Tenant's database, which one server # for all three satisfies without anything between them: a write from any # of them is there for the next request wherever it lands. WORKERS_DB_URL: http://databases:8080 WORKERS_DB_ADMIN_URL: http://databases:8081 volumes: # Tenants are published by placing files, so the directory is mounted # rather than baked in: an edit here reaches the next request on every # Node. `rake dev:publish` copies `examples/` in. - ./app:/app:ro depends_on: databases: condition: service_healthy services: # Every Tenant's databases, held where all three Nodes reach them. A Node # names the database it means in the Host header, which is where this reads # it, so one server holds them all without a name per database to resolve. databases: image: ghcr.io/tursodatabase/libsql-server:v0.24.32 command: [ "/bin/sqld", "--enable-namespaces", "--disable-default-namespace" ] environment: SQLD_DB_PATH: /var/lib/sqld SQLD_ADMIN_LISTEN_ADDR: 0.0.0.0:8081 # Left at its default of an hour, the write-ahead log of a database # under load grows for that hour: SQLite finishes a checkpoint only # when no reader is holding the log, and a busy database never offers # that. This is short enough that the quiet between bursts is used. # charts/workers-rb/README.md says how to choose it for traffic that is # not this demo's. SQLD_CHECKPOINT_INTERVAL_S: "30" volumes: - databases:/var/lib/sqld healthcheck: # Asked on the port that serves statements rather than the one that # manages databases, so what it answers for is the path a Tenant uses. # The image carries no HTTP client; bash reaches it on its own. # # This says whether the server is serving, and nothing about any one # database: a Tenant's own can stop answering while this stays green, # which is why the Host gives up on that one itself (SPEC B-34). # # Compose only records the answer — it restarts nothing, whatever # `restart:` says. Acting on it belongs to whatever runs the workload; # under Kubernetes this is the liveness probe and the restart is the # platform's. test: [ "CMD", "bash", "-c", 'exec 3<>/dev/tcp/127.0.0.1/8080; printf "GET /health HTTP/1.0\r\n\r\n" >&3; head -1 <&3 | grep -q 200' ] interval: 5s timeout: 3s start_period: 15s retries: 5 proxy: image: caddy:2-alpine ports: # The cluster's one external address. `WORKERS_PORT` moves it, for a # machine already running something of its own on 9292. - "${WORKERS_PORT:-9292}:80" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro depends_on: node-a: condition: service_healthy node-b: condition: service_healthy node-c: condition: service_healthy # `Env.node` reads the hostname the operating system reports, so each Node is # given one an operator can recognise rather than a container id. node-a: <<: *node hostname: node-a node-b: <<: *node hostname: node-b node-c: <<: *node hostname: node-c volumes: databases: