WakaStart
Sources & services

Build — from code to Docker image

The pipeline that turns your Git code into a deployable Docker image.

Version v1.08 min read

Build — from code to Docker image

📍 Where to find this in the UI — Infra → Builds tab (global list of all the app's builds)

What is a Build? The operation that takes your Git code and turns it into a Docker image — an executable, reproducible package that K8s can run.

The Build pipeline

text
Repository (code source) ↓ git checkout <branch / tag / commit> ↓ docker build (Dockerfile) ↓ Image Docker dans le registry privé Wakastart ↓ Disponible pour déploiement

Build statuses

StatusMeaning
PENDINGWaiting to run
BUILDINGDocker build in progress
PUSHINGImage built, being uploaded to the registry
SUCCEEDEDOK, the image is available
FAILEDSomething went wrong

How to trigger a build

TriggerWhen
MANUALYou click "Build" in the UI, choosing a branch/tag/commit
GIT_PUSH🚧 Coming soon — will automatically trigger a build on push to the watched branch

Once SUCCEEDED, the image is available: you can deploy it in an environment via a ServiceInstance.

Image names

Each build produces an image with a unique name. Date and time are in UTC.

Build typeImage nameExample
Branch<branch>-YYYYMMDD-hhmmssmain-20261009-143012
Commit<branch or commit>-YYYYMMDD-hhmmss-<sha7>main-20261009-143012-3f9a2c1
Git tag<tag>-YYYYMMDD-hhmmssv1.2.0-20261009-143012
  • <sha7>: the first 7 characters of the commit.
  • A commit build that isn't attached to any branch starts with commit: commit-20261009-143012-3f9a2c1.
  • The branch name is lowercased, and disallowed characters are replaced with -: feature/Login becomes feature-login.
  • The git tag keeps its case: only characters that aren't allowed in a Docker tag are replaced with -, and leading . or - characters are removed. release/V1.0 becomes release-V1.0.
  • Wakastart always picks the name. An image name sent through the API when creating the build is ignored.

Build cache

Every build starts from scratch: the platform doesn't reuse any layer from a previous build. There is no "No cache" option anymore.

The API still accepts the noCache field, so existing calls don't break, but it no longer has any effect.

Image retention (automatic purge)

Each successful build leaves an image in the app's registry. Without a purge, these images pile up. The automatic purge deletes the images of the oldest builds, while always keeping the ones still in use.

Enabling the purge

The purge is disabled by default. It's set app by app:

The purge card is only displayed in French: its labels are quoted as they appear on screen, followed by a translation.

  1. Open Infra → Builds, card Purge automatique des builds (automatic build purge).
  2. Turn on Purge automatique (automatic purge).
  3. Choose the number of Builds gardés par branche (builds kept per branch): 10 by default, between 3 and 500.
  4. Click Enregistrer (save), then confirm.

Before you save, the screen shows how many images the next purge would remove with the value you entered. It's a maximum: at purge time, more images may still be spared.

You're asked to confirm when you turn the purge on, and also when you lower the number of builds kept. The confirm button only becomes active once the number of affected images has been worked out; if that calculation fails, the dialog says so and you can still confirm.

Only the app's managers can change these settings: by default, the profiles that already have the right to delete builds. Other users can see them but can't change them.

What is kept

Builds are sorted into groups. In each group, the N most recent are kept (N = the number you chose):

Build typeGroup
Branchthe branch
Commit attached to a branchthe same branch as the branch builds
Commit without a branchone "commits" group per service
Git tagone "tags" group per service

Only successful builds are affected. A build in progress or a failed build is never touched.

What is never deleted

Even beyond the N most recent, an image is always kept if:

  • it's running in one of the app's environments;
  • it was deployed less than 90 days ago, including the image that this deployment replaced (so you can roll back);
  • it's shared with a kept build;
  • it's used by a scheduled task;
  • it's still referenced in the cluster, for example in a deployment's history.

When in doubt, nothing is deleted: if the platform can't check what the cluster uses, that night's purge doesn't run.

When and how

  • The purge runs every night at 03:30.
  • It deletes at most 100 images per night, across the whole platform. A large first purge can therefore spread over several nights.
  • A deleted image can't be recovered. The matching build can no longer be deployed. To get that version back, run a new build of the same commit.
  • Space is only freed by the registry's weekly cleanup, on Sunday at 00:00 UTC. The displayed storage therefore goes down at most one week after the purge.
  • The card shows the date of the last purge and the number of images deleted.

Purge in simulation mode

The platform can run the purge in simulation mode. In that case, nothing is deleted: the purge only works out which images would have gone. The card says so with a message starting with « La purge tourne actuellement en simulation » (the purge is currently running in simulation mode), followed by the date of the last simulation and the number of images that would have been deleted. « Dernière purge » (last purge) only covers real purges. This message only shows when the purge is turned on for the app. The purge handles at most 100 images per night across the whole platform, so the number shown can be lower than the total.

Badges in the build list

BadgeMeaning
Déployé · prod, dev (deployed)The image is running in environments of these types
Conservé (kept)The purge won't delete this image: it's among the most recent of its group, or it's protected (see above)

Registry quota

A platform administrator can set a storage quota for an app. By default, there is none.

The Registre card

The Registre (registry) card, at the top of Infra → Builds, shows:

  • the storage used by the app's images, and when it was measured;
  • if there is a quota: the storage used out of the quota, with a gauge.

Storage is measured every 15 minutes, and after each successful build.

A warning appears at 80% of the quota. At 100%, new builds are refused.

When the quota is reached

Wakastart refuses to start a new build of the app, whether it's started from the console, through the API, or automatically. The message is in French:

Quota du registre atteint : X Go utilisés sur Y Go. Libérez de la place (purge automatique, suppression de builds) ou demandez un relèvement du quota.

(registry quota reached: X GB used out of Y GB. Free up space (automatic purge, deleting builds) or ask for a higher quota.) X has one decimal, with a dot as separator (for example 41.2), and Y is a whole number of GB (Go in French). Through the API, the response has status 409.

Good to know:

  • The quota is checked when the build starts. A build that has already started runs to the end, even if it pushes storage over the quota.
  • Deploying an image that has already been built is still possible.
  • Nothing is limited in the registry itself: it's Wakastart that refuses to start the build.

Freeing up space

Turn on the automatic purge (see above). Note: the space of a purged image is only freed by the registry's weekly cleanup, on Sunday at 00:00 UTC. Until then, the displayed storage doesn't go down and new builds are still refused.

If you can't wait, ask a platform administrator to raise the quota.

Diagnosing a failed build

If a Wakastart build ends up FAILED, the first thing to do is reproduce the error locally with docker build. The Wakastart builder runs exactly the same command as you would locally — if it passes locally, it passes on the platform.

For a reliable diagnosis, clone the repo into a fresh folder before running the build:

bash
git clone <url-du-repo> /tmp/build-check cd /tmp/build-check git checkout <branche-ou-commit-qui-échoue> docker build -f <dockerfilePath> <buildContext>

This matters because a working copy typically contains artifacts that don't exist on Wakastart's side and that can mask the error:

  • a locally installed node_modules/ (which may contradict what pnpm install produces in the Dockerfile)
  • a dist/ or .next/ folder left over from a previous build
  • a local .env file that injects variables missing on the platform
  • generated Prisma binaries (@prisma/client) that might compensate for a prisma generate step forgotten in the Dockerfile
  • an out-of-sync lockfile (pnpm-lock.yaml modified but not committed)

A build in a freshly cloned repo reproduces exactly the Wakastart builder's context: only versioned files are present, nothing else. If the error doesn't reproduce under these conditions, it's coming from a local artifact, not the committed code.

💡 A well-written .dockerignore (excluding node_modules, .next, dist, .env*) already protects against most artifact leaks into the Docker context — but doesn't exempt you from testing in a fresh repo if doubt remains.