Nomad Deployment Commands
pfy nomad turns the deployment spec stored in the Manager into a Nomad job file and runs it: render writes the job, deploy renders, validates, plans, and runs it, and adopt imports an existing hand-written job into the spec. update-image, validate, and plan are helpers for hand-written HCL files. All of them shell out to the nomad CLI, which must be on your PATH.
Jobs are rendered from a deployment spec
pfy nomad render renders a full Nomad job from the deployment spec on the Manager's Deployment entity, and pfy nomad deploy runs render → nomad job validate → nomad job plan → nomad job run. The in-place image/tag rewrite is deprecated and only runs behind --legacy-rewrite. See Generated Artifacts and deployment.
Overview
The pfy nomad command group provides:
render- Render a full Nomad job from the deployment spec (deterministic,GENERATEDheader, spec hash stamped)adopt- Adopt a hand-written job file into the deployment spec (the migration path)deploy- Render, validate, plan, and run the job, or the application's whole stack with--stackupdate-image/validate/plan- Legacy utilities for hand-written HCL files
Targeting flags
Every spec-consuming command (render, adopt, deploy, and the deployment commands) shares the same target flags to point at one (application, environment) Deployment:
| Flag | Short | Description |
|---|---|---|
--env | -e | Environment alias from project.yaml (resolves to an application + deployment) |
--app | Application ID (overrides project.yaml; needed when the env alias has no application_id) | |
--deployment-id | Target a specific deployment by ID (skips env→deployment resolution) | |
--name | Nomad job/service name (defaults to the deployment's server-derived upstream) | |
--tenant | Tenant slug: target that tenant's dedicated deployment (default: the shared deployment) | |
--service | Service slug within the application (default: the application's primary service) |
Commands
pfy nomad render
Render a full Nomad job from the deployment spec.
Usage:
pfy nomad render --env <alias> [--tag <tag>] [--out <file>]Flags (in addition to the targeting flags):
-t, --tag- Image tag for this release (appended to the spec's image)--use-project-version, --pv- Use the version fromproject.yamlas the image tag--region- Nomad region (default:global)--optimizer-endpoint- Autoscaler optimizer endpoint for theproductify-scalerstrategy--out- Output file (defaults toproject.yamlci.nomad_file;-, or unset with nonomad_file, prints to stdout). There is no-oshort form; a-obefore the subcommand is the global output-format flag
Examples:
# Render prod's job to the committed artifact path from project.yaml
pfy nomad render --env prod --tag v1.2.3
# Render a dedicated tenant's job to stdout
pfy nomad render --env prod --tenant acme --tag v1.2.3 --out -Rendered myapp job to nomad/myapp.nomad.hcl (spec 3f9a2c…)The rendered file carries a GENERATED header with the spec hash and never contains secrets (secrets flow through Nomad template stanzas at runtime).
When the spec has scaling enabled, the rendered scaling block carries a productify-scaler strategy with metric_app_name (the application UUID, which is the app label the proxy stamps on the pfy_* metrics the optimizer forecasts from), group and task (both the job name, which are the labels on the Nomad allocation metrics), min/max, and optimizer_url (--optimizer-endpoint, default http://productify-optimizer.service.consul:8015). The application UUID is read from the Manager's Deployment.applicationId; rendering with scaling enabled fails if it cannot be resolved rather than falling back to the job name, which matches no series.
pfy nomad adopt
Adopt a hand-written Nomad job file into the deployment spec, the migration path off hand-maintained HCL. It reads the job file, extracts everything that maps onto the spec, writes that spec to the Manager (same GraphQL path as pfy deployment set), renders the generated job from it, and prints the residual: every stanza that did not map, with guidance to triage each into extra_hcl or a template feature request. Nothing is silently dropped.
Usage:
pfy nomad adopt <jobfile.hcl> --env <alias> [--dry-run] [-o json|yaml]Flags (in addition to the targeting and render flags above):
--dry-run- Preview the extracted spec, render, and residual without writing to the Manager-o, --output- Machine-readable report format:jsonoryaml(default: human-readable text; note this local-ois the report format, not a file)
Example:
pfy nomad adopt nomad/myapp.nomad.hcl --env prod --dry-runAdopted nomad/myapp.nomad.hcl → application job "myapp"
Mapped onto the deployment spec:
image: ghcr.io/acme/myapp
count: 2
…
note: image tag "v1.2.3" is not part of the spec — supply it at deploy time with --tag (or --use-project-version)
Residual — 1 stanza did NOT map; triage each into the spec's extra_hcl or request a spec field:
…
[DRY RUN] spec NOT written. Re-run without --dry-run to write it to deployment <id>.Notes:
- The image tag and the region are render-time inputs, not spec fields; the adopted values are reported and reused for the render preview.
- The machine-readable report (
-o json) containsjob_name,spec,image_tag,region,residual[](path/reason/guidance/snippet),written, andspec_hash, all stable snake_case keys for CI. - Run with
--dry-runfirst: a real run writes the spec before rendering the preview.
pfy nomad deploy
Render the Nomad job from the deployment spec, then validate, plan, and run it.
Usage:
pfy nomad deploy --env <alias> [--tag <tag>] [flags]Flags (in addition to the targeting/render flags and --project/--project-id for --stack slug resolution):
--out- Write the rendered job here before deploying (defaults toproject.yamlci.nomad_file). No-oshort form--yes- Skip thenomad job planconfirmation step and run immediately--plan-only- Render + validate + plan, but do not run--skip-validation- Skip thenomad job validatestep--dry-run- Render and print without writing, validating, or deploying--stack- Apply the application's whole stack for this environment in dependency order (see below)--legacy-rewrite- Deprecated: run the in-placeimage=rewriter instead of rendering from the spec-f, --file---legacy-rewriteonly: path to the hand-written HCL file to rewrite-i, --image---legacy-rewriteonly: image name to rewrite into the file
Examples:
# Deploy prod with an explicit tag
pfy nomad deploy --env prod --tag v1.2.3 --yes
# Deploy using the version from project.yaml
pfy nomad deploy --env prod --use-project-version --yes
# Plan only — review before deploying
pfy nomad deploy --env prod --tag v1.2.3 --plan-only
# Preview the rendered job without touching anything
pfy nomad deploy --env prod --tag v1.2.3 --dry-runWorkflow:
- Resolves the target deployment and renders the full job from its spec
- Writes it to
--out/ci.nomad_file(the committed artifact) - Validates the job file (unless
--skip-validation) - Runs
nomad job planas a review step (skipped with--yes;--plan-onlystops here and prints thepfy nomad deploy --env <alias> --yescommand to run next) - Runs
nomad job run
Rendered myapp job to nomad/myapp.nomad.hcl (spec 3f9a2c…)
Deploying spec 9c1d0e… → 3f9a2c…
✓ Rendered job is valid
Running 'nomad job run nomad/myapp.nomad.hcl'...
✓ Job deployed successfullyThe Deploying spec line compares the spec hash stamped on the running job with the new one (Re-deploying spec … when they match; a bare Deploying spec … when the job is not running yet).
Stack deploys (--stack)
--stack applies the whole application stack for one (application, environment[, tenant]) in dependency order: managed data stores first (seeding any missing store credential on the way), then their backup jobs, then the services that consume them, waiting for each stage to become healthy before starting the next.
Stack-only flags:
--out-dir- Directory the rendered stack jobs are written to (default:deploy/)--only-data- Apply just the managed data stores and their backup jobs--no-wait- Do not gate stages on health (faster when stores are already up; a service can start before its database accepts connections)--wait-timeout- How long each stage has to become healthy (default:5m)--install- Path toinstall.yaml, which defines the namedbackup_targetsa store's backup policy resolves against (default:install.yaml)--service <slug>- Narrow the apply to one service's job (--only-datatogether with--serviceselects nothing and is refused)
# Apply the full stack for prod: postgres first, then the services
pfy nomad deploy --stack --env prod --app myapp --project my-saas --tag v1.2.3 --yes
# Only the data stores
pfy nomad deploy --stack --env prod --app myapp --project my-saas --only-data --yesUnder --stack, --app accepts a slug (resolved via --project) or an ID. Each stage prints what it rendered and ran:
Generated a credential for main at <nomad variable path>
Rendered myapp--main (data store) to deploy/myapp--main.nomad.hcl
Running 'nomad job run deploy/myapp--main.nomad.hcl'...
Waiting for myapp--main (data store) to become healthy...
✓ myapp--main is healthy
Rendered myapp (service, with prestart migration) to deploy/myapp.nomad.hcl
Running 'nomad job run deploy/myapp.nomad.hcl'...
✓ Stack applied (3 jobs)Legacy rewrite (--legacy-rewrite)
The in-place image= rewriter is deprecated and runs only behind --legacy-rewrite. Every use prints a WARNING: --legacy-rewrite is DEPRECATED ... line on stderr:
pfy nomad deploy --legacy-rewrite -f manager/nomad/manager.nomad --tag v1.2.3Without --legacy-rewrite, pfy nomad deploy -f <file> --tag <tag> goes through the spec-render flow and ignores -f. Use pfy nomad render/deploy, or pfy nomad adopt to import the hand-written file into the spec once and render from then on.
pfy nomad update-image
Update only the image/tag in a hand-written Nomad HCL file without deploying (legacy image= rewriter).
Usage:
pfy nomad update-image -f <file> [options]Flags:
-f, --file(required) - Path to the Nomad HCL file-i, --image- Docker image name-t, --tag- Docker image tag/version--use-project-version, --pv- Use version fromproject.yamlas the image tag
Examples:
Update only the tag:
pfy nomad update-image -f manager/nomad/manager.nomad --tag v1.2.3Update using project version:
pfy nomad update-image -f manager/nomad/manager.nomad --use-project-versionInterpolated image references are skipped
An image line built from a variable, such as image = "${IMAGE_NAME}:${TAG}", cannot be rewritten without destroying the interpolation, so update-image (and the legacy deploy --legacy-rewrite) leave it byte-for-byte untouched and report it:
Skipped job.nomad:5: image = "${IMAGE_NAME}:${TAG}" interpolates a variable; left unchanged
rewriting it would destroy the interpolation; set the tag through the job's variable instead (nomad job run -var ...) or use a job file with a literal imageSet the tag through the job's own variable (nomad job run -var ...) instead, or use a job file with a literal image reference. Other image lines in the same file are still updated normally, and --dry-run (on deploy --legacy-rewrite) reports the same skip as [DRY RUN] Would skip ....
Registry ports are preserved: the tag is split on the last colon only when it follows the last slash, so localhost:5000/acme/app:1.0.0 updates to localhost:5000/acme/app:2.0.0.
pfy nomad validate
Validate a Nomad HCL job file.
Usage:
pfy nomad validate -f <file>Flags:
-f, --file(required) - Path to the Nomad HCL file
Example:
pfy nomad validate -f manager/nomad/manager.nomadThis runs nomad job validate to check the job file syntax and configuration.
pfy nomad plan
Run nomad job plan on a HCL file to preview changes.
Usage:
pfy nomad plan -f <file>Flags:
-f, --file(required) - Path to the Nomad HCL file
Example:
pfy nomad plan -f manager/nomad/manager.nomadThis shows what changes would be made to the Nomad cluster without actually applying them.
Integration with Version Management
The Nomad commands take the image tag from the project version:
# Bump version in project.yaml
pfy version bump --part minor
# Deploy using the new version as the image tag
pfy nomad deploy --env prod --use-project-version --yesThe project version and the deployed container tag then stay in step.
Common Workflows
Simple Deployment
# Update version
pfy version set --version 1.2.3
# Deploy to Nomad from the spec
pfy nomad deploy --env prod --use-project-version --yesSafe Deployment with Planning
# Render, validate, and plan; review before deploying
pfy nomad deploy --env prod --tag v1.2.3 --plan-only
# Review the plan output, then deploy
pfy nomad deploy --env prod --tag v1.2.3 --yesMulti-Environment Deployment
With one project.yaml env alias per environment (seeded by pfy sync, managed by pfy env):
# Development
pfy nomad deploy --env dev --tag dev-latest --yes
# Staging
pfy nomad deploy --env staging --tag v1.2.3 --yes
# Production: plan first
pfy nomad deploy --env prod --tag v1.2.3 --plan-only
# Review plan, then:
pfy nomad deploy --env prod --tag v1.2.3 --yesMigrating a hand-written job file
# 1. Preview what maps and what doesn't
pfy nomad adopt nomad/myapp.nomad.hcl --env prod --dry-run
# 2. Write the spec to the Manager
pfy nomad adopt nomad/myapp.nomad.hcl --env prod
# 3. From now on, render and deploy from the spec
pfy nomad deploy --env prod --tag v1.2.3 --yesPrerequisites
- The
nomadCLI on yourPATH(renderalone does not need it;validate,plan,deploy,adopt's preview, anddeploy diff's cluster check do) NOMAD_ADDR(andNOMAD_TOKENif ACLs are on) pointing at the cluster- A Nomad token allowed to plan and run jobs in the target namespace
- Manager credentials (
pfy login); the spec is read from the Manager
See Also
- deployment - Read and write the deployment spec
- deploy diff - Drift detection
- env - Environment aliases the
--envflag resolves through - Version Management
- CI Commands
- Project Configuration