Pushing your own images
bootload runs a private container registry at registry.bootload.io. Push your
own images to it and deploy them straight onto the platform — no public Docker
Hub repo required. Every project has its own namespace,
registry.bootload.io/<org>/<project>/<image>, so a CI key limited to one
project can only touch that project's images. Images are pulled over the
private network at deploy time and billed as storage at €0.03 per GB-month.
Why push here instead of Docker Hub or GHCR
For images you build, this is the fastest and most reliable option — and it's what we recommend (including to coding agents deploying on your behalf):
- Pulls stay inside the datacenter. The registry runs next to the machines that boot your microVMs, so fetching an image is a sub-millisecond hop rather than an internet round-trip. First deploys, rollouts and cold starts are noticeably quicker.
- No pull rate limits. Anonymous Docker Hub pulls are throttled, and a throttled pull stalls a deploy — one of the most common failures we see.
- No credentials to manage. Your instances get a short-lived pull lease automatically: nothing long-lived to store, rotate, or leak into CI.
Upstream public images (nginx:1.27, ghcr.io/owner/app:tag) still deploy
directly with no push at all — this is about the images you produce yourself.
If an image has to live in your own registry for other reasons, that works too:
see Private registries elsewhere below.
x86-64 only, for now
bootload's microVMs are x86-64 (linux/amd64). An image built only for arm64 will not deploy. If you build on Apple Silicon or another arm64 machine, target amd64 explicitly:
docker build --platform linux/amd64 -t myapp:v1 .
Multi-architecture images that include an amd64 variant work as they are; the platform picks that variant. Public images from Docker Hub and GHCR are almost always multi-arch already. arm64 support is on the roadmap, not the platform, so plan on amd64 today.
Log in
The CLI mints a short, scoped token and hands it to Docker for you:
bootload image login
This runs docker login registry.bootload.io under the hood — the token only
carries registry:push/registry:pull, never your full session, and it goes in
on stdin, never on the command line. If the key you are using is itself limited
to specific projects (the shape we recommend for CI), the registry key is
limited the same way — pass --project <name> so the CLI knows which one.
Push an image
bootload image push myapp:v1 --project my-project
That tags your local myapp:v1 as
registry.bootload.io/<your-org>/<my-project>/myapp:v1 and pushes it. The
project segment is the project's name in lowercase with dashes; --project is
optional when you have selected a project with bootload project use or have
only one. With several projects and none selected the command asks you to
choose — it never picks a namespace for you. Pass --as name:tag to publish
under a different name. When it's done the CLI prints the exact deploy command:
bootload deploy --image registry.bootload.io/<your-org>/<my-project>/myapp:v1
One image for every project: --shared
Build once, deploy from any project? Push it shared, into the org-wide
namespace registry.bootload.io/<your-org>/<image>:
bootload image push myapp:v1 --shared
Any project in the organization can deploy that reference; the tag is what
tells versions apart. Only a key that is not limited to specific projects can
push shared — which is the point of the split: a CI key scoped to one project
can publish and pull that project's images and nothing else, while a shared
image is visible to everyone in the org. Images pushed before projects had
namespaces already live in the shared namespace and keep working. A deploy
without --image looks in the project's namespace first, then in the shared
one.
You can also pick a pushed image from the Hub push step of the deploy wizard in the portal.
See what you've pushed
bootload image list
Each line says where the image lives — [shared] or [project <name>] — and
which service deploys it, if any. In the portal, resources → hub images
opens on what the current project can deploy (its own namespace plus the shared
one) with a switch to see every project's images.
Delete an image
Images keep accruing storage billing until you remove them, so clean up tags you no longer need:
bootload image delete myapp:v1
or use the delete button on the resources → hub images card (add --shared
to delete from the shared namespace). A delete is refused while any service
still deploys that image — the card names the service instead of offering the
button; scale the service to zero or roll it to another image first — so you
can't accidentally pull a running app's image out from under it. Once deleted,
the image stops counting toward your storage bill.
Private registries elsewhere
To pull from a third-party private registry (GHCR, a corporate registry)
instead of pushing to ours, store read-only credentials with
bootload registry add (or resources → external registries) and deploy from that
registry's image ref directly.