Self-hosted service
goss-org/goss avatar
goss-org/goss

goss: YAML server validation that doubles as a health endpoint

Quick and Easy server testing/validation

5,981 stars499 forksGoApache-2.0

At a glance

What is it?
goss generates a YAML test suite from a running server, replays it with goss validate, and can serve the same checks over HTTP. Here is how it installs, where it breaks down, and how it compares with serverspec.
Who is it for?
Adopt goss when you want a small, single-binary validator that can also answer /healthz, and when you are willing to pin a release tag rather than track latest. Skip it if you need a mature Windows or macOS story, since the README points those platforms at a separate feature-parity page instead of documenting them inline.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem goss solves: proving a server is still configured the way you meant

Configuration management converges a machine to a declared state once. Nothing in that workflow keeps checking afterwards. A package upgrade can replace a config file, a port can stop listening, a service account can lose its shell, and the machine still looks healthy to anything that only checks whether a process is alive. goss targets that gap. It is a YAML based alternative to serverspec for validating a server's configuration, and it is aimed at people who already think in terms of declared state: sysadmins, SREs, and anyone building golden images or container images who wants a post-build assertion step.

The scope is deliberately narrow. goss checks resources of a handful of kinds, including ports, services, users, groups and processes, as the generated example in the README shows. It is not a general purpose test framework and it does not configure anything. It reads state and compares it to a file. If your problem is "did the image build preserve the properties I care about", goss is in scope. If your problem is "is the application returning correct business responses", it is not.

How goss works: autoadd generates the suite, validate replays it

The workflow has two halves. The first is generation. goss autoadd inspects the running system and writes a goss.yaml describing what it found. The README's sshd example shows the shape: a port block with tcp:22 and tcp6:22 entries carrying listening: true and ip lists, a service block with enabled and running, a user block with uid, gid, groups, home and shell, a group block with gid, and a process block with running. Running it as root lets goss also detect ports, according to the README.

The second half is replay. goss validate reads that file and compares each declared property against the live system, then prints a dot per check and a summary line with duration and counts. The generated file is a starting point, not a finished test. The README explicitly suggests editing it to use templates and running with a vars file, which is where the real value sits: one goss.yaml parameterised across hosts instead of one file per machine.

Between the two halves sits the runtime mode that makes goss unusual. The same suite can be served over HTTP. goss serve starts a server, and the README shows curl localhost:8080/healthz returning the result, with --format json for a JSON body and content negotiation through the Accept header for an rspecish response. That means the assertions you wrote for validation become the assertions a load balancer or orchestrator polls. The README links a blog post with Docker and Kubernetes healthcheck, health endpoint and container ordering examples, and the repository ships extras for Kubernetes (kgoss) and Docker Compose (dcgoss) alongside the dgoss wrapper.

Installing goss and running a first validation

The README offers a one-line installer that places goss and dgoss in /usr/local/bin, and warns that curl piped to sh is not recommended for production systems. The same installer accepts GOSS_VER and GOSS_DST to pin a version and change the destination, which is the form you want on a build host.

bash
curl -fsSL https://goss.rocks/install | GOSS_VER=v0.4.10 GOSS_DST=~/bin sh

For CI, the README recommends against downloading latest and instead using a specific release tag, because latest may lead to unexpected behaviour. The manual path downloads the tarball for a pinned version and extracts only the goss binary.

bash
VERSION=v0.4.10
curl -L "https://github.com/goss-org/goss/releases/download/${VERSION}/goss_${VERSION#v}_linux_x86_64.tar.gz" | tar xz -C /usr/local/bin goss
chmod +rx /usr/local/bin/goss

The optional second step fetches the dgoss wrapper from the same release, which is what you use to test containers. If you would rather build from source, the Makefile exposes make build, and the README documents a goreleaser path with --clean, --single-target and --snapshot flags.

With the binary in place, generate a suite against a service you already run. The README uses sshd and notes that root privileges let goss detect ports as well.

bash
sudo goss autoadd sshd

That writes goss.yaml in the working directory. You should see blocks for port, service, user, group and process. Read it before trusting it: autoadd records what is true now, so anything already misconfigured becomes an assertion that the misconfiguration is correct. Then run it.

bash
goss validate

The README's example output shows fifteen checks, a duration around 0.021s and a Count/Failed summary. Two follow-on commands matter in practice. goss --vars vars.yaml validate runs the suite with a variables file once you have templated it, and goss validate --retry-timeout 30s --sleep 1s keeps retrying until the system reaches a valid state or the timeout expires, which is the form you want immediately after a service restart. To expose the same suite over HTTP, goss serve runs in the foreground and curl localhost:8080/healthz returns the result.

Where goss stops being the right tool

The generation step is the sharpest edge. autoadd and add derive tests from current state, so a suite generated on a machine that is already wrong encodes the wrong state as the expected state. Nothing in the README describes a review or diff step for that. You have to treat the generated file as a draft and edit it, which is exactly the manual work goss is advertised as reducing.

The platform story is uneven. The README states plainly that for macOS and Windows you should see a separate platform-feature-parity page, and the install section opens with that pointer. It does not document what differs. If your fleet is mixed, you are reading a second document before you know whether a check you rely on behaves the same way. That is a real gap, not a documentation nit.

Then there is the health endpoint itself. goss serve answers with the result of the same suite you run for validation. A suite that checks a service user's home directory and shell is not a good liveness probe: it will fail on a host that is serving traffic correctly, and an orchestrator that restarts on that signal will restart healthy containers. The README presents serve as a capability and links healthcheck examples, but it does not draw a line between checks that belong in a probe and checks that belong in a build gate. You have to draw it yourself, and the natural default (serve the whole file) is the wrong one.

Finally, goss is a state checker. Anything requiring a request to an application, a database query or a multi-step interaction is out of scope. The repository layout includes matchers and outputs packages, so the comparison logic is extensible in code, but that is a Go contribution, not a YAML feature.

goss versus serverspec, and when the difference matters

The README frames goss as a serverspec alternative, and the difference is not cosmetic. serverspec suites are Ruby: you write code, you get RSpec's matcher library, and running them requires a Ruby toolchain on or near the target. goss suites are YAML, and the runtime is a single self-contained binary the README describes as under 10MB. That changes the deployment question. A goss.yaml plus a binary can be dropped into a container image and executed there; a serverspec suite needs Ruby, the gem set and a runner.

The trade-off runs the other way too. Ruby is a programming language, so serverspec can express loops, conditionals and computed expectations that a YAML file cannot without templates. goss compensates with sprig-based templating and a vars file, which the README points at, but templating is not a substitute for a full language when the logic gets conditional. If your checks are a fixed list of resource assertions, YAML is an advantage. If your checks compute values at runtime, it is a constraint.

The third difference is the health endpoint. serverspec has no equivalent built in. goss ships serve as a first-class subcommand, which is why it appears in the project's topic list next to health-check and health-endpoint. If you already run a dedicated probe endpoint in your application, that advantage shrinks; if you have bare hosts with no application-level health route, it is the reason to pick goss.

Maintenance, releases and what the licence means for packaging

The repository is not archived, and the last push was on 2026-09-14, so it is being worked on. The release cadence is worth reading closely rather than assuming. v0.4.10 landed on 2026-07-26, but the release before it, v0.4.9, dates to 2024-09-26, and v0.4.8 to 2024-07-19. That is a long quiet stretch followed by a fresh release, which is a pattern to plan around: pin a version, and do not assume a fix for something you hit will arrive on a predictable schedule.

The versioning signal is also worth noting. After more than a decade of releases the project is still on 0.4.x. The README's own CI guidance, to avoid latest and use a specific release tag, is consistent with that. Treat upgrades as deliberate events: download the new tarball, run your existing goss.yaml against it, and check whether the output format or check semantics shifted before promoting it across a fleet.

Licensing is Apache-2.0, per the LICENSE file at the repository root. For most users that is unremarkable. If you redistribute goss inside a product or a bundled appliance image, Apache-2.0 carries notice and attribution obligations that differ from MIT, and the repository also contains a Dockerfile_trivy, suggesting a scanner is part of the image pipeline. Whether that affects your distribution is a question for your own counsel; the licence identifier itself is the fact worth carrying into that conversation.

Editorial conclusion

Adopt goss when you want a small, single-binary validator that can also answer /healthz, and when you are willing to pin a release tag rather than track latest. Skip it if you need a mature Windows or macOS story, since the README points those platforms at a separate feature-parity page instead of documenting them inline. Before rolling it out, run goss autoadd sshd on one host, inspect the generated goss.yaml, and confirm the port, service, user, group and process checks match what you actually intend to assert.

Frequently asked questions

What does goss stand for?

The README does not expand the name into words. It presents goss only as the project name, and the repository is goss-org/goss with the homepage at goss.rocks.

What is the full form of Goss?

The documentation gives no full form. The README describes what the tool does, a YAML based serverspec alternative for validating a server's configuration, but never treats goss as an acronym.

How do I install goss on Ubuntu?

The README's installer targets /usr/local/bin and the manual path downloads the linux_x86_64 tarball for a pinned version, extracts the goss binary and marks it executable. The README warns against using curl piped to sh on production systems and recommends a specific release tag in CI rather than latest.

What is dgoss and when do I need it?

dgoss is the Docker wrapper for testing containers, installed alongside goss by the one-line installer or fetched separately from the release assets. The README points to it for container testing, and the repository also ships kgoss and dcgoss wrappers for Kubernetes and Docker Compose.

How do I turn a goss suite into a health endpoint?

Run goss serve, which the README shows answering curl localhost:8080/healthz. Adding --format json returns a JSON body, and the README notes an rspecish response is available through content negotiation on the Accept header.

Official sources

  1. goss-org/goss on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/goss-org-goss.svg)](https://hysenlabs.com/projects/goss-org-goss)