Skip to content

feat(builds): build images on a remote build machine #403

Open
0 of 6 issues completed
Open

Description

@PiquelChips

Problem

piqueld builds images on the host that runs them. On a small production host, a build competes with the services it is about to replace for CPU, memory and disk, and the build cache fills the same disk as the volumes. A larger machine on the same tailnet can't help.

Model

  • The host still checks the repository out. Git credentials, snapshots and self sources don't move.
  • A build machine runs the build: a BuildKit daemon and an image registry, reached over the tailnet. The host's docker buildx sends it the build context.
  • BuildKit pushes to the build machine's registry, and the host pulls by digest, as it already does for image sources. Only the layers the host lacks travel.
  • The build machine may be off. Running services, restores, promotions, drift repair and restarts need no build. A deployment that does need one fails fast, unless the host is configured to build locally instead.
  • A deployment reuses the image of an unchanged build, so a change to a variable or a secret deploys without the build machine.

Decisions

  • One build machine, configured in config.toml under [build]: by the rule in feat(settings): daemon settings editable through the API #334 it is a fact about the host. The manifest stays backend-neutral (refactor(runtime): a runtime backend abstraction, with Swarm behind it #323), so an application doesn't choose where it builds.
  • The registry lives on the build machine, not on the host: pushes are local, the history of images stays off the smaller disk, and the host keeps only what it runs plus images.keep_deployments. An external registry would need registry credentials, which piqueld doesn't have.
  • A dedicated BuildKit daemon, not the build machine's Docker Engine over SSH: access to Docker is root on that machine, and an internet-facing host shouldn't hold it.
  • An unreachable build machine fails the deployment by default (builder_unavailable). Building on the host instead is opt-in, since a build can starve production.
  • Reuse is the default. A redeployment of an unchanged commit no longer pulls newer base images; --rebuild forces a build.

Roadmap

Order Issue Depends on Pull request
1 #404 reuse the image of an unchanged build none #425
2 #405 run builds on a remote builder #404 #428, stacked on #425
3 #406 handle an unreachable builder #405 #432, stacked on #428
4 #407 show the builder in the CLI and dashboard #406 #434, stacked on #432
5 #408 a build machine module #405
6 #409 clean up the build machine's registry #405

The pull requests form a stack: each builds on the one before it and merges after it, so each issue depends on the previous one. For this machine, PiquelChips/dotfiles#29 sets up the registry by hand until #408 provides a module.

Related: #322 and #325 (other nodes need a registry to pull from), #329 (services sharing one build use the same build identity), #334 (which settings stay in config.toml).


Written with Claude Fable 5.2 in Claude Code (via T3 Code).

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions