Inspect your Argo CD fleet without getting wet
drydock is a fast, single static Go binary and embeddable library for
runtime-offline Argo CD desired-state analysis. It discovers, renders, tests,
diffs, and diagnoses GitOps Applications without requiring a live Argo CD
instance or Kubernetes cluster.
It is built for operators who want quick, deterministic feedback before a change reaches the cluster. Pull request diffing is a key workflow, but the same native engine also supports render validation, image inventory, repository diagnostics, cache inspection, and Go API embedding.
Default commands use native Go renderers and do not shell out to kubectl,
argocd, Helm CLI, Kustomize CLI, or repo-server wrappers. Runtime-offline
does not mean network-disconnected: declared Git, HTTP Helm, OCI Helm, and
remote Kustomize sources may still be fetched into explicit drydock caches
unless --offline is set.
Full documentation: sholdee.github.io/drydock.
The PR action posts a markdown summary and links a standalone Full Rendered Diff View so Argo CD/GitOps reviewers can inspect rendered Kubernetes resources before merge.
Open an example Full Rendered Diff View
Install the latest Linux/macOS release with Homebrew:
brew install sholdee/tap/drydockHomebrew installs shell completions automatically.
For GitOps repository and CI pinning, use mise with the GitHub backend:
[tools]
"github:sholdee/drydock[exe=drydock]" = "vX.Y.Z"Install Script
curl -fsSL https://raw.githubusercontent.com/sholdee/drydock/main/scripts/install-drydock.sh -o install-drydock.sh
bash install-drydock.sh --yesThe script verifies release checksums, verifies Sigstore bundles when
available, installs the drydock binary, and attempts shell completion
installation. Pin a release with --version vX.Y.Z.
Pipe form:
curl -fsSL https://raw.githubusercontent.com/sholdee/drydock/main/scripts/install-drydock.sh | bash -s -- --yesPinned pipe form:
curl -fsSL https://raw.githubusercontent.com/sholdee/drydock/main/scripts/install-drydock.sh | bash -s -- --version vX.Y.Z --yesUse --no-completions when completions should be installed manually.
GitHub Actions
Workflows that install a released binary can use the setup action:
- uses: sholdee/drydock/setup-action@main
with:
version: vX.Y.ZFor pull request validation, the PR action wraps render tests, manifest diffs, image diff reports, source caches, artifacts, and sticky PR comments:
name: drydock
on:
pull_request:
branches: [main]
permissions:
contents: read
pull-requests: write
jobs:
drydock:
runs-on: ubuntu-latest
steps:
- uses: sholdee/drydock/pr-action@main
with:
version: vX.Y.ZThe setup action accepts latest, vX.Y.Z, or bare X.Y.Z and verifies the
selected archive with the release checksum manifest by default.
See the GitHub Actions reference for full action inputs, GitHub App token support, cache behavior, comments, artifacts, and outputs.
Download A Binary
Download Linux and macOS amd64 or arm64 archives from the
latest release. Verify
the archive with checksums.txt before installing the drydock binary.
Docker / GHCR
Release containers are published to GHCR for Linux amd64 and arm64:
docker run --rm -v "$PWD:/workspace:ro" ghcr.io/sholdee/drydock:latest test apps --path /workspaceFor repeatable automation, pin ghcr.io/sholdee/drydock:vX.Y.Z.
Go Install
Build from source with Go:
go install github.com/sholdee/drydock/cmd/drydock@latestManual binary installs can generate shell completions with:
drydock completion zsh
drydock completion bash
drydock completion fishRun drydock from the root of an Argo CD GitOps repository.
List discovered Applications:
drydock get apps --path .Test every discovered Application without printing rendered manifests:
drydock test apps --path .Example text output:
PASS renovate
PASS cert-manager
FAIL argocd/broken Application argocd/broken source[0] path="..." ...
Compare a pull request checkout against a baseline tree:
git worktree add ../baseline main
drydock diff apps --path . --path-orig ../baselineDiff commands use changed-only selection by default. Use
--changed-only=false when you want to render and compare every discovered
Application. Use repeatable --changed-only-include and
--changed-only-ignore globs when CI should ignore known non-GitOps paths
before changed-only ownership is evaluated.
You can also compare against committed Git refs without creating a baseline worktree:
drydock diff apps --path . --ref-orig main
drydock diff apps --repo . --ref feature --ref-orig mainInspect image changes in a machine-readable form:
drydock diff images --path . --path-orig ../baseline -o jsonFor CI jobs that have already populated drydock's source caches, require a cache-only run:
drydock test apps --path . --offline
drydock diff apps --path . --path-orig ../baseline --offline| Goal | Command |
|---|---|
| List Applications | drydock get apps --path . |
| List rendered image references | drydock get images --path . -o name |
| Render all Applications | drydock build apps --path . |
| Render one Application | drydock build app renovate --path . |
| Test renderability | drydock test apps --path . |
| Diff rendered manifests | drydock diff apps --path . --path-orig ../baseline |
| Diff one Application | drydock diff app renovate --path . --path-orig ../baseline |
| Diff rendered image references | drydock diff images --path . --path-orig ../baseline -o json |
| Inspect repository diagnostics | drydock diag --path . |
| Inspect redacted settings | drydock diag --path . --settings -o json |
| Inspect cache roots | drydock cache path |
| List cache entries | drydock cache list -o json |
drydock <command> --help lists command-specific flags. See
the docs reference for the
operator guide index.
drydock covers the common Argo CD GitOps repository shapes operators need to inspect locally and in CI:
- Application discovery: committed Applications, supported ApplicationSets, rendered app-of-apps/bootstrap children, explicit Kustomize discovery entrypoints, AppProjects, and settings objects.
- Rendering: directory, Kustomize, Helm, Jsonnet, single-source and multi-source Applications, Kustomize Helm charts, remote Helm charts, and remote Kustomize sources.
- Source acquisition: declared Git, HTTP Helm, OCI Helm, and remote
Kustomize inputs through explicit drydock caches, plus
--repo-mapfor adjacent local checkouts. - Diffs and images: desired-vs-desired manifest and image diffs, changed-only selection, default noisy-field filtering, and structured or markdown output.
- Plugins: native safe Kustomize compatibility,
avp-compatplaceholder redaction, native policy overrides, staticplugin-policy initandplugin-policy doctoronboarding, trusted exec/container policy with--enable-plugins, and policy bootstrap entrypoints. - Diagnostics: render status, custom health Lua validation, redacted settings/repository/AppProject checks, source acquisition diagnostics, and cache lifecycle commands.
See the compatibility overview for the support matrix and links to detailed reference docs.
drydock performs desired-vs-desired analysis. It renders Kubernetes manifests from repository inputs, explicit mappings, and drydock caches. Diff commands compare a current snapshot to a baseline snapshot.
Default commands do not ask a live Kubernetes cluster or Argo CD server what is currently running. They also do not reproduce runtime behavior such as API defaulting, admission mutation, server-side diff, live health aggregation, managed-fields ownership, or full RBAC authorization.
This boundary is intentional: normal workflows stay fast, deterministic, and
safe for local use and CI. Source acquisition may still fetch declared Git,
Helm, OCI, or remote Kustomize inputs unless --offline is set.
See Runtime Offline and Argo CD Render Parity for the design model and validation strategy.
flowchart TD
current[Current tree]
baseline[Baseline tree]
current --> discover
baseline --> discover
discover[Discover static and rendered Argo CD fleet objects]
discover --> plan[Plan sources, resolve repo maps, use caches]
plan --> render[Render desired manifests with Go libraries]
render --> normalize[Apply Argo-aware filters and diff normalization]
normalize --> outputs[Test statuses, manifest diffs, image diffs, diagnostics]
The render path imports Argo CD API types and selected reusable helpers, but drydock owns offline orchestration. See How It Works and Argo CD Render Parity for the architecture and validation model.
Embedding callers can use github.com/sholdee/drydock/pkg/drydock to list,
render, and diff Applications without shelling out:
result, err := drydock.Render(ctx, drydock.Config{Path: "."})drydock.NewClient accepts public Git, chart, and remote-resource acquirer
interfaces, plus a public config management plugin renderer hook. Embedders can
use those interfaces for tests, offline fixtures, and custom source handling.
When one selected Application fails, the result still includes successful
manifests, diagnostics, and per-Application statuses from the partial build.
drydock is inspired by Flate, a Flux resource inflator, and the home-operations community.
Join the home-operations Discord at https://discord.gg/home-operations.
- Documentation site: curated operator docs and full reference pages.
- Getting started: first local discovery, render test, and comparison commands.
- GitHub Actions: setup action, PR action, comments, artifacts, and caches.
- Local diffs: terminal manifest and image diff workflows.
- Compatibility: supported Argo CD behavior and intentional runtime boundaries.
- Runtime Offline: what drydock does without live Argo CD or Kubernetes.
- Argo CD Render Parity: how covered render semantics are validated against real Argo CD.
- Plugin policy: onboarding commands, trusted policy engines, schema, CMP compatibility, bootstrap discovery, and command security.
- Source acquisition: Git, Helm, remote Kustomize, cache, and auth behavior.
- Reference: operator guide index.
Apache-2.0. See LICENSE.