Container Builds with Shipwright
Brokkr integrates with Shipwright Build to provide native container image building capabilities. This guide covers installation, configuration, and usage of Shipwright builds through Brokkr’s work order system.
Overview
Section titled “Overview”Shipwright Build is a CNCF Sandbox project that provides a framework for building container images on Kubernetes. Brokkr uses Shipwright as the execution engine for build work orders, allowing you to:
- Build container images from Git repositories
- Push images to container registries
- Leverage production-ready build strategies (buildah, kaniko)
- Manage builds through Brokkr’s work order API
Prerequisites
Section titled “Prerequisites”Kubernetes Version
Section titled “Kubernetes Version”Shipwright integration requires Kubernetes 1.29 or later due to dependencies on newer API features.
# Verify your Kubernetes versionkubectl versionCluster Requirements
Section titled “Cluster Requirements”- Sufficient resources for build pods (recommended: 4GB memory, 2 CPU cores available)
- Network access to container registries you’ll push to
- Network access to Git repositories you’ll build from
Installation Options
Section titled “Installation Options”Option 1: Chart-Managed Installation (Recommended)
Section titled “Option 1: Chart-Managed Installation (Recommended)”Enabled by default. Nothing is vendored into the chart: on every helm install and every helm upgrade, a pre-install hook Job downloads the pinned upstream release manifests and kubectl applys them.
# Install agent with chart-managed Shipwright (default)helm install brokkr-agent oci://ghcr.io/colliery-io/charts/brokkr-agent \ --set broker.url=http://brokkr-broker:3000 \ --set broker.existingSecret=brokkr-agent-credentials \ --waitThis installs:
- Tekton Pipelines (v0.68.1) - Task execution engine
- Shipwright Build (v0.18.1) - Build orchestration
- Sample ClusterBuildStrategies (buildah, kaniko, etc.)
- A webhook TLS certificate for Shipwright — self-signed by the Job by default, or issued by cert-manager when
shipwright.certManagement=cert-manager
The versions are pinned in the chart’s values (shipwright.install.tektonVersion and shipwright.install.shipwrightVersion) and are the versions the integration is tested against. Override them there if you need different releases.
Before you enable it, know what the hook does
Section titled “Before you enable it, know what the hook does”The installer Job is not a scoped add-on. Two consequences are worth deciding on deliberately:
- It needs internet egress from the cluster. The Job fetches release manifests from
storage.googleapis.comandgithub.comat install time. In an air-gapped or egress-filtered cluster it will hang and then fail onactiveDeadlineSeconds. Use Option 2 there. - It runs as
cluster-admin. Installing CRDs, cluster-scoped controllers, and namespaces requires it, so the chart creates a ServiceAccount bound tocluster-adminfor the duration of the hook. It also mutates cluster-wide state outside the release namespace — thetekton-pipelinesandshipwright-buildnamespaces, fourshipwright.ioCRDs, and the cluster build strategies — none of which Helm will remove when you uninstall the agent.
If either is unacceptable in your cluster, install Shipwright out-of-band and use Option 2.
Option 2: Bring Your Own Shipwright
Section titled “Option 2: Bring Your Own Shipwright”If you already have Shipwright and Tekton installed, need specific versions, or cannot grant the installer Job cluster-admin and internet egress, turn the installation off but keep shipwright.enabled=true — that flag also gates the agent’s RBAC for shipwright.io and tekton.dev resources, which build work orders require. With both install.* flags false the hook Job, its ServiceAccount, and its cluster-admin binding are not rendered at all:
# Skip the installer job, keep Shipwright integration (and RBAC) enabledhelm install brokkr-agent oci://ghcr.io/colliery-io/charts/brokkr-agent \ --set broker.url=http://brokkr-broker:3000 \ --set broker.existingSecret=brokkr-agent-credentials \ --set shipwright.install.tekton=false \ --set shipwright.install.shipwright=false \ --waitSet shipwright.enabled=false only if you are not using build work orders at all.
Manual Shipwright Installation
Section titled “Manual Shipwright Installation”If installing Shipwright manually, prefer the versions the chart pins (Tekton v0.68.1, Shipwright v0.18.1) — older releases may work but are not what Brokkr is tested against. These are the same manifests the hook Job applies, so running them yourself from a mirror is the supported air-gapped path:
# Install Tekton Pipelineskubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.68.1/release.yaml
# Wait for Tekton to be readykubectl wait --for=condition=Ready pods -l app=tekton-pipelines-controller -n tekton-pipelines --timeout=300s
# Install Shipwright Buildkubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.18.1/release.yaml
# Wait for Shipwright to be readykubectl wait --for=condition=Ready pods -l app=shipwright-build-controller -n shipwright-build --timeout=300s
# Install sample build strategieskubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.18.1/sample-strategies.yamlVerifying Installation
Section titled “Verifying Installation”Check Components
Section titled “Check Components”# Verify Tekton Pipelineskubectl get pods -n tekton-pipelines# Expected: tekton-pipelines-controller and tekton-pipelines-webhook Running
# Verify Shipwright Buildkubectl get pods -n shipwright-build# Expected: shipwright-build-controller Running
# Verify ClusterBuildStrategieskubectl get clusterbuildstrategies# Expected: buildah (and others if sample strategies installed)Test Build Capability
Section titled “Test Build Capability”Create a simple test build to verify the installation:
# test-build.yamlapiVersion: shipwright.io/v1beta1kind: Buildmetadata: name: test-buildspec: source: type: Git git: url: https://github.com/shipwright-io/sample-go strategy: name: buildah kind: ClusterBuildStrategy output: image: ttl.sh/brokkr-test-$(date +%s):1h---apiVersion: shipwright.io/v1beta1kind: BuildRunmetadata: generateName: test-build-run-spec: build: name: test-build# Apply the test buildkubectl apply -f test-build.yaml
# Watch the build progresskubectl get buildruns -w
# Check build logskubectl logs -l buildrun.shipwright.io/name=test-build-run-xxxxx -c step-buildConfiguration
Section titled “Configuration”Build Strategies
Section titled “Build Strategies”The chart-managed installation includes the official sample ClusterBuildStrategies (buildah, kaniko, buildpacks, etc.) by default via shipwright.install.sampleStrategies:
# Sample strategies are installed by default; re-enable explicitly if neededhelm upgrade brokkr-agent oci://ghcr.io/colliery-io/charts/brokkr-agent \ --reuse-values \ --set shipwright.install.sampleStrategies=trueDisable Sample Strategies
Section titled “Disable Sample Strategies”If you only want Shipwright without sample strategies:
helm install brokkr-agent oci://ghcr.io/colliery-io/charts/brokkr-agent \ --set broker.url=http://brokkr-broker:3000 \ --set broker.existingSecret=brokkr-agent-credentials \ --set shipwright.enabled=true \ --set shipwright.install.sampleStrategies=falseRBAC Configuration
Section titled “RBAC Configuration”Build work orders require the agent to manage shipwright.io and tekton.dev resources. The brokkr-agent chart includes these RBAC rules in the agent ClusterRole whenever shipwright.enabled=true (even when the installer Job is skipped):
# Automatically included when shipwright.enabled=true- apiGroups: ["shipwright.io"] resources: ["*"] verbs: ["*"]- apiGroups: ["tekton.dev"] resources: ["*"] verbs: ["*"]If you disable shipwright.enabled, the agent loses these permissions and build work orders will fail.
Registry Authentication
Section titled “Registry Authentication”To push images to private registries, create a Kubernetes secret:
# Create registry credentials secretkubectl create secret docker-registry registry-creds \ --docker-server=ghcr.io \ --docker-username=<username> \ --docker-password=<token> \ --docker-email=<email>Reference this secret in your Build spec:
apiVersion: shipwright.io/v1beta1kind: Buildmetadata: name: my-buildspec: source: type: Git git: url: https://github.com/org/repo strategy: name: buildah kind: ClusterBuildStrategy output: image: ghcr.io/org/my-image:latest pushSecret: registry-creds # Reference your secret hereGit Authentication
Section titled “Git Authentication”For private Git repositories:
# Create Git credentials secret (HTTPS)kubectl create secret generic git-creds \ --from-literal=username=<username> \ --from-literal=password=<token>
# Or for SSHkubectl create secret generic git-ssh-creds \ --from-file=ssh-privatekey=/path/to/id_rsaReference in your Build:
spec: source: type: Git git: url: https://github.com/org/private-repo cloneSecret: git-credsTriggering a Build Through Brokkr
Section titled “Triggering a Build Through Brokkr”Builds run through Brokkr’s work order system. Create a work order with work_type: "build" and the Shipwright Build YAML in yaml_content, targeting agents by ID, label, or annotation:
curl -X POST "http://broker:3000/api/v1/work-orders" \ -H "Authorization: Bearer $ADMIN_PAK" \ -H "Content-Type: application/json" \ -d '{ "work_type": "build", "yaml_content": "apiVersion: shipwright.io/v1beta1\nkind: Build\nmetadata:\n name: my-build\nspec:\n source:\n type: Git\n git:\n url: https://github.com/org/repo\n strategy:\n name: buildah\n kind: ClusterBuildStrategy\n output:\n image: ghcr.io/org/my-image:latest\n pushSecret: registry-creds", "targeting": { "labels": ["builder"] } }'A matching agent claims the work order, applies the Build, creates a BuildRun, and watches it to completion. The watch lasts at most 15 minutes, and less when the work order has a short claim_timeout_seconds. On success, the work order completes with the image digest as its result message; on failure, the error details are recorded instead. If the BuildRun is still running at the end of the watch, the work order fails without a retry. The agent does not cancel the BuildRun, so it can still finish in the cluster. Completed work orders move to the work-order log:
# View completed builds (the message field carries the image digest)curl "http://broker:3000/api/v1/work-order-log?work_type=build" \ -H "Authorization: Bearer $ADMIN_PAK"See the Work Orders Reference for the full request schema, targeting semantics, and retry behavior.
Troubleshooting
Section titled “Troubleshooting”Helm Install Hangs, Then Fails
Section titled “Helm Install Hangs, Then Fails”The pre-install hook Job is blocking the release. Read its logs before anything else — a stalled manifest download (no cluster egress) and a rejected kubectl apply (installer ServiceAccount missing its cluster-admin binding) look identical from Helm’s side:
kubectl logs -l app.kubernetes.io/component=shipwright-installer --tail=100The Job self-deletes shortly after success, so an empty result on a healthy install is expected.
Build Pods Not Starting
Section titled “Build Pods Not Starting”# Check for pending podskubectl get pods -l build.shipwright.io/name
# Check eventskubectl get events --sort-by='.lastTimestamp'
# Verify ServiceAccount has required permissionskubectl auth can-i create pods --as=system:serviceaccount:default:defaultShipwright Controller Not Ready
Section titled “Shipwright Controller Not Ready”# Check controller logskubectl logs -n shipwright-build -l app=shipwright-build-controller
# Check for CRD installationkubectl get crd builds.shipwright.io buildruns.shipwright.ioTekton Pipeline Failures
Section titled “Tekton Pipeline Failures”# Check Tekton controller logskubectl logs -n tekton-pipelines -l app=tekton-pipelines-controller
# Check TaskRun statuskubectl get taskrunskubectl describe taskrun <taskrun-name>Next Steps
Section titled “Next Steps”- Learn about Work Orders for managing builds through Brokkr
- Configure Monitoring for build metrics