uniac CLI connects a local application composition to a remote project.
Its commands prepare descriptions, deploy services, and read live state.
npm install -g @uniac/cli installs the uniac command with Node 18+.
npx -y @uniac/cli … runs the same command without a global installation.
This reference describes release 0.3.24.
Invocation
Local directory options default to the current directory. Flags may appear before or after a command’s positional argument; a surplus argument is a usage error.uniac -h lists commands, and a command’s -h prints its
usage.
--version and -v are aliases for version. Projects are deleted in the
dashboard.
Output describes result formats, progress and exit codes.
Local initialization
init runs offline and writes a prebuilt-image service definition named
<name>-definition and a private deployment declaration <name> that
instantiates it; public_ports on the declaration adds an endpoint. It prompts
for the service name, previews the file and asks for confirmation;
end-of-input accepts the defaults. The default name comes from
the directory name, with app as the fallback. init stops when the
directory already has a uniac.yaml.
npm create @uniac@latest invokes uniac init through the @uniac/create
package. Initialization is local: it writes uniac.yaml and leaves the remote
account unchanged.
Local project ownership
plan, deploy, link, and status resolve the owning local project from
their starting directory. A containing workspace
owns its included packages. Without a workspace, the nearest ancestor
uniac.yaml owns the standalone project. Above that project, only a
uniac.yaml that declares workspace can contain it; discovery reads the
others’ top-level keys alone. Starting from a member or its subdirectory
selects the same project as starting from the root.
All four commands validate manifest structure and workspace membership.
An unlisted manifest below a workspace and a nested workspace are errors.
link and status need only a valid description; deployable workloads,
buildable sources and Docker are requirements of deploy.
Project selection
Deployment addresses an existing remote project.project create <name> creates one on the authenticated account and prints
its name and assigned slug. It is non-interactive, works from any directory,
and changes only the remote account. The name must match
^[a-z][a-z0-9-]{0,62}$. Project creation and linking use the
platform selected by UNIAC_PLATFORM_URL, whose default and credential
selection are described in Authentication.
link resolves the local project first. An exact project slug or a uniquely
matching name selects the project directly. Without an argument, link opens
the project picker, whatever the number of projects, and several matching
names open it too. The command fails when nothing matches, the account has no
projects, or required input stays unanswered.
Linking writes or replaces .uniac/deploy.json at the owning project root:
All workspace packages share the root’s binding; a binding file in a member or
on the path below the root is an error, even when it matches the root binding.
Relinking from any member changes the owner’s binding for subsequent
operations. Each operation captures its destination when it starts, so a
concurrent relink applies to later operations. Relinking changes where later
commands deploy; remote services stay where they are.
deploy, status and the delete commands
select their destination as follows:
- A nonempty
UNIAC_PROJECT_URLnames a project by its gateway URL or slug, in place of the binding, and the platform origin comes fromUNIAC_PLATFORM_URL. The CLI finds that project in the account’s project listing on that platform and uses its name, slug and gateway; a value that names no project on the account fails withnot_linked. - Otherwise the binding supplies the project gateway and platform. A
conflicting explicit
UNIAC_PLATFORM_URLfails before a network call. A binding withoutplatform_urluses the selected default platform; one withoutgateway_urlderives the gateway from its slug. - Without a binding or override,
deployopens the project picker and saves the selected binding;statusand the delete commands report that the project is not linked.
status reads the project that the binding or UNIAC_PROJECT_URL names.
It reads every service in the project, including services missing
from the local description; whole-project status also reads volumes.
Planning and deployment
plan and deploy collect every deployment declaration in the resolved
project’s root and included packages, so they always cover the whole project.
Planning requires at least one deployment declaration, and each service comes
from one declaration.
plan performs description validation offline
and needs neither credentials nor Docker. It composes the complete graph and
checks that its build paths exist; image builds and remote checks happen in
deploy. --full expands the
text preview; --json returns the generated description, as specified in
Output.
deploy repeats this planning before authentication or remote activity.
Single-service and multi-service projects use the same deployment path.
Deployment additionally requires credentials for the target project’s
platform and a reachable local Docker daemon for either image: or build:.
Before Docker or image work, deployment checks the credential with the
platform. It looks up the project’s slug and requires the returned name, slug
and gateway to match the binding, or the project that UNIAC_PROJECT_URL
names in the account-level project listing. A saved binding is optional
because deployment can select an existing project interactively.
For service sources, deployment pulls
prebuilt images using local Docker credentials or builds from the current
working tree. Both target linux/amd64. The build context’s .dockerignore
filters its input. Builds run on every deployment and use Docker’s layer
cache. The resulting
image is pushed to the project registry and registered with the service
description. Sources remain relative to their defining package. Within one
run, services sharing a source and target platform share image work;
different packages’ build: . sources remain distinct.
Missing build directories or Dockerfiles fail during local planning.
Dockerfile syntax, missing build stages, failing build commands, image pulls
and daemon availability are checked during image work. Planning checks the
endpoint, environment variable and volume limits that the
service,
exposure and
storage pages state, and the platform applies those
pages’ constraints when the deployment is submitted.
All service images are checked before the first push. Each run submits a new
deployment version of
every declared service, in reference order: a service whose environment
references another declared service is
registered after that service’s deployment has settled, so the reference
resolves to the version the same run declared. Services with no reference
between them are registered together before the CLI waits for any of them.
Services that reference each other in a cycle are registered together, and
each resolves the others against the versions serving at that moment.
When registration returns a task ID and the initial task read succeeds, the
CLI polls every two seconds until the task
finishes or a five-minute observation deadline passes. Authentication or
access denial fails the command. In other cases, the report shows the accepted
registration without an observed state.
Failure or interruption stops new local work and returns partial results:
when a deployment fails to settle, the services registered after it are not
attempted. Deployments the platform accepted continue, each on its own. An
interrupted or lost registration response leaves acceptance unconfirmed. A
later deploy is a new, independent operation.
After a release attempt, including a partial failure, the CLI writes a local
record of image digests, submission outcomes and receipts under
~/.uniac/store; UNIAC_STORE_DIR selects another directory.
Output describes recording
failures.
Deleting services and volumes
service delete <name> deletes a service of the linked project, with the
effects in Dashboard and removal:
a volume it holds is detached and keeps its data. The command then polls every
two seconds until the service is gone, up to a five-minute deadline; the
deletion continues after the deadline or an interruption.
volume delete <name> deletes a volume and its data. <name> is the volume’s
full name as status lists it, <service>.<volume>. The volume must be
unattached.
In a terminal, both commands show what they delete and ask for its typed
name; any other answer deletes nothing and exits 2. --silent skips the
question and changes nothing else. Without a terminal on standard input,
--silent is required, and the command exits 2 before any network call. Both
commands select the project as status does and use its platform’s
credentials. Output describes their results.
