Self-hosted service
voxpupuli/puppetboard avatar
voxpupuli/puppetboard

Puppetboard gives open source Puppet the reporting console it lost

Web frontend for PuppetDB

737 stars243 forksPythonApache-2.0

At a glance

What is it?
Puppetboard is a Flask web frontend for PuppetDB, built by Voxpupuli to replace the reporting half of the Puppet Enterprise console. It is easy to run in Docker, it leans on pypuppetdb for every query, and its support window for PuppetDB has a documented hole at version 8.1.0.
Who is it for?
Puppetboard is a sound choice for teams running open source Puppet who want the reporting views the Enterprise console used to provide, and the Docker image plus a handful of environment variables make a first run small. It does not suit a PuppetDB deployment stuck on version 8.1.0, since the README points at an upstream bug and asks you to move to 8.1.1 or later, and it does not replace the rest of the Enterprise console.
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 received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

The reporting half of the Enterprise console, without the licence

Puppet has shipped a dashboard for a long time, and the version that came with Puppet Enterprise was never part of the open source distribution. Puppetboard exists to fill that specific gap. Its stated aim is to be a web interface to PuppetDB that replaces the reporting functionality of the Puppet Enterprise console, previously called the Puppet Dashboard, for the open source Puppet. The audience is therefore the system administrator running a fleet of Puppet agents without an Enterprise subscription, who still needs to answer the everyday questions: which nodes reported, which catalog did a node apply, what resources failed on the last run. The project is maintained by Voxpupuli and published on PyPI as a Python package, and the package metadata classifies it as a production stable Flask application aimed at system administrators. It is a read oriented tool. Nothing in the described feature set writes to your infrastructure, which is why it can sit in front of a PuppetDB that also serves the Puppet agents themselves.

A Flask app that talks to PuppetDB through pypuppetdb

The architecture is straightforward and the dependency list shows its edges. The web layer is Flask 3.1, with Werkzeug and Jinja2 underneath it, and forms are handled by Flask-WTF with WTForms. Queries do not go out through raw HTTP calls written by hand: pypuppetdb is the client library, so the request and response handling of the PuppetDB API lives in that package rather than in this repository. In front of the queries sit Flask-Caching and Flask-APScheduler, which means the stack expects cached data and scheduled work, although the README does not document cache keys or refresh intervals and the excerpt does not show how they are configured. Markdown is rendered with commonmark, which matches a report view that shows run output rather than a plain table. The package itself holds two Python packages, puppetboard and puppetboard.views, so the view layer is kept separate from the application wiring, and the repository also ships wsgi.py for deployment behind a WSGI server. Configuration lives in settings.py.sample, and the presence of query_presets.yaml.example next to QUERY_PRESETS.md indicates that the saved query set is a file you control rather than hard coded in the views.

Starting from the official Docker image

The quickest route is the container, published to the GitHub Container Registry and to Dockerhub under the Voxpupuli organisation. The README gives the run command it recommends, on the PuppetDB host itself.

bash
docker run -it \
  -e PUPPETDB_HOST=localhost \
  -e PUPPETDB_PORT=8080 \
  -e SECRET_KEY=XXXXXXXX \
  --net=host \
  ghcr.io/voxpupuli/puppetboard

The README is emphatic about the secret key: you must provide one, and it suggests generating a random value with a short Ruby one liner that calls SecureRandom.hex(32).

The image is also available as a Dockerfile in the repository if you would rather build it yourself.

bash
docker build -t puppetboard .

Inside the image the application is served by gunicorn rather than the development server. The Dockerfile sets the listening port and address, exposes that port and runs the Flask application object under gunicorn with a preload flag and a worker count that defaults to one.

dockerfile
ENV PUPPETBOARD_PORT 80
ENV PUPPETBOARD_HOST 0.0.0.0
EXPOSE 80

That default of a single worker is worth noting before you put the interface in front of a large organisation, since the worker count comes from the PUPPETBOARD_WORKERS environment variable and the container does not change it on its own. The same Dockerfile also defines a health check that queries a status endpoint on the exposed port, so orchestrators can tell whether the container is serving.

The environment variables that decide what the interface shows

Everything about the deployment is driven by environment variables, and the README's Puppet code example lists the useful ones. PUPPETDB_HOST and PUPPETDB_PORT select the PuppetDB to query. ENABLE_CATALOG turns on the catalog view. DEFAULT_ENVIRONMENT is set to * in the example, which is how you widen the view beyond a single environment. The SSL related variables are the ones people usually miss: PUPPETDB_KEY, PUPPETDB_CERT and PUPPETDB_SSL_VERIFY point at certificate files, and the README states plainly that you must use SSL when talking to PuppetDB if you want all features enabled. PUPPETDB_SSL_VERIFY=false appears in the example, which disables certificate verification and is a deliberate trade-off in a lab setup rather than a default to copy into production. PUPPETBOARD_URL_PREFIX serves the app under a path such as /puppetboard when something else already owns the root of your domain. For an isolated network the README suggests adding OFFLINE_MODE=true to the environment list, which makes the app load all content from the local puppetboard web service instead of reaching out. The Puppet example shows the whole set managed as code, which is the most maintainable way to run it.

puppet
docker::run { 'puppetboard':
  image => 'ghcr.io/voxpupuli/puppetboard',
  env   => [
    'PUPPETDB_HOST=127.0.0.1',
    'PUPPETDB_PORT=8080',
    'PUPPETBOARD_PORT=8088',
    'SECRET_KEY=XXXXXXXX',
  ],
  net   => 'host',
}

PuppetDB 8.1.0 is a hole in the support window

The requirements section is unusually specific, and it is where the sharpest edges are. Puppetboard supports PuppetDB versions 5.2 through the 8 series, and the README singles out one exclusion: PuppetDB 8.1.0 is not supported because of a bug tracked in the PuppetDB issue tracker, and the instruction is to update to 8.1.1 or later. If you pin your PuppetDB to 8.1.0 you are outside the tested range, and the documentation offers no workaround, only an upgrade. The other requirement is Python 3.12 through 3.14, or Docker. The package metadata is consistent with that, since the project pins python = "^3.12" and the setup.py declares python_requires of at least 3.12.0. The container sidesteps the interpreter question entirely by running on its own Alpine based Python image, which is the argument for the Docker route in a heterogeneous estate. There is a second, quieter constraint in the same area. The README lists an official Puppet module that installs Puppetboard for you and mentions documentation for RedHat and CentOS 7, which tells you the oldest supported platform is not current, and packaged builds for FreeBSD and OpenBSD exist but sit outside the main path.

How Puppetboard differs from the alternatives around it

Three options sit nearby. The Puppet Enterprise console is the product Puppetboard deliberately imitates; it is commercial, it covers reporting and more, and Puppetboard takes only the reporting slice of it for teams without that subscription. The Puppet module on the Puppet Forge is not a competitor at all but a different layer: it installs Puppetboard onto a node and manages it as code, so choosing between the module and the Docker image is a packaging decision rather than a product decision. The third option is no frontend at all, using pypuppetdb directly from your own scripts. pypuppetdb is a client library and gives you the data with no interface to maintain, which is the right choice for automation and alerting, and the wrong choice for a human asking what happened on a node last Tuesday. Puppetboard sits in between. It adds caching, scheduling and a rendered report view on top of the same library, which is convenient for operators but introduces the extra moving parts of a web application, a session secret and a certificate story that a direct script does not have. Puppetboard also offers an OpenShift template for source to image builds and an air gapped offline mode, neither of which a library call needs.

Apache-2.0 licensing and a release line that moves quickly

Puppetboard is licensed under Apache-2.0, both in the package metadata and in the repository licence file. For an open source operations tool that is about as permissive as it gets: you can run it internally, modify it, and redistribute it without the copyleft obligations that attach to a GPL component, though your own legal review should cover any internal modification policy. The project is not archived and its last push was on 2026-10-19, two days after the newest tag. The release list shows how fast the line moves: v8.1.0 on 2026-10-12, v8.0.0 on 2026-10-09 and v7.0.4 on 2026-10-08, so three releases in five days spanning a major version. That pattern has a consequence for operators. A major version bump inside a single week implies breaking configuration or dependency changes arriving on a short cycle, and the pinned requirements file shows how tightly the runtime is coupled to a specific Flask and Werkzeug generation. Upgrading means reading the CHANGELOG.md file and the RELEASE.md file in the repository rather than pulling the newest image blindly, and the container's default of one gunicorn worker is the first thing to re-check after an upgrade.

Editorial conclusion

Puppetboard is a sound choice for teams running open source Puppet who want the reporting views the Enterprise console used to provide, and the Docker image plus a handful of environment variables make a first run small. It does not suit a PuppetDB deployment stuck on version 8.1.0, since the README points at an upstream bug and asks you to move to 8.1.1 or later, and it does not replace the rest of the Enterprise console. Before you commit, run the image with PUPPETDB_HOST, PUPPETDB_PORT and a generated SECRET_KEY against a copy of your PuppetDB and confirm that the report list loads, then decide whether you need the SSL path with PUPPETDB_KEY and PUPPETDB_CERT before you expose the interface.

Frequently asked questions

Which PuppetDB versions does Puppetboard support?

PuppetDB 5.2 through the 8 series, with one exclusion: version 8.1.0 is not supported because of a bug tracked in the PuppetDB issue tracker, and the README asks you to update to 8.1.1 or later.

How do I run Puppetboard with Docker?

Run the published image with PUPPETDB_HOST, PUPPETDB_PORT and a SECRET_KEY you generate yourself, using --net=host as the README shows. You can also build the image yourself with docker build -t puppetboard . using the Dockerfile in the repository.

Does Puppetboard need SSL to talk to PuppetDB?

For the full feature set, yes. The README states that you must use SSL talking to PuppetDB if you want all features enabled, with PUPPETDB_KEY, PUPPETDB_CERT and PUPPETDB_SSL_VERIFY controlling the certificate settings.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. voxpupuli/puppetboard on GitHub
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/voxpupuli-puppetboard.svg)](https://hysenlabs.com/projects/voxpupuli-puppetboard)

Was this useful?