// substrate-first-node.lock — what a machine must be before a mesh exists. // // Steps 0 to 4 of the bootstrap (novox/hq 03-DESIGN/01-to-be/07-the-substrate.md): a container // runtime, a store, a database per context, that context's schema, and the broker. // // It stops before step 5 (a virtual host, a credential, a certificate) and step 6 (the control // plane runs), because nothing consumes them yet. A bundle naming a control plane that serves // nothing would be a bundle whose last step cannot be checked. // // PINNED BY DIGEST, and the digest is not decoration: a tag can be made to point at a different // image, and this file is applied on a machine with no mesh to ask about anything. These digests // belong to the registry the lab raises, which is what a real node pulls from anyway — what is // required is a reference that is exact and cannot move (novox/hq ADR 0006). // // The store's data is a NAMED VOLUME, not a directory on the machine. A directory the host // creates is owned by root, and the database runs as somebody else inside the container — so it // could not write, and the container crash-looped. A named volume lets the image set up its own // ownership, and outlives the container, which is what you want for the thing holding the mesh's // state. { "declaration": 1, "resources": [ { "id": "container-runtime", "type": "package", "package": "docker" }, { "id": "container-runtime-running", "type": "service", "unit": "docker.service", "state": "running", "boot": "enabled" }, { "id": "store", "type": "container", "name": "mesh-store", "image": "192.0.2.250:5000/postgres@sha256:7abf537131b66ed5af448d90653abf1679b0c7e9a1f07efdd4c3108a401b259a", "env": { "POSTGRES_PASSWORD": "bootstrap", "PGDATA": "/var/lib/postgresql/data/pgdata" }, "volumes": ["mesh-store-data:/var/lib/postgresql/data"] }, { "id": "store-ready", "type": "action", "in": "mesh-store", "command": ["sh", "-c", "for i in $(seq 1 60); do pg_isready -U postgres >/dev/null 2>&1 && exit 0; sleep 1; done; exit 1"], "verify": ["pg_isready", "-U", "postgres"] }, { "id": "inventory-database", "type": "action", "in": "mesh-store", "command": ["sh", "-c", "psql -U postgres -c 'CREATE DATABASE inventory'"], "verify": ["sh", "-c", "psql -U postgres -lqt | cut -d'|' -f1 | grep -qw inventory"] }, { "id": "inventory-schema", "type": "action", "command": ["docker", "run", "--rm", "--network", "container:mesh-store", "-e", "MESH_STORE_INVENTORY=postgres://postgres:bootstrap@127.0.0.1:5432/inventory?sslmode=disable", "192.0.2.250:5000/mesh-control@sha256:1c27a43c4431c2b580404e8e1768cd858009e265e80b6f1591eb6de1123fc411", "migrate"], "verify": ["sh", "-c", "docker exec mesh-store psql -U postgres -d inventory -tAc \"select to_regclass('public.node')\" | grep -qx node"] }, { "id": "broker", "type": "container", "name": "mesh-broker", "image": "192.0.2.250:5000/cloudamqp/lavinmq@sha256:b117c254e6e269a29db479e6b410ca4e46e035b4981e49d24b159673ef09d336", "ports": ["5672:5672"], "volumes": ["mesh-broker-data:/var/lib/lavinmq"] }, { "id": "broker-ready", "type": "action", "in": "mesh-broker", "command": ["sh", "-c", "for i in $(seq 1 60); do lavinmqctl status >/dev/null 2>&1 && exit 0; sleep 1; done; exit 1"], "verify": ["lavinmqctl", "status"] } ] }