Skip to content

CI/CD Pipelines

A pipeline watches a git branch. It rebuilds on every new commit. It is the automated half of althost's build system. althost build runs locally from a checkout. A pipeline runs the same build on a dedicated machine whenever the branch changes.

The loop is always build → artifact → deploy:

  1. The builder agent (althost-builder) polls the control plane for your pipelines.
  2. For each pipeline it clones/pulls the branch. When the HEAD commit changes, it runs althost build against the repo's althost.yaml.
  3. That uploads artifacts — a zip for static apps, an image tarball for services/containers — exactly as a local build does.
  4. The workload runner downloads the latest artifact and deploys it (blue-green for containers; a failed build leaves the running version alone).

Nothing goes through a registry. The builder need not be the machine that runs your workloads.

Create a pipeline

In the portal under Pipelines, give a name, the repository URL, and a branch. For a private repo over SSH, the builder generates an ed25519 deploy key on first run. It reports the key's public half. Add that to the repo host (GitHub → Deploy keys). The private key never leaves the builder.

The build targets and their configuration come from the repo's own althost.yaml (see CLI & althost.yaml). The pipeline record only tracks the repo, branch, deploy key, and last-built commit.

Run the builder agent

The builder is a standalone agent. Install it on any machine with git and a container builder (Docker, nerdctl, or podman). The install is one line, like the runner:

curl -s "https://api.althost.dev/v1/builder/script" | sh -s -- \
  --server https://api.althost.dev --api-key ak_xxx

That installs althost-builder (bundled with the CLI it drives) to ~/.local/bin. The API key needs pipelines:read, pipelines:write, and the relevant *:deploy scopes for what the repos build. Then:

althost-builder run      # one pass: build any pipeline whose branch has new commits
althost-builder watch    # poll continuously (ALTHOST_BUILDER_INTERVAL, default 30s)

Run it on demand. Or run it as a long-running service on a dedicated build machine (althost-builder watch). Set ALTHOST_DOCKER to pick a non-default image builder (e.g. nerdctl, podman). Set ALTHOST_BUILDER_LABEL to name the machine in run history.

Under the hood the builder talks to the control plane over a small HTTP contract (GET /v1/pipelines/poll, POST /v1/pipelines/:id/claim, .../runs/:runId/logs, .../runs/:runId/finish, plus the artifact upload endpoints). A reimplementation in any language works the same way.

Runs & build logs

The system records each build as a run (commit, status, start/finish, duration, and which builder ran it). Expand a pipeline in the portal (Runs) to see its history. Each run has a Logs view. That view streams the build's output live. It uses the same log viewer as services and containers. The system captures a failed run's output too. You can see why it failed without shell access to the builder.

Multiple builders

You can run more than one builder against the same pipelines (e.g. for capacity or redundancy). When a new commit appears, builders claim the build atomically. Only one wins and builds it. The rest skip. A commit is never built twice. If a builder crashes mid-build, its claim expires (PIPELINE_LEASE_MINUTES, default 30). Another builder can take over. Set a stable ALTHOST_BUILDER_LABEL per machine (defaults to the hostname) to identify them in run history.

Artifact access

Uploaded artifacts (image tarballs) are not publicly downloadable. The system serves them only through an authenticated route. It serves them only to a runner assigned to the target. The builder uploads over an API key. The runner downloads with its own token.

Webhooks

Polling is the default (simple, firewall-friendly). Commit webhooks that trigger an immediate build are a planned addition on top of the same pipeline model.