Chainguard Academy is the documentation site for Chainguard products. It exists to help you succeed with Chainguard. Visit it at 🔗 edu.chainguard.dev
You can find the educational resource files in Markdown under the content directory.
This site is based on the Doks Hugo theme.
If you would like to develop this project, clone this repo and install dependencies with npm. We prefer npm ci (clean install) over npm install: it installs the exact dependency tree from package-lock.json, so your local versions match what our build automation and production use.
npm ciTo run a local version of this site, start the development server:
npm run startWhile the server is running, open http://localhost:1313 in your web browser. To stop the server, press Ctrl+C in the terminal.
Any documentation published to Chainguard Academy is reviewed carefully for accuracy. GUI procedures, API commands, and CLI code snippets in a draft are run and tested thoroughly — by both the author and the reviewer — to confirm they work exactly as written. This helps ensure that readers can follow along and get the same results.
We also test drafts by previewing rendered content before it's published. Draft content passes through several checks between your editor and the live site:
- Local preview — Run
npm cionce, thennpm run startto serve the site athttp://localhost:1313with live reload. Use this to confirm pages render correctly, formatting holds up, and internal links resolve. When a doc includes commands or examples, run them to confirm they still work. - Pre-commit checks — A required
pre-commitcheck validates tags, lints, and scans changed files; a git hook stamps content dates; spell-check runs locally. See Pre-commit below for setup. - Deploy previews — Every pull request builds a Netlify deploy preview with a staging URL. Reviewers open this link to see your changes rendered as they'll appear in production.
When you open a pull request, describe how you tested the change so reviewers know what to verify. Recent PRs often list the steps taken, such as previewing pages in the Hugo dev server, confirming links resolve, and running any commands the doc relies on.
If you spot a major change, please file an issue. For a minor change — a typo, or tooling with a newer package available — you're welcome to open a pull request for the team to review.
In each post's header, the date format should follow year-month-day as YYYY-MM-DD.
Reduce an image's file size before adding it to the project to keep page loads fast. You can use a tool such as TinyPNG.
If you use images, bundle them with the Markdown file that references them. Create a directory with the name of the new page. Within the directory, create an index.md file and add the images alongside it.
In practice, this looks like the following, with images bundled inside the mariadb and postgres tutorial directories:
├── chainguard
│ ├── _index.md
│ ├── containers
│ │ ├── _index.md
│ │ ├── getting-started
│ │ │ ├── _index.md
│ │ │ ├── mariadb
│ │ │ │ ├── index.md
│ │ │ │ ├── mdb-demo-success-1.png
│ │ │ │ └── mdb-demo-success-2.png
│ │ │ └── postgres
│ │ │ ├── index.md
│ │ │ ├── pg-demo-success-1.png
│ │ │ └── pg-demo-success-2.pngWithin the Markdown file, add images like so, with the alt text at the front:

Run a local development environment to ensure that your file structure is set up as intended.
Use a shortcode within the Markdown to embed a YouTube video. For example, if you would like to link to the YouTube video located at https://www.youtube.com/watch?v=rqIcDrg1XOs, you can pull the string after v= and use the following shortcode on its own line within Markdown.
{{< youtube rqIcDrg1XOs >}}
Tags are autogenerated when you add the following line to a Markdown file's front matter:
tags: ["Tag1", "Tag2", etc]
This line should appear between the draft line and the images line in the front matter.
For example:
...
draft: false
tags: ["Chainguard Containers", "Overview", "Product"]
images: []
menu:
...
When applying tags, please make sure they conform to the working tag list below so that the tagging logic is consistent. If you'd like to add a new tag or suggest a tag revision, please submit a PR with a justification for the change.
Tags are based on:
- Content topics covered in the content, such as tools (Enforce, apko, etc), orgs/standards (OCI, SLSA, etc), and other relevant topics (SBOMs, etc).
- Content types represented by the content, such as procedural, conceptual, interactive, troubleshooting, etc.
You can review our current list of Tags.
This repository uses the pre-commit framework to check
changes before they merge. The pre-commit check is required on pull
requests and runs only on the files a pull request changes (a pre-existing
backlog is not gated). Run the same checks locally to catch problems before you
push. They cover:
- Secret scanning, private keys, large files, and file hygiene such as trailing whitespace and end-of-file newlines
- GitHub Actions security (
zizmor) and linting (actionlint) - JavaScript (
eslint), Markdown (markdownlint), SCSS (stylelint), and Python (bandit,black) - Content tag validation against the approved taxonomy (advisory: it warns but never blocks a commit)
- Prose spell checking with aspell (advisory and local-only; skipped in CI)
One-time setup:
# 1. Install the pre-commit framework
brew install pre-commit # or: pipx install pre-commit
# 2. Enable the repository's git hook
./setup-hooks.sh
# 3. If you edit SCSS (assets/scss/), install the Node dependencies
npm ci
# 4. Optional: install aspell for local spell checking
brew install aspellsetup-hooks.sh points git at the .githooks/ directory. On each commit, that
hook stamps date and lastmod on changed content files, then runs the
pre-commit framework, so one hook covers everything. You don't need to run
pre-commit install: git ignores .git/hooks once core.hooksPath is set, so a
separately installed hook wouldn't run. To skip the hook for a single commit, use
git commit --no-verify.
The SCSS lint step runs the project's own stylelint, so it needs the Node
dependencies from npm install or npm ci. The other hooks use pre-commit-managed
environments, so they need nothing beyond the framework itself. If you edit
assets/scss/ without installing the dependencies, that one hook fails; content
and other contributors are unaffected.
Resources:
- Complete pre-commit hook guide for contributors — detailed guide with examples
- Tag guidelines — the approved tag taxonomy
- Custom dictionary — technical terms for the spell checker
Every commit in a pull request must be cryptographically signed. This repository uses gitsign for keyless signing, and the Enforce - Commit Signing check verifies each commit. Commits made through the GitHub web interface, such as merges and applied suggestions, are signed by GitHub and pass automatically.
To sign your commits, install and configure gitsign with your Chainguard identity. See Chainguard Guardener commit verification for how the check works, and gitsign for setup.
