Container registry
Push your container images to Plany, and run them on Sandbox and Agones Autopilot.
Plany has its own container registry, at <region>.plany.cr — eu-west-2.plany.cr
today. Push images with docker, podman or whatever your CI already uses, and run
them on Sandbox and Agones Autopilot
without credentials for somebody else's registry.
An image's address is the registry, your project's id and a repository:
eu-west-2.plany.cr/{project}/{repository}:{tag}eu-west-2.plany.cr/{project}/{repository}@sha256:{digest}Create a repository first
A repository has to exist before you can push to it. Pushing to one that does not exist is refused, so a typo in a tag cannot quietly create something — and a repository is what access is granted on, so it is worth creating on purpose.
Compute → Container registry → New repository → name it → Create repositoryA repository id is lower case letters and digits, with ., _ or - between them,
and no slashes — it becomes part of every image reference that points at it. Your
project's id is the first part of the reference too, so it has to follow the same
rule; creating a repository in a project whose id does not is refused with the
reason.
Immutable tags
By default a tag can be moved, the way latest usually is. Turn on
immutable tags and a push that would move an existing tag is refused, so a tag
names one image for good — what a reproducible deploy wants.
plany registry repositories create api --immutable-tagsplany registry repositories update api --immutable-tagsIn Terraform it is immutable_tags = true.
Logging in
The registry accepts two kinds of password, and the username is not checked — any value works.
An API key is the simplest: the one you already have.
echo "$PLANY_API_KEY" | docker login eu-west-2.plany.cr -u plany --password-stdinA registry credential is better for a build machine: it reaches the registry and nothing else on Plany, expires on its own, and carries only what you ask for.
# Signed in yourself: prints the docker login command to runplany registry login # In CI: the password alone on stdout, so it can be substitutedplany registry get-token --repository api --lifetime 30m \ | docker login eu-west-2.plany.cr -u plany --password-stdin| Option | Does |
|---|---|
--repository | Restrict it to these repositories. The default is every repository in the project you can reach. |
--read-only | Pulling only — right for anything that deploys rather than builds. |
--lifetime | How long it lasts. An hour by default, at most 12 hours. |
A credential never carries more than you hold: it is what you asked for, intersected with what your own roles allow, and the CLI prints exactly what it was granted.
Pushing and pulling
docker build -t eu-west-2.plany.cr//api:v1 .docker push eu-west-2.plany.cr//api:v1 docker pull eu-west-2.plany.cr//api:v1Multi-platform images work: an image index holding one image per platform is stored as one, and a pull picks the one that matches.
In GitHub Actions
- name: Log in to Plany run: | plany registry get-token --repository api --lifetime 30m \ | docker login eu-west-2.plany.cr -u plany --password-stdin env: PLANY_API_KEY: ${{ secrets.PLANY_API_KEY }} - name: Build and push run: | docker build -t eu-west-2.plany.cr//api:${{ github.sha }} . docker push eu-west-2.plany.cr//api:${{ github.sha }}Seeing what is in a repository
Compute → Container registry → open the repository → open an imageFor each image you see its digest, every tag pointing at it, its size and the platforms it runs on. The console's image page has ready-to-copy pull and deploy commands pinned to the digest, so what runs is exactly those bytes however the tags move later.
A repository's last_pull_time shows when anything last fetched from it — the way to
find a repository nothing uses any more.
Running your images
On Sandbox
Name the repository and a tag or digest; Plany resolves a tag to its digest when it deploys, so a tag moving later does not change what is running.
plany sandbox sandboxes deploy api --image api:v1The image must be in the sandbox's own project and region. See Deploying a sandbox.
On Agones Autopilot
Use the full reference in your manifest's pod template, as you would any registry:
containers: - name: game image: eu-west-2.plany.cr//lobby:v1Applying the manifest needs permission to pull from that repository — you cannot run an image you could not pull yourself. See Agones Autopilot.
Who pulls
Neither needs a credential from you. Each sandbox and game server pulls as its own
identity, and Plany grants that identity roles/registry.puller on the one
repository its image comes from. If you give a sandbox a service account of your
own, grant it yourself:
resource "plany_registry_repository_iam_member" "backend_pulls" { repository = plany_registry_repository.api.name role = "roles/registry.puller" member = plany_service_account.backend.name}roles/registry.puller can pull and nothing else: a workload that is compromised can
fetch the image it was already running, and cannot replace the image the next one
starts from.
Who can do what
| Role | Registry |
|---|---|
roles/project.owner, roles/account.admin, roles/account.owner | Everything, including deleting repositories. |
roles/project.editor | Create and update repositories, push, pull and delete images. Cannot delete a repository. |
roles/project.viewer, roles/account.viewer | See repositories and images, and pull. |
roles/registry.puller | Pull from the one repository it is granted on. |
A change of role reaches the registry within a few minutes, because a login stays good for a few minutes after it is checked.
Credit and limits
Pushing needs credit on the account. When your balance runs out, pushes are refused within a few minutes and pulls keep working, so what you already run keeps starting.
| Hobby | Pro | |
|---|---|---|
| Repositories per project, per region | 5 | 50 |
Ask for more on registry.plany.cloud/repositories.