Devsy
Developing Providers

Drivers

A driver decides how Devsy deploys the workspace container. Set it with driver in the agent section. The default is docker.

Built-in drivers: docker, kubernetes, apple, microsandbox and custom. A sixth, external, runs a runtime plugin and is described below.

Docker Driver

The Docker driver is the default driver that Devsy uses to deploy the workspace container.

This container (specified through a devcontainer.json), is executed through Docker inside the provider environment, for example in a VM in case of Machine Providers.

Some optional configs are available:

  • path: where to find the Docker CLI or a replacement, such as Podman. Defaults to docker.
  • install: whether to install Docker or not in the target environment
  • builder: which docker builder to use
  • runtime: explicitly select the container runtime (docker, podman, or nerdctl). When empty, the runtime is auto-detected from the binary at path.
  • elevation: optionally run docker commands through a privilege-elevation helper for rootful daemons whose socket the current user can't access. One of pkexec, sudo, doas, or none (default).
  • helperImage: overrides the helper image used for volume operations. Empty falls back to the DEVSY_HELPER_IMAGE environment variable, then a built-in default.
  • env: a map of environment variables to set when running docker commands, e.g. DOCKER_HOST

Example config:

agent:
  containerInactivityTimeout: 10m
  docker:
    path: /usr/bin/docker
    install: false
    elevation: none
    env:
      DOCKER_HOST: ""

Kubernetes Driver

Instead of Docker, Devsy is also able to use Kubernetes as a Driver, which allows you to deploy the workspace to a Kubernetes cluster instead. For example, this makes it possible to create a provider that spins up a remote Kubernetes cluster (or just a namespace), connects to it, and creates a workspace there. Devsy also has a default Kubernetes provider that uses the local Kubernetes config file to deploy the workspace.

The allowed options for the Kubernetes driver are:

  • kubernetesContext: which kube context to use (if empty will use current kube context)
  • kubernetesConfig: path to which kube config to use (if empty will use default kube config, or $KUBECONFIG)
  • kubernetesNamespace: which namespace to use (if empty will use current namespace or default)
  • kubernetesPullSecretsEnabled: if true, Devsy will create Kubernetes pull secrets from injected Docker credentials for private registries
  • podTimeout: how long the provider waits for the workspace pod to come up, e.g. 10m
  • createNamespace: if true, Devsy will try to create the namespace
  • clusterRole: if defined, Devsy will create a role binding for the given cluster role for the workspace container. This is useful if you need Kubernetes access within the workspace container
  • serviceAccount: if defined, Devsy will use the given service account for the dev container
  • architecture: the CPU architecture to use for the workspace pod, e.g. amd64, arm64. If empty, Devsy inspects the cluster's nodes to auto-detect it (and errors out if the cluster has mixed architectures).
  • inactivityTimeout: after how much time to automatically stop the pod due to inactivity
  • storageClass: the storage class to use to create the persistent volume claim
  • diskSize: the default size for the persistent volume to use, e.g. 10Gi
  • pvcAccessMode: the access mode to use for the persistent volume claim, e.g. RWO, ROX, RWX or RWOP
  • pvcAnnotations: annotations to add to the main workspace PVC
  • nodeSelector: the node selector to use for the workspace pod, e.g. my-label=value,my-label-2=value-2
  • resources: resource requests/limits for the workspace container, e.g. requests.cpu=500m,limits.memory=5Gi
  • workspaceVolumeMount: overrides the path where the workspace volume is mounted. Defaults to the root of your workspace source code.
  • podManifestTemplate: a pod manifest template (inline YAML or a file path) used as the base to build the Devsy pod
  • labels: labels to add to the workspace pod, e.g. devsy.sh/example=value,devsy.sh/example2=value2
  • strictSecurity: Clears the hardcoded runAsUser/runAsGroup/runAsNonRoot fields (retaining capabilities and privileged), letting the cluster assign the container's UID/GID instead of forcing root. It sets hostUsers: false unless podManifestTemplate explicitly supplies hostUsers; this satisfies OpenShift restricted-v3.
  • agentSecurityContext: Inline YAML or a file path for a corev1.SecurityContext merged field by field onto the workspace and init containers. It can configure run-as, capabilities, privilege escalation, seccomp, and other supported security-context fields, overriding Devsy's defaults. It sets hostUsers: false unless podManifestTemplate explicitly supplies hostUsers. A matching named container in podManifestTemplate remains the highest-precedence override.
  • agentInstallPath: overrides where the agent binary is installed inside the devsy/devsy-init containers. Defaults to /usr/local/bin/devsy, which requires root to write; set this to a path under a writable mount (e.g. the workspace volume) when running non-root.
  • kubernetesUserNamespaces: Sets hostUsers: false (unless podManifestTemplate already set it), mapping the pod's UIDs into a Linux user namespace. strictSecurity and agentSecurityContext also opt in for OpenShift restricted-v3; provide hostUsers explicitly through podManifestTemplate on clusters without user-namespace support. UserNamespacesSupport is disabled by default in Kubernetes 1.30–1.32, enabled by default in 1.33–1.35, and becomes GA with the gate locked on from 1.36. Node-level support is also required (Linux kernel 6.3+, containerd 2.0+/CRI-O 1.25+).

On OpenShift, the default container security context (fixed runAsUser/runAsGroup) is rejected by the restricted-v2/restricted-v3 SCCs, which assign UIDs/GIDs from a per-namespace range. Set strictSecurity: "true" and/or agentSecurityContext (or override the container's securityContext via a named container in podManifestTemplate) to satisfy those SCCs. Also set agentInstallPath to a path under a writable mount, because a non-root container cannot write the default /usr/local/bin/devsy.

Devsy also supports building images inside Kubernetes without Docker, via a dockerless build path (agent.dockerless.disabled / agent.dockerless.image). This replaces the previous buildkit-based building approach.

Example Kubernetes Provider

Example Kubernetes provider that uses local kubectl to run a workspace in the current kube context:

name: simple-kubernetes
version: v0.0.1
agent:
  containerInactivityTimeout: 10m # Pod will automatically kill itself after timeout
  path: ${DEVSY}
  driver: kubernetes
  kubernetes:
    # kubernetesContext: default
    # kubernetesNamespace: my-namespace-for-devsy
    # clusterRole: ""
    # serviceAccount: ""
    diskSize: 20Gi
    createNamespace: true
exec:
  command: |-
    ${DEVSY} helper sh -c "${COMMAND}"

Then add the provider via devsy provider add ./simple-kubernetes.yaml

Apple Driver

The Apple driver runs the workspace as a Linux container using Apple's native container runtime (macOS 26+, Apple silicon). This is the driver used by the built-in apple provider.

Available options:

  • path: where to find the container binary. Defaults to container.
  • rosetta: enable Rosetta for x86_64 emulation inside the Linux guest.
  • env: a map of environment variables to set when running container commands
agent:
  containerInactivityTimeout: 10m
  driver: apple
  apple:
    path: container
    rosetta: "false"

Microsandbox Driver

The Microsandbox driver boots the devcontainer image as a hardware-isolated microVM using microsandbox. It is used by the built-in microsandbox provider.

Options:

  • memory, cpus: guest memory in MiB and virtual CPU count. Empty uses the runtime default.
  • maxMemory, maxCpus: ceilings for hotplugged memory and CPUs.
  • storage: root disk size in GiB. Falls back to the devcontainer's hostRequirements.storage.
  • blockEgress: deny the microVM outbound public network access.
  • ephemeral: boot from a tmpfs root disk, so disk state is discarded when the VM stops.
  • workspaceHostPermissions: mirror (default) mirrors guest permission changes on the workspace mount to the host. private keeps them in microsandbox metadata.
  • workspaceStatVirtualization: strict (default) requires host metadata support. relaxed tolerates filesystems without it. off exposes literal host ownership and modes, and cannot be combined with mirror.

Changing the workspace permission policy or the developer identity requires devsy up --recreate. The VM root disk is discarded on recreate, so back up VM-local data first. The host workspace and named volumes persist.

agent:
  containerInactivityTimeout: 10m
  driver: microsandbox
  microsandbox:
    memory: "2048"
    blockEgress: "false"
    workspaceStatVirtualization: "strict"

Custom Driver

The custom driver lets a provider implement the devcontainer lifecycle with its own shell commands. With driver: custom, these commands are required under agent.custom:

  • findDevContainer: find an existing devcontainer.
  • commandDevContainer: run a command inside it.
  • targetArchitecture: print the target architecture.
  • runDevContainer, startDevContainer, stopDevContainer, deleteDevContainer: run, start, stop and delete it.

Optional: getDevContainerLogs prints the logs, and canReprovision says whether the devcontainer can be reprovisioned in place.

External Driver

driver: external runs a runtime plugin that speaks Runtime Protocol v1.

agent:
  driver: external
  external:
    binary: RUNTIME_DRIVER
    args: ["serve"]
    imageBackend: docker
  binaries:
    RUNTIME_DRIVER:
      - os: linux
        arch: amd64
        path: https://example.com/runtime-driver
        checksum: "<SHA-256 of the extracted executable>"
  • binary: the exact key in agent.binaries. It is not a path and is never searched on PATH.
  • args: a fixed argument list. No shell or option substitution is applied.
  • imageBackend: docker (default) or none. It picks the Devsy-side image backend, not a build capability in the plugin. With none, prebuild publishing is unavailable.

Each platform needs a SHA-256 checksum, and the runtime must already be in the agent binary directory. Devsy verifies the checksum before every operation and never downloads or removes the file. The plugin is trusted provider code and runs with the same access as Devsy.

On this page