Nomad Deployment Guide
Deploying an application to Nomad with pfy: what needs to be installed, how project.yaml aliases point at a deployment, and the day-to-day commands for releasing, planning, rolling back, and running the deploy from CI. The flag reference is on nomad.
Jobs render from a spec
pfy nomad deploy renders the full job from the Manager-stored deployment spec (render → validate → plan → run). The in-place image/tag rewrite is deprecated and runs only behind --legacy-rewrite; see the nomad command reference. For background on the rendering model, start from Generated Artifacts.
Overview
The pfy nomad commands cover:
- Rendering the full Nomad job (ports, health checks, migration prestart, secrets templates, scaling policy) from the deployment spec stored in the Manager
- Validating job configurations before deployment
- Integrating with project version management (the image tag)
- Providing dry-run and plan-only modes for safety
- Applying an application's whole stack, data stores first, with
--stack
Prerequisites
1. Install Nomad CLI
The pfy nomad commands require the Nomad CLI to be installed and accessible:
# macOS
brew install nomad
# Linux: pick a release from https://releases.hashicorp.com/nomad/
NOMAD_VERSION=1.7.0
wget "https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/nomad_${NOMAD_VERSION}_linux_amd64.zip"
unzip "nomad_${NOMAD_VERSION}_linux_amd64.zip"
sudo mv nomad /usr/local/bin/
# Verify installation
nomad version2. Configure Nomad Connection
Set up Nomad connection via environment variables:
export NOMAD_ADDR=http://nomad.example.com:4646
export NOMAD_TOKEN=your-nomad-token # If ACLs are enabled3. Set up the project and environment aliases
# Initialize project configuration
pfy init --name my-project --language go
# Sync from the Manager; seeds one env alias per tenant into project.yaml
pfy sync --project my-project
# Or record/adjust aliases explicitly
pfy env add prod --tenant prod --application my-app --project my-projectThe --env <alias> flag on every deploy/render command resolves through these project.yaml aliases; see env. An alias must carry an application_id for the deploy commands to use it; the aliases pfy sync seeds carry only tenant_id, so add the application with pfy env add (or pfy env link) before deploying, or pass --app <application-id>.
4. (Optional) Configure the rendered artifact path
Add the nomad_file path to your project.yaml; this is where the rendered job is written (and what pfy deploy diff compares against):
ci:
type: github
language: go
registry: ghcr.io
image_name: my-project
nomad_file: nomad/my-app.nomad.hcl # Where the rendered job landsWith this configured, pfy nomad deploy --env prod … writes the rendered job there before applying it; otherwise pass --out <file>.
Basic Deployment Workflow
1. Update Version
First, update your project version:
# Bump patch version (e.g., 1.2.3 -> 1.2.4)
pfy version bump --part patch
# Or set a specific version
pfy version set --version 1.3.0
# Check current version
pfy version show2. Deploy to Nomad
Deploy using the project version as the image tag:
pfy nomad deploy --env prod --use-project-version --yesThis will:
- Resolve the
prodalias to its (application, environment) deployment - Render the full Nomad job from the deployment spec, with the image tag from
project.yaml - Write it to
ci.nomad_file(or--out), validate it, and run it
Without --yes, the deploy runs nomad job plan as a review step before nomad job run.
Advanced Usage
Explicit Tag
pfy nomad deploy --env prod --tag v1.2.3 --yesThe image itself comes from the deployment spec (pfy deployment get --env prod); --tag supplies the release tag appended to it.
Safe Deployment with Planning
Preview changes before deploying:
# Render + validate + plan only
pfy nomad deploy --env prod --tag v1.2.3 --plan-only
# Review the output, then deploy
pfy nomad deploy --env prod --tag v1.2.3 --yesDry Run
Print the rendered job without writing, validating, or deploying:
pfy nomad deploy --env prod --tag v1.2.3 --dry-runSkip Validation
pfy nomad deploy --env prod --tag v1.2.3 --skip-validation --yesDedicated tenants and backend services
# Deploy the tenant-dedicated job instead of the shared one
pfy nomad deploy --env prod --tenant acme --tag v1.2.3 --yes
# Deploy one backend service of the application's stack
pfy nomad deploy --env prod --service api --tag v1.2.3 --yesWhole-stack deploys
Apply managed data stores, backup jobs, and services in dependency order, gating each stage on health:
pfy nomad deploy --stack --env prod --app my-app --project my-saas --tag v1.2.3 --yesSee Stack deploys for the --only-data, --no-wait, --wait-timeout and --install knobs.
Multi-Environment Deployments
One deployment spec exists per (application, environment); the --env alias picks it. There is no per-environment job file to maintain; the render is the artifact.
Development Environment
pfy nomad deploy --env dev --tag dev-latest --yesStaging Environment
pfy nomad deploy --env staging --tag v1.2.3 --yesProduction Environment
# Always use plan-only first in production
pfy nomad deploy --env prod --tag v1.2.3 --plan-only
# Review the plan carefully, then deploy
pfy nomad deploy --env prod --tag v1.2.3 --yesCI/CD Integration
GitHub Actions Example
name: Deploy to Nomad
on:
push:
tags:
- "v*"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install pfy CLI
run: |
PFY_VERSION=$(curl -fsSL https://api.github.com/repos/ProductifyFW/cli/releases/latest | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
curl -fsSLO "https://github.com/ProductifyFW/cli/releases/download/v${PFY_VERSION}/pfy_${PFY_VERSION}_linux_amd64.tar.gz"
curl -fsSLO "https://github.com/ProductifyFW/cli/releases/download/v${PFY_VERSION}/checksums.txt"
grep "pfy_${PFY_VERSION}_linux_amd64.tar.gz" checksums.txt | sha256sum -c -
tar -xzf "pfy_${PFY_VERSION}_linux_amd64.tar.gz" pfy
sudo mv pfy /usr/local/bin/pfy
- name: Deploy to staging
env:
NOMAD_ADDR: ${{ secrets.NOMAD_ADDR }}
NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN }}
PFY_MANAGER_URL: ${{ secrets.PFY_MANAGER_URL }}
PFY_MANAGER_TOKEN: ${{ secrets.PFY_MANAGER_TOKEN }}
run: |
# Extract version from tag
VERSION=${GITHUB_REF#refs/tags/v}
# Deploy to staging
pfy --ci nomad deploy --env staging --tag v$VERSION --yes
- name: Deploy to Production
if: github.event_name == 'release'
env:
NOMAD_ADDR: ${{ secrets.NOMAD_ADDR }}
NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN }}
PFY_MANAGER_URL: ${{ secrets.PFY_MANAGER_URL }}
PFY_MANAGER_TOKEN: ${{ secrets.PFY_MANAGER_TOKEN }}
run: |
VERSION=${GITHUB_REF#refs/tags/v}
pfy --ci nomad deploy --env prod --tag v$VERSION --yesGitLab CI Example
This assumes pfy is installed in the job image (see Configuration for an install snippet) and that the pipeline writes the release version to a .version file in an earlier stage.
deploy:staging:
stage: deploy
script:
- VERSION=$(cat .version)
- pfy --ci nomad deploy --env staging --tag v$VERSION --yes
environment:
name: staging
only:
- main
deploy:production:
stage: deploy
script:
- VERSION=$(cat .version)
- pfy --ci nomad deploy --env prod --tag v$VERSION --plan-only
# Requires manual approval in GitLab; the approved job then runs with --yes
environment:
name: production
only:
- tags
when: manualWorkflow Examples
Complete Release Workflow
# 1. Bump version
pfy version bump --part minor
# 2. Commit version change
git add project.yaml
git commit -m "Bump version to $(pfy version show)"
# 3. Create git tag
git tag v$(pfy version show)
git push && git push --tags
# 4. Deploy to staging
pfy nomad deploy --env staging --use-project-version --yes
# 5. Test staging...
# 6. Deploy to production (with plan)
pfy nomad deploy --env prod --use-project-version --plan-only
# 7. Review plan, then deploy
pfy nomad deploy --env prod --use-project-version --yesHotfix Workflow
# 1. Create hotfix branch
git checkout -b hotfix/critical-fix
# 2. Make fixes and bump patch version
pfy version bump --part patch
# 3. Deploy directly to production with planning
pfy nomad deploy --env prod --use-project-version --plan-only
# 4. After review, deploy
pfy nomad deploy --env prod --use-project-version --yes
# 5. Merge back to main
git checkout main
git merge hotfix/critical-fixRollback Workflow
# 1. Find previous version
git log --oneline project.yaml
# 2. Deploy previous version's image tag
pfy nomad deploy --env prod --tag v1.2.2 --yes
# Or update project.yaml and use project version
pfy version set --version 1.2.2
pfy nomad deploy --env prod --use-project-version --yesRolling back the image tag does not roll back spec changes; inspect those with pfy deployment get --env prod and pfy deploy diff --env prod.
Troubleshooting
Nomad Connection Issues
# Verify Nomad connection
nomad status
# Check environment variables
echo $NOMAD_ADDR
echo $NOMAD_TOKENValidation Failures
# Validate the rendered job file
pfy nomad validate -f nomad/my-app.nomad.hcl
# Or use Nomad directly
nomad job validate nomad/my-app.nomad.hclImage Not Found
Ensure the image exists in your registry:
# Check if image:tag exists
docker pull ghcr.io/acme/myapp:v1.2.3Deployment Failures
# Check Nomad job status
nomad job status my-app
# View allocations
nomad alloc logs <alloc-id>
# Check events
nomad alloc status <alloc-id>Best Practices
1. Always Plan Before Production
# Never deploy to production without planning first
pfy nomad deploy --env prod --tag v1.0.0 --plan-only2. Use Project Version Management
# Keep image tags in sync with project.yaml
pfy nomad deploy --env prod --use-project-version --yes3. Tag Docker Images Properly
# Use semantic versioning for tags
pfy nomad deploy --env prod --tag v1.2.3 --yes
# Avoid using 'latest' in production4. Keep the spec in the Manager, the render in git
The deployment spec (resources, ports, health checks, scaling) lives on the Manager's Deployment entity; edit it with pfy deployment set rather than hand-editing rendered HCL, and commit the rendered artifact so pfy deploy diff can catch drift.
5. Automate in CI/CD
Run the deploy commands from the CI/CD pipeline so every release goes through the same steps.
6. Document Deployments
# Use git tags and commit messages
git tag -a v1.2.3 -m "Release v1.2.3: New features and bug fixes"See Also
- Nomad Commands Reference
- deployment - Deployment-spec scripting
- deploy diff - Drift detection
- Version Management
- CI Commands
- Project Configuration