Operations
Quickstart
Section titled “Quickstart”meta.svc config generate minimal > .meta.yamlmkdir -p myapp/pages && echo "title: Home" > myapp/pages/home.yamlmeta.svc -f .meta.yamlcurl -H "X-Customer: acme" "http://localhost:8080/product/myapp/file/pages/home.yaml"Embedded config profiles: minimal, product-git, fs-cache, multi-customer, marketplace, full — list with meta.svc config list, print with config generate <profile>.
Server configuration (.meta.yaml)
Section titled “Server configuration (.meta.yaml)”name: metaport: "8080"products: acme: # customer - name: myapp # product url: ./myapp type: local - name: storefront url: https://git.example.com/acme/storefront.git type: remote ref: main reftype: branch watchduration: 60s cachetype: fs cachedir: /var/lib/meta/cache allowedversions: - name: main - pattern: "v[0-9]+\\.[0-9]+\\.[0-9]+" access: read: "true" write: "false"Per-repo keys: name, url, type (local|remote), readonly, watchduration, ref, reftype, pinversion, allowedversions (names or regex pattern), cachetype (memory|fs), cachedir, stalewarningduration (default 1h), entitlement, access.read / access.write.
${env:VAR} interpolation keeps git tokens out of the file. Global keys: istenantproductmandatory, defaultallowrepoaccess (default false), tenantproductspath, remoteservices: (federation fallbacks).
Run flags: -f config file, -m/--mode meta|product|marketplace, -A/--apikey, -l/--log.
Config changes trigger a stop-the-world repository refresh.
meta serve — the dev server
Section titled “meta serve — the dev server”A lightweight single-command server for local product development:
meta.svc serve acme:myapp # serves ./myappmeta.svc serve acme:myapp:./somewhere # explicit pathmeta.svc serve -f .meta.yaml acme:myapp # apply the matching config entry's settingsmeta.svc serve # no args: serve the binary's embedded products- A git repo at the path is auto-detected (full branch/tag support); a plain folder is served as-is.
- Flags:
-p/--port(8080),-k/--apikey(empty = no auth),--readonly(default true),--license. - Repo access defaults open in serve mode, and a single-customer serve defaults the
X-Customerheader — zero-friction local loops.
Embedding products
Section titled “Embedding products”Ship products inside the binary for appliance-style installs:
meta.svc embed ./myproduct out.bin --key <key> --entitlement <ent>meta.svc embed-info --license <token> # inspect what's insideEmbedding and unpacking are CLI-only — there is deliberately no HTTP surface for it.
Health and readiness
Section titled “Health and readiness”/health— up with the HTTP server. Liveness never fails for repository problems (a restart cannot fix an expired token)./ready— deferred until repositories load. All service repos failing → 500; partial failure → ready with CRITICAL logs; product-repo failures never flip readiness.
Caching and staleness
Section titled “Caching and staleness”cachetype | Behavior |
|---|---|
memory | Clone in RAM; re-clones on restart. Dev |
fs | Clone at cachedir/<name>/; survives restarts and credential expiry — mount a persistent volume in production |
- Stale escalation relative to
stalewarningduration(default 1h): WARN at 1×, ERROR at 4×, CRITICAL at 12×. - Per-hostname concurrent pull limit (default 3) protects the git provider.
- Git tokens embedded in URLs are watched: warnings at <7 days, <24 hours, and on expiry.
- Health escalates after 3 consecutive pull failures on a repo.
Failure modes
Section titled “Failure modes”| Symptom | Action |
|---|---|
| Repo serving stale content, ERROR/CRITICAL staleness logs | The pull loop is failing — usually an expired git token. Rotate the credential; the pull loop recovers on its own. Restarting does not fix it (and with cachetype: memory a restart loses the last good clone) |
META_READONLY on writes | Repo is readonly (the default in serve mode) |
| “given version is not allowed” | Add the ref to allowedversions |
| 403 with valid auth | Entitlement gate or per-repo access rule |
META_MISSING_CUSTOMER | Send X-Customer or a JWT with the customer claim |