Skip to content
Talk to our solutions team

Deployment

Audience: DevSecOps — deploy and operate meta.svc, the platform’s git-backed product-definition distribution plane. It distributes a product’s per-block definition to the service blocks (it is not the configuration plane; that’s config.svc). This guide covers how to run and operate it. For what it is, see the what-is-meta design overview; for config keys, see the meta reference.

A single binary (meta.svc), configured with a YAML file (-f) and selected into one of three modes with -m/--mode:

ModeRoleTypical instance
meta (default)serves cluster/forge/tools/config reposplatform bring-up
productserves forge product reposforge-ui + product runtime
marketplaceserves marketplace products + search indexmarketplace

Run one binary per role — do not fork per-mode binaries. Keeping one binary everywhere preserves dev/prod parity.

Meta has two consumer shapes (read-mostly fleet vs. interactive forge-ui authoring). The authoring/write instance is normally a separate deployment from the production read instance — give the read instance read-only repo credentials and scale it independently.

  • File: meta.svc -f /etc/meta/meta.yaml. Generate a starting point with meta.svc config generate <profile> -d /etc/meta/.
  • Secrets: every value supports ${env:VAR} interpolation. Put git tokens and API keys in env (k8s Secrets), never in the file.
  • Meta also participates in the chassis config/discovery boot like every other service; the -f file is the local override.

Repo URLs embed the token: https://x-access-token:${env:GIT_TOKEN}@host/org/repo.git.

  • Tokens expire. With cachetype: fs, meta keeps serving the last-known-good clone and retries pulls in the background — a restart does not fix an expired token, so rotate the secret and let the pull loop recover.
  • providermaxconcurrent caps simultaneous git operations per provider host (prevents hammering GitHub/GitLab on cold start when many repos share a host).
  • Watch intervals are jittered to avoid a thundering herd of simultaneous pulls.
cachetypeBehaviourWhen
memory (default)clones in RAM; full re-clone on restartsmall/dev
fsclones under cachedir/<name>/; survive restarts & token expiryproduction

For fs in Kubernetes: mount a PersistentVolume at cachedir. Optionally use an init container to pre-populate the cache for zero-downtime cold starts. Size RAM for memory mode against the total working-tree size of all served repos.

  • Liveness (/health) flips true once the HTTP server is up.
  • Readiness (/ready) is deferred until repos have actually finished loading (meta sets DeferReadiness), so a load balancer won’t route traffic to an instance whose repos aren’t served yet. Wire /ready to the k8s readinessProbe.
  • Total repo-load failure flips readiness (not liveness); partial failure is logged but stays ready.
  • mTLS / zero-trust: chassis-managed; provide cert material via the standard service-discovery/TLS integration. Meta degrades gracefully when none is set.
  • API key: set api.key to require an X-Api-Key header on every request.
  • JWT: internal callers authenticate with a vault-minted service JWT.
  • Default listen port 8080 (port: in config, or -p for meta.svc serve).
  • The read API lives under /api/v2 (see the Meta API reference).
  • The read plane is stateless w.r.t. clients and scales horizontally — add replicas behind the readiness probe.
  • Each replica independently clones/refreshes repos; budget git bandwidth and set providermaxconcurrent accordingly.
  • The authoring/write instance is low-traffic; run it singly (or few) with write credentials.
  • Stale escalation: with fs cache, meta escalates log severity by how stale its data is relative to stalewarningduration — WARN at 1×, ERROR at 4×, CRITICAL at 12×. Alert on ERROR/CRITICAL: it means pulls have been failing (usually an expired/rotated git token).
  • Metrics and structured logs are emitted via the chassis; scrape as usual.
  • Meta does not expose any endpoint that rewrites the server binary — product packing/unpacking is CLI-only (meta.svc embed). Do not re-add it to HTTP.
  • There is no websocket surface; the API is HTTP (/api/v2) only.
  • Serve repos read-only (readonly: true) on production read instances.
# readinessProbe -> /ready (only green once repos are loaded)
# livenessProbe -> /health
# volumeMounts -> PersistentVolume at cachedir when cachetype: fs
# env -> GIT_TOKEN, META_API_KEY from Secrets, referenced as ${env:...}
# args -> ["-m", "product", "-f", "/etc/meta/meta.yaml"]