In one paragraph: the RareCloud Container Registry is a private Docker and OCI image registry. You pick a handle once (for example acme), and every image you push lives under registry.rarestack.net/acme/<repo>:<tag>. You log in with robot credentials (one per CI job, laptop or cluster), and you can link a RareCloud Kubernetes cluster so every namespace can pull your images without copying a secret around. Everything goes through the public API at https://api.rarecloud.io/v1, so the console, the CLI (version 0.4.0) and the Terraform provider (version 0.4.0) all do the same thing. The registry is in beta: tiers, limits and prices below can change before general availability.
Before you start
- A RareCloud account that can order cloud resources. Enabling the registry runs the same balance check as any other cloud order, free tier included: a newer account needs a positive balance that covers what it already runs, and an account that has made two payments and is at least 38 days old can enable it without one.
- An API token with
services:readandservices:write. Create it in the console under Account, then API tokens. Scopes match exactly, so:writedoes not include:read. - Docker, Podman or any other OCI client for pushing and pulling.
kubectlif you want to use the images in Kubernetes. - The CLI or the Terraform provider if you prefer them to the console. Both work with the same token:
export RARECLOUD_TOKEN=rc_pat_...
How it fits together
| Piece | What it is |
|---|---|
| Handle | Your namespace in the registry. 3 to 30 lowercase letters and digits, chosen once, never changed. Some words are reserved. |
| Hostname | registry.rarestack.net. Images are registry.rarestack.net/<handle>/<repo>:<tag>. |
| Tier | free, starter, premium or enterprise. Sets the included storage, the burst ceiling and the repository cap. |
| Credential | A robot login for docker login. Username <handle>+<name>, a secret shown once, scope pull or push (push includes pull), optional expiry. |
| Cluster link | A small controller installed in one of your RareCloud Kubernetes clusters that keeps a pull secret in every namespace. |
| Pull-secret manifest | A ready-to-apply Kubernetes Secret for a cluster you run yourself, anywhere. |
Step by step
1. Pick a tier and enable the registry
rarecloud registry tiers # quota, burst ceiling, price, availability
rarecloud registry enable --handle acme --tier free
rarecloud registry get # hostname, usage, quota, push state
If the handle is taken you get handle_taken; try another. The handle cannot be changed later, so pick the one you want in your image names.
2. Create a credential
rarecloud registry credentials create --name ci --scope push
The output shows the username (acme+ci), the secret and a ready docker login line. The secret is shown once and can never be retrieved again, so store it in your CI secrets or password manager now. Add --expires 90d (or 30d, 1y) for a credential that stops working on its own. Use --scope pull for anything that only needs to download images.
3. Log in, push and pull
echo "$REGISTRY_SECRET" | docker login registry.rarestack.net -u acme+ci --password-stdin
docker tag myapp:latest registry.rarestack.net/acme/myapp:1.0
docker push registry.rarestack.net/acme/myapp:1.0
docker pull registry.rarestack.net/acme/myapp:1.0
Repositories are created by the first push; there is nothing to create first. Docker talks to the registry's token endpoint by itself during login, push and pull, and you never call it by hand.
4. See what you stored
rarecloud registry repos list
rarecloud registry repos get myapp # the repository and its tags
rarecloud registry get # usage, quota and whether a push would be accepted now
registry get reports push.allowed and a reason, so you can see why a push would be refused before you try one (see Limits).
5. Use it from Kubernetes
A RareCloud managed Kubernetes cluster: link it once, and every namespace, including the ones you create later, can pull from your registry.
rarecloud registry clusters link <cluster-service-id>
rarecloud registry clusters list # status goes from linking to active
Then reference the image normally; the pull secret is already attached to the namespace's service accounts:
spec:
containers:
- name: web
image: registry.rarestack.net/acme/myapp:1.0
Read what linking installs before you run it, under What a cluster link installs. You can also ask for the link when you create a cluster in the console or through the API ("registry": {"link": true} on POST /v1/services).
A cluster you run yourself (anywhere): get a ready-to-apply Secret manifest.
rarecloud registry k8s-manifest --namespace apps --scope pull --expiry 90d \
--output-file pull-secret.yaml
kubectl apply -f pull-secret.yaml
The Secret is named rarecloud-registry unless you pass --secret-name. Reference it from your pods:
spec:
imagePullSecrets:
- name: rarecloud-registry
Every k8s-manifest call creates a new credential (it counts toward your credential limit) and the secret inside the manifest is shown once. Revoke the ones you no longer use with rarecloud registry credentials revoke <id>.
6. Clean up
rarecloud registry tags delete myapp 1.0 # one tag; the image and its other tags stay
rarecloud registry manifests delete myapp sha256:<digest> # the image itself and every tag on it
rarecloud registry repos delete myapp --yes # the whole repository, irreversible
rarecloud registry credentials revoke <credential-id> # stops working immediately
rarecloud registry clusters unlink <cluster-service-id> # removes everything the link installed
manifests delete refuses when more than one tag points at the digest, unless you add --confirm.
Authentication
Two different logins are involved, and they do not mix:
| Where | What you use |
|---|---|
| The RareCloud API, CLI, Terraform and console | Your API token (rc_pat_...) with services:read and services:write |
docker login, push, pull, Kubernetes | A registry credential: username <handle>+<name>, its secret |
A registry credential cannot call the API, and an API token cannot log in to the registry. Credential names are 2 to 31 characters: lowercase letters, digits and hyphens, starting with a letter or digit. credentials list never shows a secret; the last used time tells you which credentials are still in use.
Every CLI command
From the 0.4.0 release binary. rarecloud reg is a short alias for rarecloud registry, and every command accepts the global flags (-o json, --token, --api).
Account and tier
| Command | What it does |
|---|---|
rarecloud registry enable | Enable your registry, or reopen a closed one with the same handle. Flags: --handle, --tier (both required) |
rarecloud registry get | Show the account, usage, quota and push state |
rarecloud registry tiers | List tiers with quota, burst ceiling, price, overage in EUR and USD, repository limit and availability |
rarecloud registry set-tier <tier> | Change tier. Upgrades are immediate; a downgrade below your measured usage is refused |
rarecloud registry close | Close the registry (reopenable with the same handle until the grace window ends). Flags: --confirm <your-handle> |
Credentials
| Command | What it does |
|---|---|
rarecloud registry credentials create | Create a robot credential (secret shown once). Flags: --name, --scope pull|push (both required), --expires |
rarecloud registry credentials list | List usable credentials (neither revoked nor expired; never shows a secret). Flags: --include-revoked (list every credential) |
rarecloud registry credentials revoke <id> | Revoke a credential immediately |
Repositories, tags and images
| Command | What it does |
|---|---|
rarecloud registry repos list | List the repositories under your handle. Flags: --limit (1 to 100), --cursor |
rarecloud registry repos get <repo> | Show one repository and its tags |
rarecloud registry repos delete <repo> | Delete a whole repository (irreversible; refuses without --yes). Flags: --yes |
rarecloud registry tags delete <repo> <tag> | Delete one tag (the tag only: an image left untagged is removed by retention, or delete it by digest) |
rarecloud registry tags vulnerabilities <repo> <tag> | List vulnerability findings for a tag (see the note under Limits). Flags: --limit, --cursor |
rarecloud registry manifests delete <repo> <digest> | Delete an image by digest, with every tag that points at it. Flags: --confirm |
Kubernetes
| Command | What it does |
|---|---|
rarecloud registry clusters list | List linked clusters and their status |
rarecloud registry clusters link <service-id> | Link one of your RareCloud Kubernetes clusters |
rarecloud registry clusters rotate <service-id> | Replace the cluster's pull credential without a gap |
rarecloud registry clusters unlink <service-id> | Unlink a cluster (repeating it mid-unlink is fine; a cluster that is not linked fails with not found) |
rarecloud registry k8s-manifest | Print a pull-secret manifest for a cluster you run yourself (creates a new credential each call). Flags: --scope (default pull), --expiry (30d default, 90d, 1y, never), --namespace (default default), --secret-name, --output-file |
Terraform
The rarecloudio/rarecloud provider 0.4.0 has four resources (rarecloud_registry, rarecloud_registry_credential, rarecloud_registry_cluster_link, rarecloud_registry_kubernetes_manifest) and two data sources (rarecloud_registry_tiers, rarecloud_registry_repositories) for the registry. Set up the provider as on the Terraform page.
rarecloud_registry
| Argument | Required | Notes |
|---|---|---|
handle | yes | 3 to 30 lowercase letters and digits. Changing it replaces the resource. |
tier | yes | free, starter, premium or enterprise. Changed in place; a downgrade below your measured usage fails with tier_below_usage. |
Exports hostname, status (active, suspended or closed) and created_at. Destroying it closes the registry: images are not deleted right away, and the same handle can reopen it during the grace window. Import with terraform import rarecloud_registry.acme acme.
rarecloud_registry_credential
| Argument | Required | Notes |
|---|---|---|
name | yes | Becomes the second half of the username, <handle>+<name>. |
scope | yes | pull or push. |
expires_at | no | RFC 3339 time. Omit for a credential that never expires. |
Exports username, secret (sensitive), created_at, last_used_at and revoked_at. Every argument forces a new credential when changed. Destroy revokes it. Import is not supported.
rarecloud_registry_cluster_link
| Argument | Required | Notes |
|---|---|---|
service_id | yes | The service id of a Kubernetes cluster you own. |
Exports status, cluster_name, syncer_ready, last_error, credential_name, secret_name, installs and disclosure (the text under What a cluster link installs). A cluster that is not reachable yet stays linking and is finished later by the platform. Destroy unlinks it.
rarecloud_registry_kubernetes_manifest
For clusters you run yourself. All arguments are optional and force a new credential when changed: scope (default pull), expiry (30d default, 90d, 1y, never), namespace (default default), secret_name (default rarecloud-registry). Exports manifest and secret (both sensitive), username, credential_name and expires_at. It is a resource rather than a data source because every call creates a credential. Destroy revokes it.
rarecloud_registry_tiers (data source)
No arguments. Returns tiers, a list with tier, quota_gb, burst_ceiling_gb, monthly_price_cents_eur, monthly_price_cents_usd, overage_cents_per_gb_month, overage_cents_per_gb_month_usd, max_repos and available.
rarecloud_registry_repositories (data source)
No arguments. Returns repositories (every page, sorted by name), each with name, path, size_bytes, image_built_at (the newest image's build time) and newest_tag. Fails when the registry is not enabled.
Secrets end up in your state
rarecloud_registry_credential.secret and the manifest resource's manifest and secret are stored in Terraform state in plain text. Marking them sensitive only hides them from plan output. The API shows a secret once, so state is the only copy Terraform has. Use an encrypted remote backend with restricted access. If state leaks, destroy the resource (which revokes the credential) and create a new one.
Example
resource "rarecloud_registry" "acme" {
handle = "acme"
tier = "starter"
}
resource "rarecloud_registry_credential" "ci" {
name = "ci"
scope = "push"
}
resource "rarecloud_registry_cluster_link" "prod" {
service_id = "<kubernetes-cluster-service-id>"
}
output "registry_login" {
value = "docker login ${rarecloud_registry.acme.hostname} -u ${rarecloud_registry_credential.ci.username} -p ${rarecloud_registry_credential.ci.secret}"
sensitive = true
}
A cluster you run yourself:
resource "rarecloud_registry_kubernetes_manifest" "byo" {
namespace = "apps"
expiry = "90d"
}
output "pull_secret_manifest" {
value = rarecloud_registry_kubernetes_manifest.byo.manifest
sensitive = true
}
terraform output -raw pull_secret_manifest | kubectl apply -f -
MCP tools
The MCP server (@rarecloudio/mcp-server 0.4.0) has twenty registry tools: get_registry, list_registry_tiers, suggest_registry_handle, list_registry_credentials, list_registry_repositories, get_registry_repository, list_registry_tag_vulnerabilities, list_registry_clusters, enable_registry, set_registry_tier, close_registry, create_registry_credential, revoke_registry_credential, delete_registry_repository, delete_registry_tag, delete_registry_manifest, link_registry_cluster, unlink_registry_cluster, rotate_registry_cluster_link and create_registry_kubernetes_manifest. Until the registry launches in production, the reads stay open (list_registry_tiers and suggest_registry_handle answer normally; get_registry and the other account reads answer 404 "not enabled" because no registry exists yet) and every write tool gets a 503.
What a cluster link installs
Linking creates a pull-only credential for that cluster (named k8s-<service-id>) and installs a small controller, the RareCloud registry secret-syncer, in a rarecloud-system namespace. In short, the disclosure shown when you link a cluster says:
The controller may create a Secret named
rarecloud-registry-credentialsin any namespace, and may read, update or delete only Secrets with that exact name. In its own namespace it may also watch that same Secret, so a rotation takes effect within seconds. It cannot read any other Secret in the cluster. It can read every ServiceAccount and change itsimagePullSecrets. It acts in every namespace exceptkube-*,monitoring, the platform's own system namespaces, and any namespace or ServiceAccount labelledrarecloud.io/registry-secret=disabled. Unlinking removes everything it installed.
The pull credential can read every repository under your handle, in every namespace it reaches. To keep a namespace out, label it:
kubectl label namespace sandbox rarecloud.io/registry-secret=disabled
rotate mints a new credential and only revokes the old one after every namespace has the new copy, so pods never lose the ability to pull.
Limits
| Limit | Value |
|---|---|
| Registries per account | 1 |
| Active credentials | 20 per account (cluster links and pull-secret manifests count) |
| Enable attempts | 3 per account and 10 per IP address per day |
| Repositories | 20 (free), 100 (starter), 500 (premium), 2,000 (enterprise) |
| Registry token requests (login, push, pull) | 30 a minute per IP address; 10 failed logins a minute per credential |
| Grace window after closing | 7 days, then the stored images are deleted for good |
A push is refused, and registry get says why, when:
push.reason | What it means |
|---|---|
over_ceiling | Storage reached the tier's burst ceiling. Delete images or move to a bigger tier. |
repo_limit | You are at the tier's repository cap. Pushes to existing repositories still work. |
balance_under_72h | Your spendable balance does not cover 72 hours of the registry's current cost. Top up. |
meter_stale_24h | Usage could not be measured for over a day, so new pushes pause until it can. |
suspended | The registry account is suspended. Pulls keep working; pushes resume once the suspension is lifted (contact support). |
Pulls are never blocked by any of these. Usage is measured once an hour, so a delete shows up in registry get within the hour.
Vulnerability scanning is not active yet. The tags vulnerabilities command and the vulnerability counts on tags exist, but today they report the scan as unavailable.
Pricing
Beta pricing, provisional until launch. These are the defaults in the code today; rarecloud registry tiers (or GET /v1/registry/tiers) always shows the live numbers, including USD.
| Tier | Included storage | Burst ceiling | Monthly |
|---|---|---|---|
free | 10 GB | 10 GB (no burst) | EUR 0 |
starter | 20 GB | 40 GB | EUR 3.50 |
premium | 50 GB | 100 GB | EUR 7.50 |
enterprise | 1,024 GB | 2,048 GB | EUR 15 |
Storage above the included amount, up to the burst ceiling, is EUR 0.02 per GB per month. Storage is the logical size of your images in decimal GB, measured hourly; a layer shared by two repositories counts in each. The monthly fee is billed by the hour and capped at the monthly price, and a tier change applies from the hour it happens. It all lands on your cloud invoice with the rest of your cloud usage.
Troubleshooting
| What you see | What it means |
|---|---|
The container registry is not available yet. (HTTP 503) | The registry has not launched yet. |
Not enough balance to order this when enabling | Enabling runs the same balance check as any cloud order, even on the free tier. Top up and retry. |
handle_taken | Someone else has that handle. Pick another; the console can suggest free ones. |
credential_limit | You have 20 active credentials. Revoke unused ones, including old pull-secret manifests. |
tier_below_usage | You are trying to downgrade below what you store. Delete images first. |
account_closed | The registry is closed. Run registry enable with the same handle inside the grace window to reopen it. |
docker login fails with 401 | Check the username is <handle>+<name>, the credential is not revoked or expired, and you pasted the whole secret. |
docker push is denied but login works | The credential has pull scope, or registry get shows a push refusal reason above. |
Pods show ImagePullBackOff on a linked cluster | Run registry clusters list: the link must be active with the syncer ready. Check the namespace is not labelled rarecloud.io/registry-secret=disabled. |
already_linked or rotation_in_progress | The cluster is already linked, or a rotation is still running. Wait and check clusters list. |
Links
- API reference: console.rarecloud.io/docs/api
- CLI releases: github.com/RareCloudio/rarecloud-cli
- Terraform provider: registry.terraform.io/providers/rarecloudio/rarecloud
- The same API from the command line and as code: CLI docs and Terraform docs