A lightweight CLI tool that tracks HashiCorp Nomad job configuration changes using Git, providing version history and rollback capabilities.
njgit syncs your Nomad job specifications to Git, creating a version-controlled history of all changes. It detects configuration changes, commits them with detailed messages, and allows you to view history and rollback to previous versions.
Key Features:
- Automatic change detection - Only commits when jobs actually change
- Version history - Track all configuration changes over time
- Easy rollback - Deploy any previous version with one command
- Multi-region support - Organize jobs by region/namespace/name
- Flexible backends - Local Git or GitHub API
- Simple setup - Interactive wizard gets you started in minutes
Download the binary for your platform from releases, or build from source:
git clone https://github.com/wlame/njgit
cd njgit
go build -o njgit ./cmd/njgitnjgit initThis interactive wizard will ask you:
- Backend: Choose
git(local Git repo) orgithub-api(stateless) - Repository path: Where to store job files (for git backend)
- Nomad address: Your Nomad cluster URL
- Jobs to track: Which jobs to monitor
For the git backend, initialize your repository:
cd . # Your configured local_path
git init
git config user.name "Your Name"
git config user.email "you@example.com"
# Optional: Add remote for backup/sharing
git remote add origin git@github.com:yourorg/nomad-jobs.git# Sync your jobs to Git
njgit sync
# View history
njgit history
# Deploy a previous version
njgit deploy <commit-hash> <job-name>Jobs are stored in a hierarchical structure:
<region>/<namespace>/<job-name>.hcl
Example:
global/
default/
web-app.hcl
api-server.hcl
production/
worker.hcl
us-west/
default/
cache.hcl
- Sync:
njgit syncfetches job specs from Nomad, converts them to HCL, and commits changes - History:
njgit historyshows all commits with job changes - Show:
njgit show <commit>displays a specific version - Deploy:
njgit deploy <commit> <job>rolls back to a previous version
Create njgit.toml (or run njgit init):
# Git backend (local-only)
[git]
backend = "git"
local_path = "." # Path to your Git repository
# Nomad cluster
[nomad]
address = "http://localhost:4646"
# token = "" # Or set NOMAD_TOKEN env var
# Jobs to track
[[jobs]]
name = "web-app"
namespace = "default"
region = "global"
[[jobs]]
name = "api-server"
namespace = "production"
region = "us-west"Local-only mode - You manage the repository:
[git]
backend = "git"
local_path = "."Features:
- Local commits only (no automatic push/pull)
- You control remotes and synchronization
- Full Git flexibility
- Works offline
Setup:
git init
git remote add origin <your-repo-url> # Optional
# Use git push/pull manually when you wantStateless mode - No local repository:
[git]
backend = "github-api"
owner = "myorg"
repo = "nomad-jobs"
branch = "main"
author_name = "njgit"
author_email = "bot@example.com"Features:
- No local storage required
- Automatic push to GitHub
- Good for CI/CD environments
- Requires
GITHUB_TOKENenvironment variable
Interactive setup wizard. Creates njgit.toml configuration file.
njgit init
njgit init --force # Overwrite existing configFetches jobs from Nomad, detects changes, and commits to Git.
njgit sync # Sync all configured jobs
njgit sync --dry-run # Preview changes without committing
njgit sync --jobs web-app # Sync specific jobs onlyWhat it does:
- Fetches job spec from Nomad
- Converts to HCL format
- Compares with last committed version
- Commits if changed (with detailed message)
Shows commit history for jobs.
njgit history # Show all commits
njgit history --job web-app # Filter by job
njgit history --namespace production # Filter by namespace
njgit history --region us-west # Filter by region
njgit history --limit 10 # Show last 10 commitsDisplays job configuration from a specific commit.
njgit show abc123 # Interactive file selection
njgit show abc123 --job web-app # Show specific job
njgit show abc123 --job web-app --region global --namespace defaultDeploys a job from a specific commit (rollback feature).
njgit deploy abc123 # Auto-detect job from commit
njgit deploy abc123 web-app # Deploy specific job
njgit deploy abc123 web-app --region us-west --namespace production
njgit deploy abc123 web-app --dry-run # Preview without deployingAuto-detection: If the commit only changed one job, njgit automatically detects which job to deploy.
Manage configuration.
njgit config check # Validate config and test connections
njgit config show # Display current configuration# 1. Set up
njgit init
git init
# 2. Track your jobs
njgit sync
# 3. Make changes in Nomad UI or nomad CLI
nomad job run web-app.nomad
# 4. Sync changes to Git
njgit sync
# Creates commit: "Update global/default/web-app"
# 5. View history
njgit history --job web-app
# Shows all changes to web-app
# 6. Rollback to previous version
njgit deploy abc123 web-app
# Deploys the version from commit abc123# .github/workflows/nomad-backup.yml
name: Backup Nomad Jobs
on:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
jobs:
backup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Sync Nomad jobs
env:
NOMAD_ADDR: ${{ secrets.NOMAD_ADDR }}
NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN }}
run: |
curl -L https://github.com/wlame/njgit/releases/latest/download/njgit-linux-amd64 -o njgit
chmod +x njgit
./njgit sync
git push[[jobs]]
name = "web-app"
namespace = "default"
region = "us-east"
[[jobs]]
name = "web-app"
namespace = "default"
region = "us-west"
[[jobs]]
name = "web-app"
namespace = "default"
region = "eu-central"Files created:
us-east/default/web-app.hcl
us-west/default/web-app.hcl
eu-central/default/web-app.hcl
Set one of these (in priority order):
NOMAD_TOKENenvironment variablenomad.tokenin config file~/.nomad-tokenfile
Required for github-api backend:
export GITHUB_TOKEN="ghp_..."Token needs repo scope for private repositories.
njgit intelligently ignores Nomad-internal fields that change on every deployment:
ModifyIndexModifyTimeJobModifyIndexSubmitTimeCreateIndexStatusStatusDescription
Only real configuration changes trigger commits.
your-repo/
├── global/
│ └── default/
│ ├── web-app.hcl
│ └── api-server.hcl
└── us-west/
└── production/
└── worker.hcl
Each .hcl file contains the complete Nomad job specification in HCL format.
Problem: Git backend can't find your repository.
Solution:
cd <local_path> # Path from your config
git init
git config user.name "Your Name"
git config user.email "you@example.com"Problem: Can't reach Nomad cluster.
Solutions:
- Check
nomad.addressin config - Verify
NOMAD_ADDRenvironment variable - Test:
curl $NOMAD_ADDR/v1/agent/self - Check ACL token if Nomad has ACLs enabled
Problem: No jobs listed in config file.
Solution: Add jobs to njgit.toml:
[[jobs]]
name = "your-job"
namespace = "default"
region = "global"njgit config checkThis validates your config and tests connections to Nomad and Git.
- Go 1.21 or later
- Git
git clone https://github.com/wlame/njgit
cd njgit
go build -o njgit ./cmd/njgit# Linux
GOOS=linux GOARCH=amd64 go build -o njgit-linux ./cmd/njgit
# macOS (Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o njgit-darwin-arm64 ./cmd/njgit
# Windows
GOOS=windows GOARCH=amd64 go build -o njgit.exe ./cmd/njgitOr use the included build script:
./build.sh
# Creates binaries in dist/ directory# Unit tests
go test ./internal/...
# Integration tests (requires Docker)
./run-all-tests.shnjgit/
├── cmd/njgit/ # Main entry point
├── internal/
│ ├── backend/ # Storage backends (Git, GitHub API)
│ ├── commands/ # CLI commands (sync, deploy, history, etc.)
│ ├── config/ # Configuration management
│ ├── git/ # Git operations
│ ├── hcl/ # HCL formatting
│ └── nomad/ # Nomad API client
├── tests/ # Integration tests
├── docs/ # Additional documentation
│ ├── BACKENDS.md # Backend comparison and setup
│ └── CLI_GUIDE.md # Detailed CLI usage
└── README.md # This file
- Backend Configuration Guide - Detailed backend comparison
- CLI Usage Guide - Complete command reference
Contributions welcome! Please open an issue first to discuss proposed changes.
MIT License - see LICENSE file for details
- HashiCorp Nomad - The workload orchestrator this tool supports
- go-git - Pure Go Git implementation used by this project