Goliash — what runs where, on which version: a service × environment matrix with upstream releases and drift. Deployed as a single host-networked Nomad service with a data volume; it watches the Nomad cluster it runs on out of the box (read-only) and can add Kubernetes, ECS, Docker and Compose targets.
Needs nomad-pack on PATH. The script only adds the nomploy registry and runs this pack.
Source ↗ Project ↗ ★ 1 ⚑ Report an issue
Save as values.hcl, edit, then run:
# The name of the Nomad job.
job_name = "goliash"
# The Nomad namespace to deploy into.
namespace = "default"
# The datacenters to deploy to.
datacenters = ["*"]
# The Goliash server image. Pin a tag in production.
image = "ghcr.io/pipozzz/goliash:0.3.0"
# Host port for the web UI, API and agent endpoint.
port = 8070
# The address people use, e.g. https://goliash.example.com. Sign-in links and cookies depend on it. Empty = http://<node-ip>:<port>.
public_url = ""
# E-mail of the first owner. Until they sign in, every start logs a one-time sign-in link in the task logs.
owner_email = "admin@example.com"
# Environment the Nomad cluster belongs to in Goliash (e.g. prod or staging).
environment = "prod"
# Watch the Nomad cluster this job runs on (read-only), without an agent.
watch_nomad = true
# Nomad API address for watching the cluster. Empty = http://<node-ip>:4646.
nomad_address = ""
# Nomad ACL token with the read-job capability, when ACLs are enabled. Empty = no token.
nomad_token = ""
# Key that encrypts notification channel secrets (openssl rand -base64 32). Empty = generated on the data volume on first start.
secret_key = ""
# GitHub token for release notes lookups (raises GitHub's rate limit). Optional.
github_token = ""
# Named volume for the SQLite database and the secret key (/data).
data_volume = "goliash_data"
# Constraints to pin the job to the node holding the data volume.
constraints = []
# Task resources.
resources = {
cpu = 200
memory = 256
}
| Name | Type | Default | Description |
|---|---|---|---|
| job_name | string | "goliash" | The name of the Nomad job. |
| namespace | string | "default" | The Nomad namespace to deploy into. |
| datacenters | list | ["*"] | The datacenters to deploy to. |
| image | string | "ghcr.io/pipozzz/goliash:0.3.0" | The Goliash server image. Pin a tag in production. |
| port | number | 8070 | Host port for the web UI, API and agent endpoint. |
| public_url | string | "" | The address people use, e.g. https://goliash.example.com. Sign-in links and cookies depend on it. Empty = http://<node-ip>:<port>. |
| owner_email set me | string | "admin@example.com" | E-mail of the first owner. Until they sign in, every start logs a one-time sign-in link in the task logs. |
| environment | string | "prod" | Environment the Nomad cluster belongs to in Goliash (e.g. prod or staging). |
| watch_nomad | bool | true | Watch the Nomad cluster this job runs on (read-only), without an agent. |
| nomad_address | string | "" | Nomad API address for watching the cluster. Empty = http://<node-ip>:4646. |
| nomad_token key | string | "" | Nomad ACL token with the read-job capability, when ACLs are enabled. Empty = no token. |
| secret_key key | string | "" | Key that encrypts notification channel secrets (openssl rand -base64 32). Empty = generated on the data volume on first start. |
| github_token key | string | "" | GitHub token for release notes lookups (raises GitHub's rate limit). Optional. |
| data_volume | string | "goliash_data" | Named volume for the SQLite database and the secret key (/data). |
| constraints | list | [] | Constraints to pin the job to the node holding the data volume. |
| resources | object | {
cpu = 200
memory = 256
} | Task resources. |
No variables match.
This pack stores data in one Docker named volume:
goliash_data
restic
# Run on the node hosting this pack. Point restic at your repo first: # export RESTIC_REPOSITORY="s3:https://<account>.r2.cloudflarestorage.com/<bucket>" # export RESTIC_PASSWORD="<repo-password>" # export AWS_ACCESS_KEY_ID=<key> AWS_SECRET_ACCESS_KEY=<secret> restic backup \ /var/lib/docker/volumes/goliash_data/_data
rclone (sync to S3/R2)
rclone sync /var/lib/docker/volumes/goliash_data/_data backup:<bucket>/goliash_data
Paths assume the default Docker volume location (/var/lib/docker/volumes). Restore by stopping the job, restoring files into the same volume, and re-running the pack.
Goliash shows what runs where, on which version: a service × environment matrix with the running and the newest upstream version, history of every deploy, and drift between environments.
Single host-networked Nomad service with a data volume. Out of the box it watches the Nomad cluster it runs on (read-only), so the matrix fills without an agent. Kubernetes, ECS, Docker hosts and Compose files can be added in the UI.
nomad-pack registry add nomploy https://github.com/Nomploy/nomad-packs
nomad-pack run goliash --registry=nomploy \
--var owner_email=you@example.com --var public_url=https://goliash.example.com
Then open the task logs: the first start logs a one-time sign-in link for owner_email.
| Variable | Default | Description |
|---|---|---|
port |
8070 |
UI, API and agent endpoint. |
public_url |
"" |
Address people use. Empty = http://<node-ip>:<port>. |
owner_email |
admin@example.com |
First owner; a sign-in link is logged until they sign in. |
environment |
prod |
Environment the Nomad cluster belongs to. |
watch_nomad |
true |
Watch this Nomad cluster without an agent. |
nomad_address |
"" |
Nomad API. Empty = http://<node-ip>:4646. |
nomad_token |
"" |
ACL token with read-job, when ACLs are on. |
secret_key |
"" |
Encrypts channel secrets. Empty = generated on the volume. |
github_token |
"" |
Optional, for release notes lookups. |
data_volume |
goliash_data |
/data — SQLite database and secret key. |
image |
ghcr.io/pipozzz/goliash:0.3.0 |
Image. Pin a tag in production. |
resources |
{ cpu = 200, memory = 256 } |
Task resources. |
count = 1; pin the job with constraints. For more,
point GOLIASH_DATABASE_URL at PostgreSQL (see the docs).nomad_token:
nomad acl policy apply goliash-read - <<<'namespace "*" { capabilities = ["read-job"] }' then
nomad acl token create -name goliash -policy goliash-read.goliash.service to a job's meta to name its service; everything else waits in the Inbox.goliash.key, which channel secrets need.