When you’re iterating on application code, the last thing you want is a slow feedback loop. sew’s builds feature lets you compile, build a Docker image, push it to the cluster, and restart workloads – all in a single command, without leaving your terminal.
Defining builds#
Add a builds section to your sew.yaml. Each entry describes one image you build locally. Here is a real-world example that builds Ambassador Edge Stack from source:
from:
- gravitee.io/ee/edge-stack
builds:
- name: emissary
image: emissary-base:local
dir: $HOME/src/gravitee/edge-stack
pre:
- EMISSARY=$(make -C apro env BUILD_VERSION=dev 2>/dev/null | sed -n 's/^EMISSARY_IMAGE=//p') && docker pull --platform linux/amd64 $EMISSARY && docker tag $EMISSARY emissary-base:local
- name: aes
image: docker.io/datawire/aes:3.12.7
dir: $HOME/src/gravitee/edge-stack/apro
pre:
- make $PWD/vendor
platform: linux/amd64
buildArgs:
EMISSARY_BASE: emissary-base:local
The from field pulls the edge-stack registry context, which brings in the Kind cluster config, Helm chart, CRDs, and preload images. The builds section adds two local builds on top.
Builds run sequentially in declaration order, which matters here because the two entries form a chain:
emissaryhas no Dockerfile in its context directory. sew detects this and skipsdocker build, but still runs theprecommand – which pulls the upstream Emissary image forlinux/amd64and tags it asemissary-base:local– then pushes that image to the cluster. This pattern is useful for preparing base images from upstream without writing a Dockerfile.aesbuilds the actual Edge Stack image. It references the locally-tagged base viabuildArgs.EMISSARY_BASE, vendorizes Go dependencies in itsprestep, and forcesplatform: linux/amd64so the build works on Apple Silicon machines where the base image is only published for amd64.
| Field | Required | Description |
|---|---|---|
name | yes | Short identifier, used to select builds on the CLI |
image | yes | Docker image tag to build (e.g. myapp:latest) |
dir | no | Working directory for pre commands and base for relative paths. Supports env vars ($HOME). Defaults to . |
pre | no | Shell commands run sequentially before docker build (compilation, packaging, etc.) |
buildArgs | no | Docker build arguments passed to docker build --build-arg. Values support $VAR / ${VAR} env-var expansion |
context | no | Docker build context, relative to dir. Defaults to . |
dockerfile | no | Path to the Dockerfile, relative to dir. Defaults to Dockerfile in the context |
platform | no | Target platform for docker build --platform (e.g. linux/amd64). Useful when the base image is only available for a specific architecture |
When neither
dockerfileis set nor aDockerfileexists in the resolved context directory, sew skipsdocker buildentirely but still pushes the image to the cluster and restarts workloads. Use this for pre-only builds that pull or tag images without building them.
Running builds#
sew build
This builds every entry in declaration order, pushes each image to the cluster’s preload registry, and restarts any Deployment or StatefulSet that references the image. In the example above, sew build runs emissary first (pull + tag + push) then aes (vendorize + docker build + push). Build output is captured in ~/.sew/logs/build/build.log and the terminal shows a clean progress view.
Building a subset#
Pass one or more names to build only what you need:
sew build aes
Once the Emissary base image is cached in the cluster, you typically only rebuild aes during iteration. You can also pass multiple names:
sew build emissary aes
Skipping pre-build commands#
When you’ve already vendorized locally and just want to rebuild the Docker image:
sew build --skip-pre aes
Building without restarting#
Push the image to the registry but don’t trigger a rollout restart:
sew build --no-restart aes
Creating and building in one step#
If you don’t have a cluster yet, --create creates one before building. When the cluster already exists, the flag is silently ignored:
sew build --create
This runs the full sew create flow (preload, cluster, component install) then proceeds with the builds. You can pass context flags too – they’re forwarded to the creation step:
sew build --create --skip-pre aes
This is the fastest way to go from a clean machine to running your local code on a cluster.
How builds interact with preloading#
When builds is configured, sew automatically excludes build images from the preload list during sew create. The edge-stack context preloads docker.io/datawire/aes:3.12.7, but since the aes build targets the same image tag, sew skips pulling it from the remote registry – it knows a local build will replace it.
This works transparently with both merge and replace preload modes. You don’t need to manually add skip entries for your build images.
Flags reference#
| Flag | Description |
|---|---|
--create | Create the cluster if it doesn’t exist |
--skip-pre | Skip pre-build commands, go straight to docker build |
--no-restart | Build and push but don’t restart workloads |
--name <cluster> | Target a specific cluster (default: from config) |
Build logs#
All build output is written to ~/.sew/logs/build/build.log. When a step fails, sew points you to the log file:
✗ Running pre-build commands (failed after 12.3s)
See logs: /home/user/.sew/logs/build/build.log
Patching a running cluster#
sew build is for local code changes. When you need to bump an upstream image tag, change a Helm chart version, or tweak values on a running cluster without recreating it, use sew patch.
Write a patch file with the components you want to upgrade:
components:
- name: edge-stack
helm:
values:
emissary-ingress:
image:
tag: 3.13.0
Then apply it:
sew patch upgrade.yaml
sew merges the patch into the resolved context and upgrades only the named components – everything else is left untouched. You can preview the changes before applying them:
sew patch upgrade.yaml --dry-run
This runs a server-side dry-run and prints a colored diff of what would change.
See the patch command reference for the full set of flags and merge rules.