Registries
Registries hold the credentials Daytona uses to pull images from private container registries. A registry credential is a username and a password or token for one registry host. A project holds at most one credential per host, matched by the host in the image reference.
Stored credentials apply to registry images. Daytona uses the credential to import a registry image and to pull it again for a Linux sandbox. Pulls from a host without a credential, and the base image of a Dockerfile build, are anonymous and work only for public images. macOS sandboxes ignore stored credentials.
Registry credentials work with GitHub Container Registry, Docker Hub, Google Artifact Registry, Amazon ECR, and any registry that accepts HTTP Basic authentication. Daytona encrypts the password or token at rest and never returns it. The provider kinds check the host when you store the credential, so a credential stored for the wrong host fails at that point instead of at pull time.
| Concept | Description |
|---|---|
| Registry credential | A username and a password or token, stored for one registry host in a project. |
| Host | The registry host, as host[:port]. Docker Hub hosts are stored as index.docker.io, and image references without a host use that credential. |
| Kind | The authentication type. basic works with any registry that accepts HTTP Basic authentication. ghcr, gcr, and ecr also check the host. |
| Anonymous pull | A pull from a host with no stored credential. It works only for public images. |
| Rotation | Storing a credential for a host that already has one replaces it. The next pull uses the new credential. |
- You store a credential for a registry host: the host, a kind (
basic,ghcr,gcr, orecr), a username, and a password or token. Theghcr,gcr, andecrkinds validate the host, so a misconfigured credential fails at write time rather than silently at pull time. - Daytona takes the host from the registry reference of an image import. A sandbox create takes a registered image name or ID; when the image was imported from a registry and is not present in the target region, Daytona pulls it again from that image’s registry reference.
- If a credential is stored for that host, the pull authenticates with it; otherwise the pull is anonymous. No opt-in is needed on individual requests.
- To rotate a credential, store the same host again with the new password. The update replaces the credential in place and takes effect on the next pull.
A registry credential has the following fields:
| Field | Description |
|---|---|
host | Bare host[:port], no scheme or path. One credential per host. |
kind | basic (default), ghcr, gcr, or ecr. ghcr requires ghcr.io; gcr requires a gcr.io, *.gcr.io, or *-docker.pkg.dev host; ecr requires an *.dkr.ecr.<region>.amazonaws.com host. |
username | Registry username, such as a GitHub username for ghcr, _json_key for gcr, or an AWS access key ID for ecr. |
password | Password or token, at most 64 KiB, such as a service account JSON key for gcr or an AWS secret access key for ecr. Write-only: encrypted at rest and never returned. |
description | Optional free-form note. |
Use cases
Section titled “Use cases”Registry credentials are used when the images that sandboxes boot from are not public.
- Private application images: images that a CI pipeline builds and pushes to a private registry are imported and boot in sandboxes.
- Images in a cloud provider’s registry: images stored in Amazon ECR or Google Artifact Registry are pulled with that provider’s access keys, such as an AWS access key or a service account JSON key.
- Private Docker Hub repositories: a credential stored for Docker Hub also applies to image references without a host, such as
my-org/my-image. - Self-hosted registries: any registry that accepts HTTP Basic authentication works with a
basiccredential for its host. - Sandboxes in other regions: a sandbox created in a region that does not have the image yet pulls it again from the registry with the stored credential.
- Credential rotation: a leaked or expired token is replaced in place, and the next pull uses the new one with no change to images or sandboxes.
- Early credential checks: the
ghcr,gcr, andecrkinds validate the host when the credential is stored. A credential for the wrong host fails at that point instead of at pull time. - Team access without shared tokens: a credential is stored once per host for the whole project, and its token is encrypted and never returned. Team members import private images without holding the token.
Container registries
Section titled “Container registries”Store a credential for a registry host. Storing a credential for a host that already has one replaces the stored credential. Daytona encrypts the password at rest, and reads return only the host, kind, username, description, and last update time.
- Go to Daytona Registries ↗
- Click
- Enter the following details:
- : the registry host, as
host[:port] - : the registry kind: Basic (username + password), GitHub Container Registry, Google Container Registry, or Amazon ECR
- : the registry username
- : the registry password or token
- : an optional description
- : the registry host, as
- Click
printf %s 'YOUR_REGISTRY_PASSWORD' | daytona registry set YOUR_REGISTRY_HOST \ --username YOUR_REGISTRY_USERNAME \ --password-stdin| Flag | Type | Description |
|---|---|---|
--username | string | Sets the registry username. This flag is required. |
--password-stdin | bool | Reads the password or token from standard input. Pass exactly one of --password-stdin and --password. |
--password | string | Sets the password or token on the command line. The value is visible in the process list and shell history. Prefer --password-stdin. |
--kind | string | Sets the registry kind: basic, ghcr, gcr, ecr, or ecr_role. ecr_role takes the IAM role ARN as --username and no password. The default is basic, or the stored kind if the host already has a credential. |
--description | string | Sets the description. An empty string clears the stored description. The default is the stored description if the host already has a credential. |
curl 'https://api.daytona.com/registries/YOUR_REGISTRY_HOST' \ --request PUT \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "username": "YOUR_REGISTRY_USERNAME", "password": "YOUR_REGISTRY_PASSWORD"}'| Field | Type | Description |
|---|---|---|
username | string | Sets the registry username. This field is required. |
password | string | Sets the password or token, at most 64 KiB. This field is required for every kind except ecr_role, which ignores it. |
kind | string | Sets the registry kind: basic, ghcr, gcr, ecr, or ecr_role. For ecr_role, username is the IAM role ARN that Daytona assumes, with the organization ID as the external ID. If omitted, the kind resets to basic. |
description | string | Sets a free-form note. If omitted, the stored description is cleared. |
- Each request replaces the whole credential.
GitHub Container Registry
Section titled “GitHub Container Registry”printf %s 'YOUR_GITHUB_PAT' | daytona registry set ghcr.io \ --kind ghcr \ --username YOUR_GITHUB_USERNAME \ --password-stdincurl 'https://api.daytona.com/registries/ghcr.io' \ --request PUT \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "kind": "ghcr", "username": "YOUR_GITHUB_USERNAME", "password": "YOUR_GITHUB_PAT"}'Docker Hub
Section titled “Docker Hub”Store a credential for Docker Hub. Daytona stores Docker Hub credentials under the host index.docker.io. The hosts docker.io, registry-1.docker.io, and registry.hub.docker.com refer to the same credential, and image references without a registry host, such as python:3.12, use it.
printf %s 'YOUR_DOCKERHUB_TOKEN' | daytona registry set docker.io \ --username YOUR_DOCKERHUB_USERNAME \ --password-stdincurl 'https://api.daytona.com/registries/docker.io' \ --request PUT \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "username": "YOUR_DOCKERHUB_USERNAME", "password": "YOUR_DOCKERHUB_TOKEN"}'Google Artifact Registry
Section titled “Google Artifact Registry”# The password is the service account JSON keydaytona registry set us-docker.pkg.dev \ --kind gcr \ --username _json_key \ --password-stdin < service-account-key.jsoncurl 'https://api.daytona.com/registries/us-docker.pkg.dev' \ --request PUT \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "kind": "gcr", "username": "_json_key", "password": "YOUR_SERVICE_ACCOUNT_JSON_KEY"}'Amazon ECR
Section titled “Amazon ECR”Store AWS access keys for an Amazon ECR registry. Daytona checks the keys with AWS STS on store and refuses keys that AWS rejects or that belong to an account other than the host’s. A failed check leaves any existing credential for the host unchanged.
printf %s 'YOUR_AWS_SECRET_ACCESS_KEY' | daytona registry set AWS_ACCOUNT_ID.dkr.ecr.AWS_REGION.amazonaws.com \ --kind ecr \ --username YOUR_AWS_ACCESS_KEY_ID \ --password-stdincurl 'https://api.daytona.com/registries/AWS_ACCOUNT_ID.dkr.ecr.AWS_REGION.amazonaws.com' \ --request PUT \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "kind": "ecr", "username": "YOUR_AWS_ACCESS_KEY_ID", "password": "YOUR_AWS_SECRET_ACCESS_KEY"}'Use private registry images
Section titled “Use private registry images”Import a private image into the project, then create sandboxes from it by name. The import authenticates with the credential stored for the host in the image reference. A Linux sandbox create takes a registered image name or ID, which must be ready first.
from daytona import Daytona
daytona = Daytona()
# The pull authenticates with the credential stored for ghcr.ioimage = daytona.v2.images.pull("ghcr.io/acme/private-runtime:latest", name="private-runtime")
# The pull returns once it is queued; each wait returns after 30 seconds at mostwhile image.status not in ("ready", "failed"): image = daytona.v2.images.get(image.id, wait="ready")if image.status == "failed": raise RuntimeError(image.error)
sandbox = daytona.v2.create("private-runtime")import { Daytona } from '@daytona/sdk'
const daytona = new Daytona()
// The pull authenticates with the credential stored for ghcr.iolet image = await daytona.v2.images.pull('ghcr.io/acme/private-runtime:latest', { name: 'private-runtime' })
// The pull returns once it is queued; each wait returns after 30 seconds at mostwhile (image.status !== 'ready' && image.status !== 'failed') { image = await daytona.v2.images.get(image.id, { wait: 'ready' })}if (image.status === 'failed') throw new Error(image.error ?? 'image build failed')
const sandbox = await daytona.v2.create('private-runtime')# The import authenticates with the credential stored for ghcr.iodaytona image create private-runtime --ref ghcr.io/acme/private-runtime:latestdaytona sandbox create --image private-runtimedaytona image createwaits up to--timeoutand exits with an error if the image fails.- The default
--timeoutis10m.
# The import authenticates with the credential stored for ghcr.iocurl 'https://api.daytona.com/images' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "name": "private-runtime", "source": { "type": "registry", "ref": "ghcr.io/acme/private-runtime:latest" } }'
# Returns on ready or failed, or after timeout_ms; repeat while status is pending or buildingcurl 'https://api.daytona.com/images/{imageId}?wait=ready&timeout_ms=60000' \ --header 'Authorization: Bearer YOUR_API_KEY'
curl 'https://api.daytona.com/sandboxes' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "image": "private-runtime" }'POST /imagesreturns once the pull is queued.{imageId}is theimage_idfield of thePOST /imagesresponse.timeout_msdefaults to 30 seconds and is at most 60 seconds.
Operations
Section titled “Operations”List registries
Section titled “List registries”daytona registry listcurl 'https://api.daytona.com/registries' \ --header 'Authorization: Bearer YOUR_API_KEY'Get a registry
Section titled “Get a registry”daytona registry get ghcr.iocurl 'https://api.daytona.com/registries/ghcr.io' \ --header 'Authorization: Bearer YOUR_API_KEY'Delete a registry
Section titled “Delete a registry”Delete the credential for a registry host. Later pulls from that host are anonymous.
daytona registry delete ghcr.io- The command asks for confirmation.
- A non-interactive shell requires
--yes.
curl 'https://api.daytona.com/registries/ghcr.io' \ --request DELETE \ --header 'Authorization: Bearer YOUR_API_KEY'- Deleting a host that has no stored credential succeeds.