Devsy
Managing your Providers

Kubernetes registry access without client credentials

A Kubernetes workspace can use a prebuilt image from a private registry without client registry credentials. The cluster pulls the image through a node identity or a service account imagePullSecret. Devsy normally reads the image configuration on the client to get the container user, environment, entrypoint, command and devcontainer.metadata. The IMAGE_CONFIG_FILE option supplies those details from a local file, so the client needs no registry read credentials.

Use this option only with a digest-pinned image that has no Features. It does not support Dockerfile builds, Compose, recovery, prebuilds or workspace image builds. Devsy trusts the file. The digest in the file catches accidental mismatches but cannot confirm that the contents came from the image.

Create the image details file

Use a fully qualified digest reference. Export the config for the Linux platform you need, then convert the OCI config to Devsy's versioned wrapper:

IMAGE='registry.example.com/team/dev-image@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
crane config --platform linux/amd64 "$IMAGE" | jq --arg image "$IMAGE" '{schemaVersion: 1, image: $image, os: "linux", architecture: "amd64", config: (.config | {User: (.User // ""), Env: (.Env // []), Labels: (.Labels // {}), Entrypoint: (.Entrypoint // []), Cmd: (.Cmd // [])})}' > image-details.json

The wrapper has this shape:

{
  "schemaVersion": 1,
  "image": "registry.example.com/team/dev-image@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "os": "linux",
  "architecture": "amd64",
  "variant": "",
  "config": {
    "User": "1000:1000",
    "Env": ["PATH=/usr/local/bin:/usr/bin"],
    "Labels": {"devcontainer.metadata": "[]"},
    "Entrypoint": ["/usr/local/bin/start"],
    "Cmd": ["serve"]
  }
}

variant is optional. The file must be a regular UTF-8 file of at most 1 MiB with one version 1 wrapper. The wrapper needs a fully qualified digest reference that matches the requested image, a Linux platform that matches ARCHITECTURE, and a valid config object. If the file is missing or invalid, Devsy fails and does not fall back to registry inspection.

Pin the image reference in devcontainer.json to the same digest. For a multi-platform image, generate one file per platform.

ARCHITECTURE selects the config platform, so Devsy does not list cluster nodes. It does not place the pod on a matching node. On a cluster with mixed architectures, also set NODE_SELECTOR.

Publish the image and its details file as separate artifacts. Devsy does not upload the details file with the image or send it to the cluster.

Configure the Kubernetes provider

Kubernetes must already have registry pull access. Add the admin-managed imagePullSecrets to the workspace service account or pod template, or use the node's registry identity. The Devsy client still needs its usual namespace permissions and access to the daemon-configuration Secrets. It does not need to read the registry pull Secret.

To use cluster-managed pull credentials without reading Docker credentials on the client, turn off credential forwarding and Devsy pull-secret creation:

devsy context set [context-name] --option SSH_INJECT_DOCKER_CREDENTIALS=false
devsy provider set kubernetes --option KUBERNETES_PULL_SECRETS_ENABLED=false

Set the file and architecture for each workspace. Use a stable absolute path:

devsy workspace up ./project --provider kubernetes --ide none \
  --provider-option IMAGE_CONFIG_FILE="$PWD/image-details.json" \
  --provider-option ARCHITECTURE=amd64

In Devsy Desktop, set IMAGE_CONFIG_FILE to an absolute path on the machine that runs Desktop. Keep the file at that path while you use the provider. Moving it does not change an existing workspace's saved image configuration. A normal up validates the configured file but keeps the workspace's saved launch recipe. To apply changed image metadata, recreate the workspace with the updated file. On another machine or workspace host, copy the file there and set its new absolute path. After the workspace exists, status, logs, stop and delete do not need the file.

If the cluster cannot pull the image, Kubernetes reports a failure such as ImagePullBackOff. Configure the service account, pod template or node identity that pulls the image. Client Docker credentials do not give the cluster pull access.

On this page