Skip to main content
uniac.yaml declares an application’s infrastructure in YAML: resources holds reusable service definitions and the deployment declarations that instantiate them, and a workspace combines package directories.

File format

The document is a mapping with these top-level fields: Resource names match ^[a-z0-9]+(?:(?:__?|-+)[a-z0-9]+)*$ and are unique within the file. A deployment declaration’s name is also its service’s name, so it is one DNS label: lowercase letters, digits and dashes, starting and ending with a letter or digit, at most 63 characters. Every resource requires type; unknown fields are rejected at every level.

Workspaces and packages

A workspace owns its containing directory and subtree. Its root resources and each included directory’s uniac.yaml contribute to one local project. A directory containing uniac.yaml is a package; the root’s resources have their own package scope.
Paths are relative to the workspace root and must name directories below it. Missing manifests, duplicate canonical directories, paths escaping the root, globs, and nested workspaces are rejected. Inclusion loads exactly the listed manifests. Root-local resources can accompany workspace directly. A manifest outside any workspace owns a standalone project. Inside a workspace, every manifest below the root is listed in includes. Resource names, from lookups and environment references are local to each package: a reference addresses the services declared in its own package, and the root’s resources form their own package. Different packages may reuse definition names; service names are unique across the project.

Definitions and deployments

type: service and type: singleton create reusable service definitions for stateless and singleton execution. A definition holds the OCI image or Dockerfile build source, environment, startup command, and storage needs. The image platform is linux/amd64. A deployment declaration turns it into a running service. Complete field contracts are in Service and Volume. A type: deployment resource instantiates one definition as a service. The declaration’s name is the service’s name: its identity in the target project and its private hostname. Several declarations can instantiate the same definition, each as its own service. The service’s replicas are the containers running it; deployment versions describes how each deployment applies the count. A definition and a deployment declaration in the same file have different names. Renaming a declaration names a different service, with its own hostname, reference target and volume names; the service deployed under the earlier name, and its data, stay in the project. Deploying a project includes every deployment declaration in its root and included packages. Each resulting service has its own deployment versions. The target project’s identity is supplied separately from this file.

Example composition

This application has an API and a private Redis service with durable storage. It assumes api/Dockerfile builds an application listening on port 8080 that uses CACHE_URL to connect to Redis.
The api declaration instantiates api_definition as the service api, running two replicas; cache instantiates cache_definition as the service cache. Both services are included in the project deployment. The API can reference cache because both declarations belong to this package. The reference names the cache service, which gives its volume the project-scoped name cache.data. The API is publicly exposed; Redis is reachable within the project’s private network. Environment and references explains resolution between services in the same package.

Validation

Local validation checks ownership, included manifests, each file’s schema, resource names, deployment declarations, replica counts, endpoint ports, volume sizes and mount paths, environment variable counts and lengths, and package-local from references. Composition checks all service names, build-source paths on disk, composed volume names, reference visibility, referenced variables, and ungrounded value-reference cycles. Unknown or cross-package service references fail locally. At least one deployment is required to produce a deployable description.

Generated description

The generated description is JSON with kind: deployable and a services array. Each entry contains a service name, normalized source declaration, environment templates, and runtime configuration, including a declared replicas count. The remote project binding lives in .uniac/deploy.json, and environment values remain templates until deployment. Build paths are authored relative to the defining manifest’s directory and normalized relative to the project root in the generated description. Thus build: . in api/uniac.yaml and jobs/uniac.yaml describes distinct sources. The digest identifies that description. Equivalent path spellings, omitted build defaults, YAML formatting, and mapping or exposure-list ordering leave it unchanged. Reordering workspace includes or moving an identical checkout to another absolute path also preserves the digest. A declared replicas count is part of the description; omitting it and null produce the same description. An explicit build target remains part of the description even when it names the Dockerfile’s last stage. The digest excludes source-file and image contents and remotely resolved environment values.