Devsy
Developing in a Workspace

devcontainer.json

Devsy uses the open devcontainer.json standard to define the development container for a project. Because VS Code and GitHub Codespaces use the same format, existing configurations work in Devsy, and the container behaves the same on every provider.

If a project has no configuration, Devsy detects the language and uses a default.

For the full format, see the reference, the VS Code documentation, and the Codespaces documentation.

Where the file lives

Devsy looks for one of:

  • .devcontainer/devcontainer.json
  • .devcontainer.json
  • .devcontainer/<folder>/devcontainer.json

To use a specific file, pass its path:

devsy workspace up github.com/my-org/my-repo --devcontainer-path ./path/to/devcontainer.json

A configuration can inherit from other files with extends, which takes a path or a list of paths. Keep files the configuration depends on inside its folder.

Existing workspaces

Devsy remembers which configuration a workspace uses. If a later search would pick a different file, Devsy warns and keeps the old one. To switch on purpose, recreate the workspace:

devsy workspace up <workspace> --recreate --devcontainer "<relative-path>"
devsy workspace up <workspace> --recreate --devcontainer "id:<name>"

The choice is saved for later runs.

Dockerfile

{
  "build": {
    "dockerfile": "Dockerfile"
  }
}

Docker Compose

Point dockerComposeFile at one or more compose files and choose the service to use as the dev container:

{
  "dockerComposeFile": ["docker-compose.yml", "docker-compose.dev.yml"],
  "service": "backend"
}

Devsy names the compose project the same way Docker Compose does, so it reuses a project that is already running. In order:

  1. COMPOSE_PROJECT_NAME in your shell.
  2. COMPOSE_PROJECT_NAME in an .env file, in the devcontainer folder, the workspace root, or a compose file's folder.
  3. The top-level name: in the compose files. The last file that sets it wins.
  4. A name derived from the workspace.

The name field in devcontainer.json is only a display name and never names the compose project.

A custom DOCKER_HOST set for the Docker provider is passed to the docker compose commands Devsy runs.

Features

Features are reusable pieces that Devsy merges into your Dockerfile, such as docker-in-docker or kubectl.

To send HTTP headers when downloading a feature archive, set them under customizations:

{
  "features": {
    "https://example.com/foo_feature.tar.gz": {}
  },
  "customizations": {
    "devsy": {
      "featureDownloadHTTPHeaders": {
        "FOO_HEADER": "${localEnv:FOO_ENV_VAR}",
        "BAR_HEADER": "bar"
      }
    }
  }
}

Applying changes

After you edit the configuration, apply it without deleting the workspace:

devsy workspace up my-workspace --recreate

This applies all changes, including the Dockerfile, mounts, and features. Devsy replaces the running container only if the rebuild succeeds, so a mistake does not break the existing workspace.

Recreating

Changes outside volumes are lost. The project folder and other mounted paths are kept.

Environment variables in devcontainer.json

When you use ${localEnv:NAME} in devcontainer.json with the SSH provider, the variable has to reach the remote machine.

  1. Reference the variable in devcontainer.json:

    {
      "name": "Node.js",
      "image": "mcr.microsoft.com/devcontainers/javascript-node:${localEnv:IMAGE_VERSION}"
    }
  2. Send it from your local ~/.ssh/config:

    Host <REMOTE-SSH-SERVER>
       SetEnv IMAGE_VERSION=0-18-bullseye
  3. On the remote machine, add AcceptEnv IMAGE_VERSION to /etc/ssh/sshd_config and restart the SSH service.

  4. Start the workspace:

    devsy workspace up <GITHUB-REPOSITORY-URL> --provider ssh --ide=none

On this page