Container Registry

Your private Docker registry

Push images to registry.suble.io, deploy them by name anywhere on Suble. Log in once from your terminal — your servers authenticate themselves.

the whole workflow
suble docker login

docker tag myapp registry.suble.io/prj_xxx/myapp:1
docker push registry.suble.io/prj_xxx/myapp:1

# suble.yml — that's the whole deploy config for the image
image: registry.suble.io/prj_xxx/myapp:1

Quickstart

Three steps from a local image to a running deployment. No registry setup, no credentials to manage — your project already has a namespace waiting.

1

Connect your terminal

One command. The CLI mints a registry credential from your Suble session and hands it straight to Docker — there is nothing to copy or paste.

log in
suble docker login

2

Push your image

Tag the image with your project's namespace and push like you would to any registry. Layers upload once and land in your private namespace.

tag & push
docker tag myapp registry.suble.io/prj_xxx/myapp:1
docker push registry.suble.io/prj_xxx/myapp:1

3

Deploy it by name

Reference the image in suble.yml, the CLI or the dashboard. Your server is signed in automatically — no docker login on the box, ever.

deploy
image: registry.suble.io/prj_xxx/myapp:1   # suble.yml

Your namespace is your project uid — the CLI prints it after login, and the dashboard shows it at the top of Project → Container Registry.

How it works

Your project is your namespace

Every image lives at registry.suble.io/<project>/<image>:<tag>. A token scoped to your project can never read or write another project's images — isolation is enforced by the token itself, not by convention.

Tokens, not passwords

Access is granted by registry tokens: push (read + write) or pull-only. The CLI mints them for you; the dashboard creates and revokes them. The secret is shown once and stored only as a hash.

Deploys sign in for themselves

Deploy an image from your own namespace and Suble authenticates the server with a pull-only credential before pulling. Public images from Docker Hub or ghcr keep working exactly as before.

image references
registry.suble.io/prj_xxx/myapp:1
registry.suble.io/prj_xxx/api:2026-06-29
registry.suble.io/prj_xxx/worker@sha256:…   # pin by digest

Manage your images

Everything you push shows up under Project → Container Registry in the dashboard: every image with its versions, sizes and digests, copy-ready pull commands, and deletion of single versions or whole images. The same tools live in the CLI:

CLI commands

suble docker lslist imagesEvery image in your namespace with its latest version, version count, unique size and last build.
suble docker tags <image>list versionsAll pushed versions of one image — tag, digest, size and build time. `suble docker ls <image>` does the same.
suble docker rm <image>[:tag]deleteDelete one version — or the whole image when no tag is given. Add --yes to skip the confirmation.
suble docker push <local> [name[:tag]]tag + pushConvenience wrapper: tags a local image into your namespace and pushes it in one go.
example
$ suble docker ls
IMAGE     LATEST  VERSIONS  SIZE     UPDATED
demo-app  v3      3         11.4 MB  2026-07-02 14:02

$ suble docker tags demo-app
TAG  DIGEST        SIZE    BUILT
v3   1832327faf04  4.0 MB  2026-07-02 14:02
v2   45e09956dc66  4.1 MB  2026-07-01 09:14
v1   5cd72f301a29  3.4 MB  2026-06-28 17:45

$ suble docker rm demo-app:v1 --yes
✓ Deleted demo-app:v1. Disk is reclaimed by the nightly cleanup.

Deploy with automatic authentication

Point a deploy at an image in your own namespace and Suble signs the instance in with a pull-only credential before pulling. You never run docker login on a server or put a registry password in suble.yml.

suble.yml — private image
name: web
plan: BXS.s1
image: registry.suble.io/prj_xxx/myapp:1   # private — pulled automatically
expose:
  domain: app.example.com
  port: 8080

How the auto-login behaves

triggeryour own namespaceAuto-login fires only for images under registry.suble.io/<your-project>/. Any other host or namespace gets no injected credentials.
scopepull-onlyThe deploy credential can read your images, never push. One reusable system token per project, created on first use.
secret handlingencrypted at restThe system token is AES-encrypted in the database and presented to the VM only at deploy time. You never see or manage it.

Pushing from CI

Pipelines authenticate with a project API key — no browser flow. Push a per-commit tag and reference it from your deploys; use a dedicated --name so the token is easy to spot and revoke later.

CI push
# CI pipeline — no browser: authenticate with a project API key
export SUBLE_API_KEY=sk_proj_…
npx @suble/cli docker login --project prj_xxx --name ci

# push a per-commit tag; deploys reference it by name
docker push registry.suble.io/prj_xxx/myapp:$GIT_SHA

Pricing

One number: storage. There are no plans, minimums or egress fees.

0.25 DKK per GB per month

Metered hourly, priced once per invoice. Delete an image and it stops counting at the next hourly tick.

Unique layers only

You pay for the unique bytes your images reference. Ten tags sharing a base image count the shared layers once.

Everything else is free

Pulls, pushes and bandwidth cost nothing. The registry sits in the same datacenter as your instances, so pulls are fast and off your traffic bill.

Reference

The details behind the workflow — token semantics, login flags and the small print worth knowing.

suble docker login flags

Flags

--project <uid>stringProject to authenticate against (its uid is the registry namespace). Omitted → you're prompted to pick one.
--pullflagMint a pull-only (least-privilege) token instead of a push token. Use for read-only machines/pipelines.
--name <n>stringLabel stored on the token for auditing. Defaults to cli@<your-hostname>.
suble docker login / logout
suble docker login --project prj_xxx
# → ✓ Logged in to registry.suble.io (project prj_xxx, push scope)
#   Tag & push images as: registry.suble.io/prj_xxx/<image>:<tag>

suble docker logout   # docker logout registry.suble.io

Tokens from the dashboard

Prefer not to use the CLI? Create push or pull-only tokens under Project → Container Registry, copy the ready-made docker login command, and revoke them any time.

Token fields

scopepush | pullpush = read + write (build/CI). pull = read-only (least privilege).
secretstringThe docker login password, format sbreg_<hex>. Shown once; stored hashed. Use your project uid as the username.
revokeactionRevoking a token immediately stops it issuing new pull/push grants. Existing short-lived sessions expire within minutes.

Good to know

Notes

Version datesbuild timeThe registry records when an image was built (from its config), not when it was pushed — pushing an old image shows its original build date.
Deleting a versionby digestA version is deleted by its digest. If two tags point at the exact same version, both disappear together — the UI and CLI warn when you delete.
Reclaimnightly cleanupDeleted layers are reclaimed by a nightly garbage-collection. Billing stops at the next hourly tick regardless.
Scanning & backupyour CIRun image scanning in your pipeline if you need it, and keep your source authoritative — every image is re-pushable from CI.