https://github.com/brianmichel/nomad-compass
A simple job reconciler for Nomad
https://github.com/brianmichel/nomad-compass
gitops hashicorp job-scheduler nomad paas reconciliation
Last synced: 25 days ago
JSON representation
A simple job reconciler for Nomad
- Host: GitHub
- URL: https://github.com/brianmichel/nomad-compass
- Owner: brianmichel
- Created: 2025-10-08T03:27:52.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-10-28T02:04:56.000Z (5 months ago)
- Last Synced: 2026-02-27T18:38:36.051Z (27 days ago)
- Topics: gitops, hashicorp, job-scheduler, nomad, paas, reconciliation
- Language: Go
- Homepage:
- Size: 3.88 MB
- Stars: 6
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Nomad Compass
A work in progress gitops reconciler for Nomad.
Nomad Compass is a GitOps reconciler for HashiCorp Nomad. It runs as a single container that hosts a tiny onboarding UI, stores encrypted repository credentials, and continuously syncs Nomad job specifications committed to Git.
## Features
- **Single container** – Vue-powered onboarding UI and Go backend served from the same binary.
- **Secure credential storage** – HTTPS tokens and SSH keys encrypted with a symmetric key supplied via configuration.
- **SQLite persistence** – Lightweight, zero-dependency database managed automatically.
- **Git polling** – Uses `go-git` to clone, fetch, and track `.nomad/*.nomad.hcl` job files.
- **Nomad integration** – Parses HCL jobspecs and registers them via the Nomad API with commit metadata attached.
- **Safe teardown** – Delete repositories or credentials from the UI and optionally purge their Nomad jobs.
- **Extensive metadata** – Jobs are tagged with repository URL, commit SHA, author, and commit title for traceability.
- **Well tested** – Core encryption, storage, reconciliation, and Git plumbing covered by unit tests.
## Screenshots
*Monitored Repositories*

*Monitored Jobs*

## Getting Started
### Tooling with `mise`
This project ships with a `.mise.toml` that pins Go and Node versions. After installing [`mise`](https://mise.jdx.dev/):
```bash
mise install
mise shell
```
### Configuration
Nomad Compass is configured via environment variables:
| Variable | Description | Default |
| --- | --- | --- |
| `COMPASS_HTTP_ADDR` | HTTP listener address | `:8080` |
| `COMPASS_DATABASE_PATH` | Path to SQLite database | `data/nomad-compass.sqlite` |
| `COMPASS_NOMAD_ADDR` | Nomad API address | `http://127.0.0.1:4646` |
| `COMPASS_NOMAD_TOKEN` | Nomad ACL token | _empty_ |
| `COMPASS_NOMAD_REGION` | Nomad region override | _empty_ |
| `COMPASS_NOMAD_NAMESPACE` | Nomad namespace override | _empty_ |
| `COMPASS_REPO_BASE_DIR` | Directory for cloned repositories | `data/repos` |
| `COMPASS_REPO_POLL_SECONDS` | Polling cadence (seconds) | `30` |
| `COMPASS_CREDENTIAL_KEY` | 32-byte encryption key encoded as 64 hex chars | _required_ |
> ⚠️ The encryption key is mandatory. Generate one with `openssl rand -hex 32`.
### Running locally
1. Install backend dependencies and prepare the database:
```bash
go test ./...
```
2. Install frontend dependencies and launch the dev server (optional live reload):
```bash
cd frontend
npm install
npm run dev
```
The Vite proxy forwards `/api` requests to the Go backend on port 8080.
3. Build the production bundle and run the Go binary:
```bash
npm run build # from frontend/
cd ..
go run ./cmd/nomad-compass
```
### Docker image
Build the container:
```bash
docker build -t nomad-compass .
```
Run it:
```bash
docker run \
-e COMPASS_CREDENTIAL_KEY=$(openssl rand -hex 32) \
-e COMPASS_NOMAD_ADDR=http://host.docker.internal:4646 \
-p 8080:8080 \
nomad-compass
```
Run it in Nomad
```bash
nomad run \
-var="nomad_token=token-goes-here" \
-var="credential_key=credential-key-goes-here" \
example/nomad-compass.nomad.hcl
```
Mount `/data` or change `COMPASS_DATABASE_PATH`/`COMPASS_REPO_BASE_DIR` if you prefer persistent volumes.
### Repository onboarding workflow
1. Create credentials in the UI (HTTPS token or SSH key). Values are encrypted before hitting disk.
2. Onboard a repository by providing display name, Git URL, branch, optional credential, and the relative path to your job specs (defaults to `.nomad`).
3. Nomad Compass clones the repo and watches every `*.nomad` and `*.nomad.hcl` file inside that path.
4. When new commits land, Compass registers each job with metadata:
- `nomad-compass/repo-url`
- `nomad-compass/repo-name`
- `nomad-compass/job-file`
- `nomad-compass/commit`
- `nomad-compass/commit-author`
- `nomad-compass/commit-title`
Trigger an immediate reconcile via the UI or `POST /api/repos/{id}/reconcile`.
### Testing
Run the Go test suite:
```bash
go test ./...
```
Vue component tests are not included yet. The backend carries the bulk of logic and has targeted unit coverage.
## Project Layout
```
cmd/nomad-compass # Application entrypoint
frontend/ # Vue + Vite UI
internal/auth # Credential encryption helpers
internal/config # Environment-driven configuration
internal/nomadclient # Thin Nomad API wrapper
internal/reconcile # Reconciliation loop
internal/repo # Git sync and job discovery
internal/server # HTTP API and SPA hosting
internal/storage # SQLite persistence layer
internal/web # Embedded frontend assets
```
## Future Enhancements
- Background webhook receiver to replace polling when SCM supports it.
- Audit log of reconciliation events.
- Pluggable secret backends (Vault, AWS Secrets Manager, etc.).
- Automated e2e pipeline for Docker image smoke testing.