diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/connect-to-a-workspace.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/connect-to-a-workspace.mdx index d65065ada4..afe4241e81 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/connect-to-a-workspace.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/connect-to-a-workspace.mdx @@ -3,125 +3,76 @@ title: Connect to a Workspace sidebar_label: Connect to a Workspace --- -## Connect to a Workspace +Once a workspace is created, it is reachable over SSH at `WORKSPACE_NAME.devsy`. If you chose an IDE, Devsy opens it after the workspace starts. -Once a workspace is created, it is reachable through the SSH host `WORKSPACE_NAME.devsy`. If you chose an IDE, Devsy opens it after the workspace starts. +Pick the IDE with `--ide` when you start a workspace, or set a default for all workspaces: - -Change the default IDE globally with `devsy ide use vscode`, or per workspace with `devsy workspace up my-workspace --ide vscode`. - +```sh +devsy workspace up my-workspace --ide vscode +devsy ide use vscode +``` -### VS Code Browser +Run `devsy ide list` to see every supported IDE. -Devsy can open VS Code in a browser tab. It installs [openvscode-server](https://github.com/gitpod-io/openvscode-server) inside the workspace and tunnels a connection to it from localhost. Open the workspace in VS Code browser with: -``` -devsy workspace up my-workspace --ide openvscode -``` +### VS Code in the browser -To pick a different openvscode version: -``` -devsy workspace up my-workspace --ide openvscode --ide-option VERSION=v1.76.2 +Devsy installs [openvscode-server](https://github.com/gitpod-io/openvscode-server) in the workspace and tunnels to it from localhost. + +```sh +devsy workspace up my-workspace --ide openvscode ``` ### VS Code -Install the [remote ssh extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) and the [code CLI](https://code.visualstudio.com/docs/editor/command-line). Then start the workspace in VS Code with: -``` +Install the [Remote - SSH extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) and the [code CLI](https://code.visualstudio.com/docs/editor/command-line), then: + +```sh devsy workspace up my-workspace --ide vscode ``` - -If this doesn't work, use the regular SSH connection `WORKSPACE_NAME.devsy` to connect VS Code. - +If that fails, connect VS Code to `WORKSPACE_NAME.devsy` over SSH. -### JetBrains Suite (Goland, PyCharm, Intellij etc.) +### JetBrains IDEs -Install [JetBrains Gateway](https://www.jetbrains.com/remote-development/gateway/) and have a valid JetBrains subscription for your local IDE. Supported JetBrains IDEs: -* **CLion (clion)** -* **Goland (goland)** -* **PyCharm (pycharm)** -* **Intellij (intellij)** -* **PhpStorm (phpstorm)** -* **WebStorm (webstorm)** -* **Rider (rider)** -* **RubyMine (rubymine)** +Install [JetBrains Gateway](https://www.jetbrains.com/remote-development/gateway/). You need a license for the IDE you use. Start the workspace with the IDE name, for example: -Start your workspace with: -``` +```sh devsy workspace up my-workspace --ide goland ``` -Devsy installs the GoLand server binary into the workspace and opens JetBrains Gateway. After installation, the Gateway SSH dialog appears pre-filled - click **Check Connection and Continue** to start the IDE inside the workspace. - -To pick a different IDE version: -``` -devsy workspace up my-workspace --ide goland --ide-option VERSION=2022.3.3 -``` +Devsy installs the IDE server in the workspace and opens Gateway. Click **Check Connection and Continue** in the prefilled SSH dialog. If that fails, connect Gateway to `WORKSPACE_NAME.devsy` over SSH. - -If this doesn't work, use the SSH host `WORKSPACE_NAME.devsy` to connect your JetBrains IDE. - - - -Fleet only works by manually adding an SSH connection to `WORKSPACE_NAME.devsy`. - +Fleet works only through a manually added SSH connection to `WORKSPACE_NAME.devsy`. ### SSH -When a workspace is created, Devsy adds an entry for `WORKSPACE_NAME.devsy` to `~/.ssh/config`. Connect with: -``` +Devsy adds a `WORKSPACE_NAME.devsy` entry to `~/.ssh/config` when it creates a workspace. + +```sh ssh WORKSPACE_NAME.devsy ``` -Any IDE that supports remote development over SSH can also use this host. - -### Devsy CLI +Any IDE with remote SSH support can use this host. Without an `ssh` client, use the CLI: -If you don't have `ssh` installed or can't connect through an IDE, use the Devsy CLI: -``` +```sh devsy workspace ssh my-workspace -``` - -Run a command non-interactively: -``` devsy workspace ssh my-workspace --command "echo Hello World" ``` -## IDE Commands - -Configure how Devsy opens workspaces with these commands. +## IDE options -### Configure IDE Options +Each IDE has options such as the version. List and change them with: -Each IDE supports options like version and download path. List them with: -``` +```sh devsy ide get openvscode -``` - -Change an option with: -``` devsy ide set openvscode -o VERSION=v1.76.2 ``` -### Change Default IDE - -Set the default IDE Devsy uses to open workspaces: -``` -devsy ide use vscode -``` - -### List supported IDEs - -List every IDE Devsy supports: -``` -devsy ide list -``` +You can also set an option for a single workspace with `--ide-option VERSION=...` on `devsy workspace up`. ## Desktop shortcuts -Devsy Desktop ships a command palette and section shortcuts for fast navigation: - -- `Cmd/Ctrl + K` - open the command palette (search workspaces, providers, machines, and pages). -- `Cmd/Ctrl + N` - start the New Workspace wizard. -- `Cmd/Ctrl + 1` through `Cmd/Ctrl + 8` - jump to Dashboard, Workspaces, Providers, Machines, Contexts, Terminals, SSH Keys, and Settings. -- `Esc` - close the active sheet, dialog, or palette (where supported). +- `Cmd/Ctrl + K` opens the command palette. +- `Cmd/Ctrl + N` starts the New Workspace wizard. +- `Cmd/Ctrl + 1` to `8` jumps between the main sections. +- `Esc` closes the open sheet, dialog, or palette. diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/continuous-integration.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/continuous-integration.mdx index 6021805201..afaca3facc 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/continuous-integration.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/continuous-integration.mdx @@ -3,13 +3,9 @@ title: Continuous Integration sidebar_label: Continuous Integration --- -## Continuous Integration +`devsy ci` builds an ephemeral devcontainer, runs a command in it, and deletes the workspace afterwards. Use it to check that your `devcontainer.json` still builds and your tests pass inside it. -`devsy ci` builds an ephemeral devcontainer, runs a command inside it, and tears -the workspace down afterwards. It lets you verify that your `devcontainer.json` -still builds. - -### How it works +## How it works 1. Resolves a workspace from the current directory (or a given source). 2. Builds and starts the devcontainer (equivalent to `devsy workspace up`, without @@ -21,7 +17,7 @@ still builds. A non-zero exit from the command propagates as the exit code of `devsy ci`, so a failing test or build fails the CI job. -### Usage +## Usage ```sh devsy ci [flags] [workspace-path|workspace-name] -- [args...] @@ -54,27 +50,16 @@ devsy ci --keep -- ./run-integration-tests.sh ### Common flags -| Flag | Description | -| --- | --- | -| `--run-cmd` | Shell command run inside the container via `sh -c` (alternative to an explicit argv after `--`). | -| `--remote-env KEY=VALUE` | Set an environment variable in the container at run time. Repeatable. | -| `--keep` | Keep the workspace instead of tearing it down. | -| `--devcontainer` | Select the devcontainer config source: `none`, `image:`, `id:`, or a path to a `devcontainer.json`. | -| `--no-cache` | Build without using the cache. | -| `--cache-from` | Reuse a pre-built image as a build cache source. Repeatable. | -| `--platform` | Run the container under a specific platform via emulation (e.g. `linux/amd64`). | -| `--workspace-env KEY=VALUE` | Env variables available at build and lifecycle time (not just at run time). Repeatable. | -| `--workspace-env-file` | File(s) of `KEY=VALUE` build/lifecycle env variables. | -| `--init-env KEY=VALUE` | Env variables injected during workspace initialization. Repeatable. | -| `--secrets-file` | JSON file (`{"KEY":"value"}`) of secrets injected into lifecycle commands. | -| `--feature-secrets-file` | JSON file of secret values for features. | -| `--secret` | Stored Devsy secret to inject, as `NAME[,type=env\|mount][,target=X]`. Repeatable. | -| `--env` | Stored Devsy env var to inject, as `NAME[=TARGET]`. Repeatable. | -| `--build-secret` | Stored Devsy secret exposed to the build via BuildKit. Repeatable. | -| `--git-token` | Stored Devsy secret with an access token for cloning a private HTTP repository. | -| `--git-token-username` | Username for `--git-token` (default inferred from the repo host). | - -### Pre-building and pushing images +Run `devsy ci --help` for the full list. The most used: + +- `--keep` keeps the workspace instead of deleting it. +- `--remote-env KEY=VALUE` sets an environment variable in the container at run time. Repeatable. +- `--devcontainer` picks the config: `none`, `image:`, `id:`, or a path to a `devcontainer.json`. +- `--cache-from` and `--no-cache` control the image build cache. +- `--platform` runs the container under another platform, such as `linux/amd64`. +- `--secret`, `--env`, `--build-secret`, and `--git-token` inject stored Devsy secrets and variables. See [Secrets](./secrets.mdx). + +## Pre-building and pushing images `devsy ci` focuses on running a command. To pre-build and publish a devcontainer image for reuse as a build cache, use `devsy workspace build`: @@ -86,7 +71,7 @@ devsy workspace build --repository ghcr.io/my-org/my-devcontainer --tag latest - Downstream CI jobs can then reference that image via `--cache-from` to speed up builds. -### GitHub Actions +## GitHub Actions Install the CLI, configure the docker provider, then run `devsy ci`: diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/create-a-workspace.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/create-a-workspace.mdx index 117cec0862..afe852549f 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/create-a-workspace.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/create-a-workspace.mdx @@ -3,223 +3,127 @@ title: Create a Workspace sidebar_label: Create a Workspace --- -A workspace in Devsy is a containerized development environment that holds a project's source code along with the dependencies needed to work on it, such as a compiler and debugger. The underlying environment where the container runs is created and managed through a Devsy provider. This gives every engineer a consistent development experience wherever the container runs - a remote machine in a public cloud, localhost, or a Kubernetes cluster. +A workspace is a containerized development environment that holds a project's source and the tools needed to work on it. A [provider](../managing-providers/what-are-providers.mdx) creates the environment it runs in. -To configure the development container, Devsy reuses the [devcontainer.json](https://containers.dev/) specification, which is also used by other popular tools such as [VS Code dev containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces). This means any project that already uses this configuration can spin up a workspace in Devsy with no extra setup. If no configuration is found, Devsy detects the project's programming language and provides an appropriate template. +Devsy uses the [devcontainer.json](https://containers.dev/) specification, which VS Code dev containers and GitHub Codespaces also use, so a project that already has one needs no extra setup. If there is none, Devsy detects the project's language and offers a template. -A workspace can be stopped and restarted without losing its state, so you can install additional programs or change configuration without reconfiguring the container. Depending on the provider, Devsy also detects when a workspace is no longer in use and shuts down idle resources to keep infrastructure costs down. +A workspace keeps its state when you stop and restart it. Once it exists, it is reachable over SSH at `WORKSPACE_NAME.devsy`, and Devsy can open it in a local IDE. -## Create a Workspace +## Create a workspace -Create workspaces from the Devsy CLI or the Desktop app. A workspace's source can be a Git repository, a local path, or a Docker image (e.g. `golang:latest`). - -Once created, the workspace is reachable through the SSH host `WORKSPACE_NAME.devsy`, or Devsy can open it in a local IDE like VS Code or IntelliJ. - - -A workspace is defined by a `devcontainer.json`. If none exists, Devsy detects the project's language and picks a matching template. - +The source can be a Git repository, a local folder, or an image such as `golang:latest`. ### Devsy Desktop -Open the Workspaces view and click **Create** to launch the wizard. It walks through five steps: - -1. **Provider** - pick an initialized provider. Cannot be changed later. If none exists, the wizard offers to add one. -2. **Source** - choose a Quick Start template, browse the image catalog, or enter a custom Git URL / image / local path. **Show advanced options** reveals: - - Ref Type and value (branch, commit, or PR number) for Git sources. - - Project subfolder within the repo. - - Open folder in container (where the editor opens). - - Dev container config path (override `.devcontainer/devcontainer.json` location). - - Prebuild repository for cached images. -3. **IDE** - pick one or more IDEs to open the workspace with. Optional; defaults to none. -4. **Review** - adjust the auto-derived workspace name and confirm the configuration. If the chosen image has no build for your machine architecture, the Review step shows a compatibility warning and a **Run under emulation** toggle. -5. **Launch** - Devsy creates the workspace and streams progress. A 10-minute watchdog cancels the launch if it stalls. The chosen IDE opens on success. - - -Under the hood, the Desktop Application will call the CLI command `devsy workspace up REPOSITORY` - - - -You can set the location of your devsy home by passing the `--home={home_path}` flag, -or by setting the env var `DEVSY_HOME` to your desired home directory. +Open **Workspaces** and click **Create**. The wizard has five steps: -This can be useful if you are having trouble with a workspace trying to mount to a windows location when it should be mounting to a path inside the WSL VM. +1. **Provider.** Pick an initialized provider. You cannot change it later. +2. **Source.** Pick a template or an image, or enter a Git URL, image, or local path. **Show advanced options** lets you set the branch, commit, or PR, a project subfolder, the folder to open, the `devcontainer.json` path, and a prebuild repository. +3. **IDE.** Optional. The default is none. +4. **Review.** Check the workspace name and configuration. If the image has no build for your architecture, you can turn on **Run under emulation**. +5. **Launch.** Devsy creates the workspace and streams progress, then opens your IDE. -For example: setting `--home=/mnt/c/Users/MyUser/` will result in a workspace path of something like `/mnt/c/Users/MyUser/.devsy/contexts/default/workspaces/...` - +The desktop app runs `devsy workspace up` for you. ### Devsy CLI -[Install the Devsy CLI](../getting-started/install.mdx#install-devsy-cli) and add a provider to host the workspace (such as local docker): -``` -# Add a provider if you haven't already +[Install the CLI](../getting-started/install.mdx#install-devsy-cli) and add a provider, for example Docker: + +```sh devsy provider add docker ``` -#### Git Repository - -Start a new workspace from a Git repository: +**Git repository** -``` -# Create from Git repository +```sh devsy workspace up github.com/microsoft/vscode-remote-try-node ``` -Append a commit hash, branch, or pull request slug to the URL to check out a specific ref: -``` -Branch: devsy workspace up github.com/microsoft/vscode-remote-try-node@main -Commit: devsy workspace up github.com/microsoft/vscode-remote-try-node@sha256:15ba80171af11374143288fd3d54898860107323 -PR: devsy workspace up github.com/microsoft/vscode-remote-try-node@pull/108/head # Only works for GitHub! -``` - - -Devsy forwards your git credentials to the remote machine so private repositories work too. - - - -Pass `--id` to override the workspace name. This lets you spin up multiple workspaces from one repository. - +Add `@` and a ref to pick a branch, commit, or pull request: +```sh +devsy workspace up github.com/microsoft/vscode-remote-try-node@main +devsy workspace up github.com/microsoft/vscode-remote-try-node@sha256:15ba80171af11374143288fd3d54898860107323 +devsy workspace up github.com/microsoft/vscode-remote-try-node@pull/108/head # GitHub only +``` -#### Local Path +Devsy forwards your git credentials, so private repositories work. Use `--id` to name the workspace, which lets you create several from one repository. -Create a workspace from a local folder: +**Local folder** -``` -# Create from a local path +```sh devsy workspace up ./path/to/my-folder ``` -Devsy syncs the folder onto the remote machine and builds the dev environment from the `devcontainer.json`. - -### Control local-folder uploads with `.devsyignore` - -Place `.devsyignore` at the root of your local workspace source to choose which -files Devsy uploads when a provider streams the folder, including Kubernetes. -The CLI and Desktop use the same transfer policy. For example: - -```text -big/ -**/node_modules/ -docs/*.tgz -build/ -!build/keep.txt -``` +Devsy copies the folder to the provider and builds from its `devcontainer.json`. See [.devsyignore](#devsyignore) to leave files out. -Rules use [Docker ignore syntax](https://docs.docker.com/build/concepts/context/#dockerignore-files), -including `*`, `?`, character classes, `**`, and ordered `!` exceptions. Paths -are relative to the workspace source root; the last matching rule wins. -`build/` excludes `build` and its descendants while retaining `buildSrc`. -`docs/*.tgz` excludes archives directly inside `docs`, while `**/node_modules/` -excludes dependency folders at any depth. A rule can exclude `.devsyignore` itself. - -A missing ignore file permits the entire source to upload. An empty file is valid. -An existing file that cannot be read or contains an invalid pattern stops the -upload before any archive data is sent. Correct the file identified in the error -and retry. This replaces the previous silent, unfiltered fallback. Debug logs -identify the ignore file and rule count without listing the rules. - -Workspace rules do not filter additional configured bind mounts, even when they -refer to the same source directory at a different container target. Configure -those mounts deliberately: `.devsyignore` does not prevent their contents from -being transferred. Local Docker bind mounts expose the host folder directly and -do not remove ignored files. Remote Git clones also do not use this upload policy. -`.gitignore` and `.dockerignore` are not substituted for `.devsyignore`; Docker -image builds continue to use their own build-context rules. - -Devsy preserves only verified artifacts generated for the current Dockerless build, -including files inside a nested build context, when they are needed for startup. -Other folders named `.devsy-internal` remain subject to the rules. A required -generated context outside the authorized workspace source produces an error. - -For a workspace with a large `big/blob.bin`, dependency folders, and packaged -archives, the example rules avoid transferring those files and reduce remote -disk usage. The reduction depends on your source contents, rather than a fixed -upload duration. [Workspace snapshots](./workspace-snapshots.mdx) also distinguish -the workspace volume from independent bind mounts. - -#### Docker Image - -Create a workspace from a Docker image: +**Image** -``` -# Create from a docker image +```sh devsy workspace up ghcr.io/my-org/my-repo:latest ``` -Devsy generates the following `.devcontainer.json`: -``` -{ - "image": "ghcr.io/my-org/my-repo:latest" -} -``` +Devsy generates a `devcontainer.json` that names the image. To run an image built for another architecture, add `--platform linux/amd64`. Emulation can be much slower, so prefer multi-arch images. -##### Run under a different platform +The desktop app also has a catalog of ready-made images and flags any that do not fit your machine. -Pass `--platform` to run the container under a non-native architecture (via QEMU emulation on Docker). This is useful for images that only ship `linux/amd64` when you're on Apple Silicon. +**Existing container** -``` -devsy workspace up ghcr.io/my-org/my-repo:latest --platform linux/amd64 +```sh +devsy workspace up my-workspace --source container:$CONTAINER_ID ``` - -Emulated containers can be significantly slower than native ones. Prefer multi-arch images when available. - +Only the `docker` provider supports this, and `--recreate` is rejected for these workspaces. -##### Image catalog (Desktop) + +To change where Devsy keeps its data, pass `--home=PATH` or set `DEVSY_HOME`. This helps on WSL when a workspace tries to mount a Windows path instead of a path inside WSL. + -Devsy Desktop ships a curated catalog of pre-built devcontainer images. The Source step of the workspace wizard surfaces them in an image picker and flags incompatible images (e.g. an `arm64`-only image on an `amd64` host). The CLI accepts any of these images as a `--source` or positional argument. +## .devsyignore -#### Existing local container +Put a `.devsyignore` file in the root of a local workspace folder to leave files out of the upload when the provider streams the folder, as Kubernetes does. It uses [Docker ignore syntax](https://docs.docker.com/build/concepts/context/#dockerignore-files). Paths are relative to the folder, and the last matching rule wins. -Bind a workspace to a container that is already running: -``` -devsy workspace up my-workspace --source container:$CONTAINER_ID +```text +big/ +**/node_modules/ +docs/*.tgz +build/ +!build/keep.txt ``` -Only the `docker` provider supports this. - - -`--recreate` is rejected on a workspace backed by an existing container. - +- A missing or empty file uploads everything. +- An unreadable file or an invalid pattern stops the upload with an error that names the file. +- It does not apply to extra bind mounts, to local Docker bind mounts, to remote Git clones, or to image builds, which use their own rules. `.gitignore` and `.dockerignore` are not used in its place. ## Inspect a workspace -`devsy workspace describe ` prints a workspace's full configuration plus its live state. By default it renders a `Field | Value` table; pass `--result-format json` for machine-readable output (Devsy Desktop uses the JSON form). - ```sh devsy workspace describe my-workspace -devsy workspace describe my-workspace --result-format json ``` -Other useful inspection commands: - -- `devsy workspace status ` - quick state check (`Running`, `Stopped`, `NotFound`). -- `devsy workspace logs ` - stream the agent logs from the container. -- `devsy workspace ping ` - verify the agent is reachable through the tunnel. -- `devsy workspace troubleshoot ` - bundle diagnostics for issue reports. +This prints the configuration and live state. Add `--result-format json` for scripts. Other commands: -## Recreating a workspace +- `devsy workspace status ` shows whether it is running or stopped. +- `devsy workspace logs ` streams the agent logs. +- `devsy workspace ping ` checks that the agent is reachable. +- `devsy workspace troubleshoot ` bundles diagnostics for an issue report. -Recreating a workspace re-applies changes from the `devcontainer.json` or its `Dockerfile`. Use this after editing the devcontainer or pulling new changes that affect the dev environment. If a prebuild repository is configured, Devsy looks for the updated image there first and falls back to building locally. +## Recreate a workspace -Only changes inside the project path or mounted volumes survive a recreate. **Everything else in the container is lost.** - -### Devsy CLI +Recreating applies changes to `devcontainer.json` or its Dockerfile. If a prebuild repository is configured, Devsy looks there for the new image first. -Rebuild an existing workspace: -``` +```sh devsy workspace up my-workspace --recreate ``` -## Resetting a workspace + +Only the project folder and mounted volumes survive. Everything else in the container is lost. + -Reset rebuilds the workspace from a clean slate - it pulls the latest Git changes or re-uploads your local folder. Use it instead of `--recreate` when you need a full restart. +## Reset a workspace -**A reset preserves nothing.** +A reset starts from a clean slate. It pulls the latest Git changes or uploads your local folder again, and it keeps nothing. -### Devsy CLI - -Reset an existing workspace: -``` +```sh devsy workspace up my-workspace --reset ``` diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/credentials.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/credentials.mdx index 0fac1b0ac2..be2bb07a96 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/credentials.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/credentials.mdx @@ -3,45 +3,40 @@ title: Reuse local credentials sidebar_label: Reuse local credentials --- -Devsy will automatically make certain local credentials available inside of the development container through a [credentials helper](https://git-scm.com/docs/gitcredentials). -This allows you to reuse existing local credentials in a safe manner within the development container without explicitly configuring them inside each workspace. -Currently Devsy supports this feature for git credentials and docker credentials. +Devsy makes some of your local credentials available inside the dev container, so you do not configure them in each workspace. It supports git credentials, Docker registry credentials, and GPG keys. - -Do not enable credential injection or SSH agent forwarding for untrusted repositories, or for any `devcontainer.json` you have not reviewed. Anything that runs inside the container - including lifecycle commands and features defined in `devcontainer.json` - can use the forwarded credentials. + +Code that runs in the container, including lifecycle commands and features from `devcontainer.json`, can use these credentials. Do not enable them for repositories or `devcontainer.json` files you have not reviewed. -SSH agent forwarding never exposes your private key to the container, but it is not a full sandbox boundary: anyone with access to the forwarded agent socket inside the container can request signatures, and therefore authenticate as you against any remote service the key is trusted by, for as long as the workspace runs. A malicious or compromised `devcontainer.json` can use this to push, pull, or otherwise act with your identity, even though it can never exfiltrate the key itself. The same caution applies to injected git/docker credentials: they let code in the container act with your access. +SSH agent forwarding never exposes your private key. It does let anything in the container request signatures, and so act as you against any service the key can access, for as long as the workspace runs. -## Git credentials +## Git -Devsy will make https credentials available inside the dev container through a [git credentials helper](https://git-scm.com/docs/gitcredentials). ssh credentials are available through agent-forwarding that will be configured automatically on the ssh configuration for the workspace. +Devsy provides HTTPS credentials through a [git credential helper](https://git-scm.com/docs/gitcredentials). SSH credentials work through agent forwarding, which Devsy sets up in the workspace's SSH config. To turn injection off for all workspaces: -If you don't want Devsy to inject the credentials, you can disable that via the following command for all workspaces: -``` +```sh devsy context set default -o SSH_INJECT_GIT_CREDENTIALS=false ``` -## Docker credentials +## Docker -Devsy will make docker registry credentials available inside the dev container through a [docker credentials helper](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers). This allows you to pull and push images from and to private registries from within the dev container. +Devsy provides registry credentials through a [Docker credential helper](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers), so you can pull and push private images from the container. To turn it off for all workspaces: -If you don't want Devsy to inject the credentials, you can disable that via the following command for all workspaces: -``` +```sh devsy context set default -o SSH_INJECT_DOCKER_CREDENTIALS=false ``` -## GPG credentials +## GPG -Devsy will make gpg keys available inside the dev container through an ssh tunnel. This allows you to sign commits from inside the workspace. +Devsy can forward your GPG keys into the container over the SSH tunnel, so you can sign commits there. To turn it on for all workspaces: -To have Devsy inject the gpg keys, enable it via the following command for all workspaces: -``` +```sh devsy context set default -o GPG_AGENT_FORWARDING=true ``` -Or when creating a workspace using: +Or for one workspace: -``` +```sh devsy workspace up --ssh-gpg-forwarding my-workspace ``` diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/devcontainer-json.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/devcontainer-json.mdx index b43eeff9a2..4d296f6d73 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/devcontainer-json.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/devcontainer-json.mdx @@ -3,77 +3,52 @@ title: devcontainer.json sidebar_label: devcontainer.json --- -Devsy uses the [open `devcontainer.json` standard](https://containers.dev/) to allow users to customize their development containers. -Development containers are Docker containers that provide a user with a fully featured development environment. -Within Devsy, this container is created based on the underlying provider either locally, in a remote virtual machine or even in a Kubernetes cluster. -Devsy makes sure that no matter where you use this configuration the developer experience stays the same. - -You can configure this development container for a certain Git repository so that each workspace gives you a custom development environment -completely configured with the tooling and runtimes you need for working on that specific project. -If Devsy doesn't find any configuration for the project it will automatically detect the programming language and provide a sane default configuration. - - -The same format is used by VS Code for their development containers and by GitHub for their Codespaces. -This makes it easy to reuse existing configurations and tooling around this standard within Devsy. - +Devsy uses the [open `devcontainer.json` standard](https://containers.dev/) 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. - -This page introduces working with devcontainers. For more detail, see: -* [DevContainer Reference](https://containers.dev/implementors/json_reference/) -* [VS Code DevContainer Documentation](https://code.visualstudio.com/docs/devcontainers/create-dev-container) -* [GitHub Codespaces Documentation](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers#devcontainerjson) - +If a project has no configuration, Devsy detects the language and uses a default. -## devcontainer.json +For the full format, see the [reference](https://containers.dev/implementors/json_reference/), the [VS Code documentation](https://code.visualstudio.com/docs/devcontainers/create-dev-container), and the [Codespaces documentation](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers#devcontainerjson). -The primary file to configure your workspace is the `devcontainer.json`, that lives in the `.devcontainer` sub-folder of your project. -This file includes information on what frameworks, tools, VS Code extensions and port-forwarding should be used during development. -The file also usually references a Dockerfile or a Docker image to use as the base for the development environment. -If Devsy doesn't find any configuration for the project, it will automatically detect the programming language and provide a sane default configuration. +## Where the file lives -The `devcontainer.json` can be located at the following places within your project: -* `.devcontainer/devcontainer.json` -* `.devcontainer.json` -* `.devcontainer/my-other-folder/devcontainer.json` +Devsy looks for one of: -You can specify a specific file to use via the `--devcontainer-path` CLI flag: -``` -devsy workspace up github.com/my-org/my-repo --devcontainer-path ./my-git-path-to/a-devcontainer-json-file.json -``` +- `.devcontainer/devcontainer.json` +- `.devcontainer.json` +- `.devcontainer//devcontainer.json` -### Existing workspace selection +To use a specific file, pass its path: -Devsy remembers the effective devcontainer configuration for an existing workspace so that restart and other lifecycle operations keep the same environment. If fresh project discovery later prefers a different config, a legacy workspace warns about the selection drift and continues using its previously resolved config. Devsy does not switch the workspace implicitly. +```sh +devsy workspace up github.com/my-org/my-repo --devcontainer-path ./path/to/devcontainer.json +``` -To adopt another config intentionally, run `devsy workspace up --recreate --devcontainer ""` or select a named profile with `--recreate --devcontainer "id:"`. The choice is persisted for subsequent lifecycle operations. +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. -A `devcontainer.json` is not able to import or inherit any settings from other `devcontainer.json` files, so make sure all dependent files and folders are available within the configuration subdirectory. +### Existing workspaces -### Using a Dockerfile +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: -In order to use a Dockerfile for your configuration, you can specify the following within your `devcontainer.json`: +```sh +devsy workspace up --recreate --devcontainer "" +devsy workspace up --recreate --devcontainer "id:" ``` + +The choice is saved for later runs. + +## Dockerfile + +```json { "build": { "dockerfile": "Dockerfile" - }, - ... + } } ``` -And the Dockerfile could look like this: -``` -FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16-buster - -# Install extra tooling into the environment via the following command -RUN apt-get update && apt-get install vim -``` - -For more information about how to write Dockerfiles, please visit the [official documentation](https://docs.docker.com/engine/reference/builder/) - -### Using Docker Compose +## Docker Compose -To use Docker Compose for your configuration, reference one or more compose files via `dockerComposeFile` and pick the service Devsy should treat as the dev container: +Point `dockerComposeFile` at one or more compose files and choose the service to use as the dev container: ```json { @@ -82,33 +57,22 @@ To use Docker Compose for your configuration, reference one or more compose file } ``` -#### Compose project name +Devsy names the compose project the same way Docker Compose does, so it reuses a project that is already running. In order: -Devsy resolves the Docker Compose project name using the same precedence Docker Compose itself uses, so `devsy workspace up` reuses an already-running compose project instead of spawning a separate one: +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. -1. `COMPOSE_PROJECT_NAME` set in the current shell session. -2. `COMPOSE_PROJECT_NAME` from an `.env` file - checked in the devcontainer config directory (e.g. `.devcontainer/.env`), the workspace root, and each resolved compose file's own directory. -3. The top-level `name:` field in the compose files (when multiple files are given, the last one that declares it wins). -4. Otherwise, a name derived from the workspace, sanitized for Docker Compose. +The `name` field in `devcontainer.json` is only a display name and never names the compose project. - -`devcontainer.json`'s `name` field is a display name for the UI (per the [Dev Containers spec](https://containers.dev/implementors/json_reference/#general-fields)) and is never used to name the Docker Compose project. To reuse an existing compose project, set `COMPOSE_PROJECT_NAME` (shell or `.env`) or a top-level `name:` in your compose file - the same options [VS Code documents](https://code.visualstudio.com/remote/advancedcontainers/set-docker-compose-project-name) for this purpose. - - - -When using a `docker-compose.yml`-based `devcontainer.json` (via `dockerComposeFile`), a `platform` pin set on the compose service (or under `build.platforms`) is correctly honored during the build, including on arch-restricted base images. - +A custom `DOCKER_HOST` set for the Docker provider is passed to the `docker compose` commands Devsy runs. -### Add Additional DevContainer Features +## Features -`devcontainer.json` allows you to reuse certain predefined features within your configuration. -You can think of features as reusable Dockerfile parts that will be merged into your Dockerfile upon creation. -This makes it easy to reuse functionality such as `docker-in-docker` or install extra tooling such as `node` or `kubectl` without having to look up the exact Dockerfile commands. -A list of available features can be found [here](https://containers.dev/features). +[Features](https://containers.dev/features) are reusable pieces that Devsy merges into your Dockerfile, such as `docker-in-docker` or `kubectl`. -Devsy is able to add HTTP headers when downloading -feature archives as tar.gz files. To do so, add the needed headers in the `customizations` -field of the `devcontainer.json` file as follows: +To send HTTP headers when downloading a feature archive, set them under `customizations`: ```json { @@ -126,58 +90,44 @@ field of the `devcontainer.json` file as follows: } ``` -## devcontainer.json Development Flow +## Applying changes + +After you edit the configuration, apply it without deleting the workspace: -When working on the `devcontainer.json` itself, it's important to understand when Devsy will apply new configuration. +```sh +devsy workspace up my-workspace --recreate +``` -A naive approach would be to delete and recreate a workspace after each `devcontainer.json` change (which obviously works), but Devsy allows you to make changes to the configuration on the fly and reapply them via `devsy workspace up my-workspace --recreate`. -This will apply **ALL** new configurations including Dockerfile changes as well as new mounts, new features or any other configuration that is not included in the above command. Devsy will only replace the existing running container if the command has succeeded, so if there is a mistake in the new configuration, the existing workspace should not be impacted. +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. - -Changes in the overlay layer of the container, which means all changes to non-volumes will be lost. Changes within the project path and all other mounted paths will be preserved. + +Changes outside volumes are lost. The project folder and other mounted paths are kept. -## Environment Variables in devcontainer.json +## Environment variables in devcontainer.json -If you're combining SSH provider with using environment variables in your `.devcontainer.json`, -please follow the steps below to make sure that your environment variables are properly set on the remote machine. +When you use `${localEnv:NAME}` in `devcontainer.json` with the SSH provider, the variable has to reach the remote machine. -### Steps +1. Reference the variable in `devcontainer.json`: -1. Prepare a `.devcontainer.json` to include `${localEnv:}` directive.
- Example `.devcontainer.json`: -```json -{ - "name": "Node.js", - "image": "mcr.microsoft.com/devcontainers/javascript-node:${localEnv:IMAGE_VERSION}" -} -``` + ```json + { + "name": "Node.js", + "image": "mcr.microsoft.com/devcontainers/javascript-node:${localEnv:IMAGE_VERSION}" + } + ``` -2. Prepare an entry in a local `.ssh/config` to include `SetEnv =` directive.
- Example `.ssh/config`: -```console -Host - SetEnv IMAGE_VERSION=0-18-bullseye -``` +2. Send it from your local `~/.ssh/config`: -3. Log to your remote machine and in the `/etc/ssh/sshd_config` add an entry `AcceptEnv `.
- For example: -```console -AcceptEnv IMAGE_VERSION -``` + ``` + Host + SetEnv IMAGE_VERSION=0-18-bullseye + ``` -4. Restart SSH service on your remote machine.
-For example on Debian Linux: -```console -systemctl restart ssh.service -``` +3. On the remote machine, add `AcceptEnv IMAGE_VERSION` to `/etc/ssh/sshd_config` and restart the SSH service. -5. Run a `devsy workspace up` command, specifying the SSH provider: +4. Start the workspace: -```console -devsy workspace up --provider ssh --ide=none -``` - - -If your Docker provider is configured with a custom `DOCKER_HOST` (or other Docker environment variables), that environment is forwarded into the `docker compose` commands Devsy runs for a `dockerComposeFile`-based `devcontainer.json`, so the build and run steps consistently hit the same daemon as your other Docker commands. - + ```sh + devsy workspace up --provider ssh --ide=none + ``` diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/dotfiles-in-a-workspace.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/dotfiles-in-a-workspace.mdx index df13d62744..aa30646a8f 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/dotfiles-in-a-workspace.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/dotfiles-in-a-workspace.mdx @@ -3,60 +3,32 @@ title: Dotfiles in a Workspace sidebar_label: Dotfiles in a Workspace --- -## Personalizing a Workspace +Devsy can clone your dotfiles repository into a workspace and install it, so your shell and tool settings are there every time. -You can personalize your workspace environment by using a `dotfiles` repository. +Pass the repository with `--dotfiles`: -Dotfiles are plain text configuration files on Unix like systems (e.g. MacOS, Linux, BSD). -Dotfiles store settings of almost every application, service and tool running on your system. -It is common practice to track dotfiles with a version control system such as Git -to keep track of changes and synchronize dotfiles across various hosts. - -You can use the `--dotfiles` flag when creating a workspace, so that Devsy will -automatically clone and install your dotfiles in the workspace. - -If you only specify the dotfiles repo, Devsy will clone your selected dotfiles -repository into the workspace, and will look into one of these locations to find -a script to setup the environment. - -- install.sh -- install -- bootstrap.sh -- bootstrap -- script/bootstrap -- setup.sh -- setup -- setup/setup - -If none of the previous locations are found, Devsy will just link every hidden file (files starting with `.`) -in the `$HOME` directory of the container. - -It is possible to specify **custom install script locations** for your special setup. -If a custom install script is specified, Devsy will directly run that one instead. +```sh +devsy workspace up https://github.com/example/repo --dotfiles https://github.com/my-user/my-dotfiles-repo +``` -### Devsy CLI +Devsy then looks in the repository for one of these install scripts and runs the first it finds: -Run the following command to start a workspace with a dotfiles repo: +- `install.sh`, `install` +- `bootstrap.sh`, `bootstrap`, `script/bootstrap` +- `setup.sh`, `setup`, `setup/setup` -``` -devsy workspace up https://github.com/example/repo --dotfiles https://github.com/my-user/my-dotfiles-repo -``` +If there is none, Devsy links every hidden file (names starting with `.`) into the container's `$HOME`. -Specifying a custom install script: +To run a different script, name it: -``` +```sh devsy workspace up https://github.com/example/repo --dotfiles https://github.com/my-user/my-dotfiles-repo --dotfiles-script custom/location/install.sh ``` -#### For all Workspaces +## For all workspaces -You can setup these options on a **context wide scope** so that you won't have to specify -`dotfiles` and `dotfiles-script` for each single workspace: +Set the options on the context so every new workspace uses them: -Example with a real repository: - -``` -devsy context set -o DOTFILES_URL=https://github.com/89luca89/dotfiles -o DOTFILES_SCRIPT=bin/.local/bin/dotfiles +```sh +devsy context set -o DOTFILES_URL=https://github.com/my-user/my-dotfiles-repo -o DOTFILES_SCRIPT=bin/install.sh ``` - -All new Workspaces will be created with that dotfile repository and install script. diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/inactivity-timeout.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/inactivity-timeout.mdx index 3eed1756eb..1956282a58 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/inactivity-timeout.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/inactivity-timeout.mdx @@ -3,37 +3,20 @@ title: Auto-Inactivity Timeout sidebar_label: Auto-Inactivity Timeout --- -By default, most providers are able to automatically shutdown unused workspaces to save costs. For example, for cloud providers such as AWS, Azure and Google Cloud, Devsy will automatically stop the machine to save costs when workspaces are not used. +Providers can stop workspaces that nobody is using, which saves cost. A machine stopped this way keeps its data, and Devsy restarts it when you start the workspace again. -Machines stopped this way preserve the data and state, so when a workspace [is started again](./connect-to-a-workspace.mdx), Devsy will simply restart the machine and the workspace. +## Configure the timeout - -All official Devsy providers offer this pre-configured to 5-10 minutes. Check the provider options to see how to change the timeout. - - -## Configuring the timeout - -Changing the default setting for inactivity timeout can be done by [configuring the provider options](../managing-providers/manage-providers.mdx#set-provider-options). Typically there is an option called `INACTIVITY_TIMEOUT` that controls this behaviour. - - -More info about the provider's auto-shutdown can be found in the [agent's development guide](../developing-providers/agent.mdx#machine-providers) -That will explain how this is done and what can be configured. - - -## How does it work? +Each provider has an `INACTIVITY_TIMEOUT` option, for example `30m`. See [Set provider options](../managing-providers/manage-providers.mdx#set-provider-options). The provider's options show its default. -### Non-Machine Providers +## How it works -For non-machine providers, Devsy can automatically kill the container it's running in by terminating the process with pid 1. This is useful for providers such as docker, podman, kubernetes or ssh, where you don't want the container to be running if it's not needed. If configured on the provider, Devsy will start a process within the container to keep track of activity and then kill itself when the user hasn't connected for the given duration. This will not erase any state within the container and instead only stop it. Then when the user wants to start working with the workspace again, Devsy will restart the container. +**Non-machine providers** such as Docker, Podman, Kubernetes, and Microsandbox run a process in the container that tracks activity. When nobody has connected for the timeout, it ends the container's main process. The container stops, its state is kept, and Devsy restarts it later. - -The Apple provider is the exception: its `INACTIVITY_TIMEOUT` option description states that it deletes the container after the idle period, rather than just stopping it like Docker, Podman and Microsandbox. As with any deleted (non-machine) container, only data on mounted volumes survives; anything in the writable layer is lost. + +The Apple provider deletes the container instead of stopping it. Only data on mounted volumes survives. -### Machine Providers +**Machine providers** run a Devsy daemon on the VM. When there is no activity for the timeout, the daemon shuts the machine down or deletes it, whichever costs less for that cloud. Devsy restarts or recreates it when you resume. -For machine providers, killing just the container within the remote machine is typically not enough as VMs still generate costs even if they are unused. Instead, Devsy will install itself as a Daemon into the remote VM and track the activity from there. If there wasn't activity for a given amount of time, Devsy will automatically shutdown the machine or even delete it, based on whichever is more cost-effective for the given cloud provider. Then when the developer wants to resume development, Devsy restarts or recreates the virtual machine. - - -See [agent's development guide](../developing-providers/agent.mdx#machine-providers) to learn more about how inactivity-timeout works on the provider side. - +See the [agent guide](../developing-providers/agent.mdx#machine-providers) for how providers implement this, and [Machine diagnostics](../managing-machines/machine-diagnostics.mdx) for debugging. diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/mcp-server.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/mcp-server.mdx index 235f2e0ae8..f0926b04ce 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/mcp-server.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/mcp-server.mdx @@ -3,43 +3,13 @@ title: Agent Control via MCP sidebar_label: Agent Control (MCP) --- -# Agent Control via MCP - -`devsy mcp serve` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio. MCP-compatible AI clients can connect to it and drive Devsy - listing, creating, and executing inside workspaces - without shelling out to the CLI themselves. +`devsy mcp serve` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio. AI clients that support MCP can use it to list, create, and run commands in workspaces. ```sh devsy mcp serve ``` -The server reads JSON-RPC frames from stdin and writes them to stdout. Configure your MCP client to launch the command; it will discover the registered tools at startup. - -## Tools exposed - -The server registers 11 tools across workspace and provider domains: - -| Tool | Purpose | -|---|---| -| `workspace_list` | List all workspaces with provider, IDE, and source. | -| `workspace_status` | Get saved workspace configuration (not live running state). | -| `workspace_create` | Create and start a new workspace. | -| `workspace_start` | Start (or resume) an existing workspace. | -| `workspace_stop` | Stop a running workspace. | -| `workspace_delete` | Delete a workspace by name. Accepts `force=true`. | -| `workspace_exec` | Run a one-shot command inside a running workspace. | -| `provider_list` | List configured providers. | -| `provider_add` | Add a provider from a registry name, GitHub URL, or local path. | -| `provider_delete` | Remove a configured provider. | -| `provider_use` | Set the default provider for new workspaces. | - -`workspace_exec` is bounded by three server flags: - -- `--exec-timeout-default` (default `5m`) - default per-call timeout. -- `--exec-timeout-max` (default `30m`) - caller-supplied timeouts are clamped to this. -- `--exec-output-cap` (default `100 KiB`) - per-stream byte cap; excess is replaced with a truncation marker. - -## Example client config - -The exact format depends on your MCP client, but every client needs the command to launch and any arguments. A generic JSON shape looks like: +Configure your MCP client to launch that command. The exact config format depends on the client. A typical shape: ```json { @@ -52,59 +22,36 @@ The exact format depends on your MCP client, but every client needs the command } ``` -Check your client's documentation for where this config lives (e.g. `claude_desktop_config.json` for Claude Desktop). Refer to the [MCP specification](https://modelcontextprotocol.io/specification) for transport and tool semantics. +## Tools -## Install the Devsy Agent Skill +| Tool | Purpose | +|---|---| +| `workspace_list` | List workspaces with provider, IDE, and source. | +| `workspace_status` | Get the saved workspace configuration. It does not report whether the workspace is running. | +| `workspace_create` | Create and start a workspace. | +| `workspace_start` | Start an existing workspace. | +| `workspace_stop` | Stop a running workspace. | +| `workspace_delete` | Delete a workspace. Accepts `force=true`. | +| `workspace_exec` | Run a one-shot command in a running workspace. | +| `provider_list` | List configured providers. | +| `provider_add` | Add a provider from a registry name, GitHub URL, or local path. | +| `provider_delete` | Remove a provider. | +| `provider_use` | Set the default provider. | -MCP provides the tools to control Devsy. The first-party Agent Skill teaches -an agent how to select workspaces and providers, execute commands, recover from -timeouts, and use CLI diagnostics when needed. It is for using Devsy, rather -than contributing to the Devsy source repository. +To check whether a workspace is running, use `devsy workspace status --result-format json`. -After installing Devsy, configure your agent's MCP client to launch -`devsy mcp serve`, then install the skill: +`workspace_exec` is limited by flags on `devsy mcp serve`: `--exec-timeout-default` (5m), `--exec-timeout-max` (30m), and `--exec-output-cap` (100 KiB per stream). `--max-concurrent-ops` (8) limits concurrent exec, create, and start calls. -```sh -npx skills add devsy-org/devsy --skill devsy -``` +## Agent skill -For use across projects, add `-g`. To target a particular agent, use `--agent`: +Devsy also publishes an agent skill that teaches an agent how to pick workspaces and providers, run commands, and recover from timeouts. It is separate from the MCP server: installing it does not install Devsy or configure MCP. It needs Node.js for `npx`. ```sh -npx skills add devsy-org/devsy --skill devsy -g -npx skills add devsy-org/devsy --skill devsy --agent codex -npx skills add devsy-org/devsy --skill devsy --agent claude-code -``` - -The Agent Skill and MCP configuration are separate. Installing the skill does -not install Devsy, configure MCP, or set up a provider. The installer requires -Node.js/`npx`; Devsy itself does not depend on it. See the -[skills installer](https://github.com/vercel-labs/skills) for supported clients -and updates. Follow your agent's instructions for reloading newly installed -skills or MCP configuration. - -### Hand this to your agent - -Copy this prompt into the agent you want to use with Devsy: - -```text -Set up the published first-party Devsy skill for this agent so you can operate -Devsy workspaces for me. Check whether Devsy is installed and supports -`devsy mcp serve`. Install the devsy skill from devsy-org/devsy for this agent; -use a project installation unless I ask for global installation. Follow this -agent's current MCP setup instructions to configure Devsy, preserving existing -MCP entries. If installation or configuration cannot be completed, tell me -which prerequisite is missing and the exact next step. Verify the integration -by listing my Devsy workspaces without creating or changing any. Report what -was installed/configured and whether the connection worked. +npx skills add devsy-org/devsy --skill devsy ``` -After setup, try: "Create a Devsy workspace for this repository and run its -tests," or "Stop my example workspace." The skill prefers MCP tools and uses -the CLI for operations the connected server does not expose. For live running -state, the current MCP `workspace_status` result is only saved configuration; -`devsy workspace status --result-format json` probes live state. +Add `-g` to install it for all projects, or `--agent` to target one agent. ## Security -The MCP server has the same authority as your local Devsy CLI. A connected client can create, modify, and delete workspaces, run arbitrary commands inside them, and add or remove providers. Only enable `devsy mcp serve` for clients you trust. +The MCP server has the same authority as your local Devsy CLI. A connected client can create and delete workspaces, run any command in them, and add or remove providers. Only use it with clients you trust. diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/prebuild-a-workspace.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/prebuild-a-workspace.mdx index 99fb13af27..86ccbd772b 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/prebuild-a-workspace.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/prebuild-a-workspace.mdx @@ -3,48 +3,31 @@ title: Prebuild a Workspace sidebar_label: Prebuild a Workspace --- -## Prebuild a Workspace +A prebuild is an image built ahead of time from `devcontainer.json`, its features, and any Dockerfile. When a prebuild exists, Devsy starts from it instead of building, which saves time on complex environments. -Prebuilding a workspace means building a ready-to-use docker image out of the `devcontainer.json`, its referenced features and optionally a linked `Dockerfile`. -Usually when creating a new workspace, Devsy will first build a docker image based on the configuration and then later use this image to create the development environment. -With prebuilds, this step can be omitted and Devsy can directly use the docker image to start the development environment. This can save start up time, especially for more complex development environments. +## How it works -### How does it work? +Devsy hashes the devcontainer configuration and uses `devsy-` plus the hash as the image tag. When you point Devsy at an image repository, it looks for that tag and uses the image if found. -Based on the `devcontainer.json` configuration, Devsy will generate a hash in the form of `devsy-HASH` and use this as a tag for the created docker image. -You can then reference docker image repositories, where Devsy will search this tag and if found uses it instead of building the image itself. +Build and push a prebuild: -To prebuild a workspace, you can run the following command: -``` -# Prebuild the docker image for github.com/my-org/my-repo and save it in image registry ghcr.io/my-org/my-repo +```sh devsy workspace build github.com/my-org/my-repo --repository ghcr.io/my-org/my-repo ``` - -Devsy will only build the workspace if there isn't an existing prebuild found in the specified docker image repository - - -Devsy will use the current provider for doing this, which means you can also use remote providers to prebuild an image. You can even have a separate provider just for prebuilding images. - -## Using Prebuilds - -Using prebuilds means you specify a docker image repository, where Devsy will search for an image with a specific hash generated from the devcontainer configuration. You can either specify this prebuild repository via a flag during workspace creation or directly in the `devcontainer.json`. +Devsy skips the build if the repository already has an image with the matching tag. It uses your current provider, so you can prebuild on a remote provider or a dedicated one. - -If a prebuild cannot be found in the given repository or credentials are missing locally, Devsy will just skip the repository. - +## Use a prebuild -### Reference Prebuild Repository as Flag +Pass the repository when you create a workspace: -When creating a new workspace, you can define the prebuild repository via the `--prebuild-repo` flag: -``` +```sh devsy workspace up github.com/my-org/my-repo --prebuild-repo ghcr.io/my-org/my-repo ``` -### Reference Prebuild Repository in devcontainer.json +Or set it in `devcontainer.json`, which suits builds run from CI: -It's also possible to include the prebuild repository directly in the `devcontainer.json`, which makes it easy to automate prebuilding through a CI/CD pipeline on changes. You can specify the prebuild repository via: -``` +```json { "name": "my-project", "customizations": { @@ -54,3 +37,5 @@ It's also possible to include the prebuild repository directly in the `devcontai } } ``` + +If no matching image is found, or you lack credentials for the repository, Devsy skips it and builds as usual. diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/stop-and-delete-a-workspace.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/stop-and-delete-a-workspace.mdx index 339fbce524..79487aba22 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/stop-and-delete-a-workspace.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/stop-and-delete-a-workspace.mdx @@ -3,72 +3,44 @@ title: Stop or Delete a Workspace sidebar_label: Stop or Delete a Workspace --- -## Stop a Workspace +## Stop a workspace -Stopping a workspace means to temporarily pause a container so that it doesn't consume any more computing resources such as CPU or memory. -Depending on the provider used, this either means to stop a container (see [docker stop](https://docs.docker.com/engine/reference/commandline/stop/) for more information) -or shutdown the underlying VM where the container is running. -Devsy will automatically determine what specific action to take when a workspace is stopped. +Stopping pauses a workspace so it stops using CPU and memory. Depending on the provider, Devsy stops the container or shuts down the VM it runs on. Its data is kept. -### Devsy Desktop +In Devsy Desktop, open the workspace's actions menu and choose **Stop**. With the CLI: -In the 'Workspaces' view, open the actions menu for a running workspace and choose 'Stop'. The workspace immediately shows a **Stopping** status badge. Once stopped, the menu will show a 'Start' option to resume the workspace. Detailed operation progress remains available on the workspace detail surface. - -### Devsy CLI - -Run the following command to stop a workspace: -``` +```sh devsy workspace stop my-workspace ``` -Afterwards, you can start the workspace via: -``` +Start it again with: + +```sh devsy workspace up my-workspace ``` -### Automatic stop - -Some providers allow automatic stop of a workspace, usually to save costs when a workspace is not used. -For example, the Google Cloud provider will shutdown the virtual machine where the workspace is running after it's unused for 10 minutes, by default. -This means you need to start the workspace after it has been stopped when you want to reconnect. - -### Background up tasks +Some providers stop idle workspaces on their own. See [Auto-inactivity timeout](./inactivity-timeout.mdx). -Stopping or deleting a workspace first cancels any active detached `devsy workspace up --detach` task for that workspace, so a background up cannot keep recreating or restarting a workspace you asked to stop. -For current detached workers on Linux, macOS, and Windows, `devsy workspace task cancel ` terminates the task's process tree and records the task as canceled. On other Unix systems, or for older task records without a saved process identity, cancellation can fail when Devsy cannot safely identify surviving processes. -While an SSH tunnel is attached, its health checks observe the workspace but never start a stopped one. +Stopping or deleting a workspace first cancels any running `devsy workspace up --detach` task for it. To cancel a task yourself, use `devsy workspace task cancel `. -## Delete a Workspace +## Delete a workspace -Deleting a workspace means to erase all state of an existing workspace and remove all traces of it within Devsy. -Depending on the Devsy provider, this means either removing a Docker container or deleting a whole virtual machine. -Devsy will automatically determine what specific action to take when a workspace is deleted. +Deleting removes the workspace and everything Devsy stores about it. Depending on the provider, that means removing a container or deleting a VM. -### Devsy Desktop +In Devsy Desktop, open the workspace's actions menu, choose **Delete**, and confirm. If the action fails, the error appears on the workspace detail page, where you can also open the logs. -In the 'Workspaces' view, open the actions menu for the workspace and choose 'Delete', then confirm the deletion dialog. The workspace immediately shows a **Deleting** status badge. The row disappears after deletion finishes and the workspace list confirms removal. Detailed operation progress, errors, and refresh recovery controls remain available on the workspace detail surface. +With the CLI: -Progress for desktop actions stays available when you navigate between pages or reload the window. If the action fails, its error remains visible on the workspace detail surface and you can open the workspace logs for details. If the action finishes but refreshing its status fails, use **Retry refresh** there; this refreshes the observation without repeating the action. - -Live action progress covers commands initiated by the desktop. Commands launched in a separate terminal are reflected by periodic status refreshes. Progress recovery after fully quitting and restarting the desktop is not supported. - -### Devsy CLI - -Run the following command to delete a workspace: -``` +```sh devsy workspace delete my-workspace ``` -`devsy workspace down` (as well as `rm`) is an alias for `devsy workspace delete`. It performs the same full Devsy workspace teardown: -``` -devsy workspace down my-workspace -``` +`devsy workspace down` and `devsy workspace rm` are aliases for the same command. -For Docker Compose-backed workspaces, teardown uses Compose `down` (with `--remove-volumes` remaining an opt-in flag to remove associated named volumes). Use `devsy workspace stop` when you want to stop a workspace while retaining its configuration and state so it can be started again later. +If the provider is unreachable, you can force the delete: -If deletion fails because the Provider is not reachable anymore or another error has occurred, you can also force delete a workspace via: -``` +```sh devsy workspace delete my-workspace --force ``` -However, this means the workspace will only be deleted on the Devsy side locally, and any error raised by the used provider will be ignored. Only use this option with caution as this might leave previously created resources behind. +This only removes the workspace on the Devsy side and ignores provider errors, so it can leave cloud resources behind. diff --git a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/workspace-snapshots.mdx b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/workspace-snapshots.mdx index d00985d46a..411f132e90 100644 --- a/sites/docs-devsy-sh/content/docs/developing-in-workspaces/workspace-snapshots.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-in-workspaces/workspace-snapshots.mdx @@ -3,113 +3,71 @@ title: Workspace Snapshots sidebar_label: Workspace Snapshots --- -## Workspace Snapshots - -A snapshot captures a workspace's working state at a point in time: the running container's filesystem (installed packages, config changes) and the contents of its bind-mounted volumes (your code, including uncommitted changes). Snapshots are stored as OCI artifacts in a registry you control, so you can restore them later, or use them to transfer a workspace to a different provider. +A snapshot captures a workspace at a point in time: the container's filesystem, such as installed packages and config changes, and the contents of its bind-mounted volume, including uncommitted code. Snapshots are stored as OCI artifacts in a registry you control. You can restore one later or use it to move a workspace to another provider. -Snapshots are pushed to and pulled from an OCI registry (Docker Hub, GHCR, ECR, or a self-hosted `registry:2`), not stored locally. You need push/pull access to a registry before creating one. +Snapshots are pushed to and pulled from an OCI registry, not stored locally. You need push and pull access to one. -## Create a Snapshot - -The workspace must already be running (`devsy workspace up` must have created it, so its mount information is available): - -```sh -devsy snapshot create my-workspace --registry ghcr.io/my-org/snapshots -``` +## Limitations -On success, the command prints the snapshot ref, which you'll use to restore it later: +- Only workspaces with exactly one bind mount are supported. +- Only local providers, such as Docker and Podman, can create snapshots. Machine-provider workspaces cannot. -``` -ghcr.io/my-org/snapshots:my-workspace-20260731150405-x7f2qk -``` +## Create a snapshot -Add `--message` to describe the snapshot: +The workspace must already exist and be running. ```sh -devsy snapshot create my-workspace --registry ghcr.io/my-org/snapshots --message "before the auth refactor" +devsy snapshot create my-workspace --registry ghcr.io/my-org/snapshots ``` -### Default Registry +The command prints the snapshot reference, which you need to restore it. Add `--message` to describe the snapshot. -Rather than passing `--registry` every time, set a default for the current context: +To avoid passing `--registry` each time, set a default for the context: ```sh devsy context set -o SNAPSHOT_REGISTRY=ghcr.io/my-org/snapshots ``` -### Limitations - -- Only workspaces with exactly one bind mount are supported today. Workspaces with multiple mounts (e.g. an extra `mounts` entry in `devcontainer.json`) aren't yet supported. -- Only local providers (Docker, Podman) can create snapshots. Machine-provider workspaces aren't supported. - -## List Snapshots +## List snapshots ```sh devsy snapshot list my-workspace --registry ghcr.io/my-org/snapshots ``` -Shows every snapshot pushed for that workspace, newest first. +This shows every snapshot of that workspace, newest first. -## Restore a Snapshot +## Restore a snapshot ```sh -devsy snapshot restore ghcr.io/my-org/snapshots:my-workspace-20260731150405-x7f2qk +devsy snapshot restore ``` -This creates a new workspace from the snapshot's committed filesystem and volumes, skipping the devcontainer build entirely since the image is already built. By default the new workspace reuses the original workspace ID; pass `--workspace-id` to restore under a different one, or `--target-provider` to restore using a different provider than the one the snapshot was taken from. +This creates a workspace from the saved filesystem and volume and skips the devcontainer build. It reuses the original workspace ID. Use `--workspace-id` to pick another one, or `--target-provider` to restore onto a different provider. -Equivalently, you can restore as part of `devsy workspace up`: +You can also restore as part of `devsy workspace up`. This cannot be combined with a source argument or `--source`. ```sh -devsy workspace up --from-snapshot ghcr.io/my-org/snapshots:my-workspace-20260731150405-x7f2qk +devsy workspace up --from-snapshot ``` -`--from-snapshot` can't be combined with a positional source or `--source`. - -### Transferring Between Providers +To move a workspace to another provider, restore its snapshot with `--target-provider`. -To move a workspace to a different provider, restore its snapshot with `--target-provider`: +## Delete a snapshot ```sh -devsy snapshot restore ghcr.io/my-org/snapshots:my-workspace-20260731150405-x7f2qk --target-provider kubernetes +devsy snapshot delete ``` -## Delete a Snapshot - -```sh -devsy snapshot delete ghcr.io/my-org/snapshots:my-workspace-20260731150405-x7f2qk -``` - -Removes the snapshot's manifest from the registry. The underlying image and volumes blobs are left for the registry's own garbage collection. - -## Export and Import - -`devsy workspace export`/`devsy workspace import` automatically carry a workspace's snapshot ref when the workspace was itself restored from one, so exporting and re-importing a snapshot-sourced workspace preserves its actual filesystem and volume state, not just its metadata - provided the snapshot manifest is still present in the registry and the environment doing the import has access to pull that registry artifact. If the manifest has been deleted or the import environment can't reach or authenticate to the registry, only the workspace's metadata carries over, not its filesystem/volume state. - -## Identifying Snapshot Images +This removes the manifest from the registry. The registry's own garbage collection removes the image and volume blobs. -The container image a snapshot commits is tagged `LABEL sh.devsy.snapshot=true`, so it can be identified with `docker inspect` or filtered with `docker images --filter label=sh.devsy.snapshot` even outside `devsy snapshot` tooling. +## Export and import -## Volume filtering +`devsy workspace export` and `devsy workspace import` carry the snapshot reference for a workspace that was restored from one. The import restores the real filesystem and volume only if the manifest still exists and the importing machine can pull from the registry. Otherwise only the workspace metadata carries over. -`.devsyignore` rules do not apply to the committed container image. +## What is included -When Devsy captures host bind mounts, `.devsyignore` applies only to the explicitly -designated workspace mount, relative to that source root. The streaming protocol -keeps additional bind mounts independent of those rules. -The snapshot CLI currently requires a single workspace mount because restore -cannot disambiguate multiple mounts. +The committed container image carries the label `sh.devsy.snapshot=true`, so you can find it with `docker images --filter label=sh.devsy.snapshot`. -Files excluded from the workspace volume are absent from the snapshot and from a -restore into an empty or reset target. Without `--reset`, Devsy skips restoring a -target that already contains workspace files and retains its existing contents. -A missing ignore file applies no user exclusions; an invalid or unreadable existing file -stops snapshot streaming. Snapshot creation loads persisted workspace metadata, -which does not grant generated-file transfer exceptions. Devsy excludes its generated -`.devsy-internal` directory at the configured build context, including files left -behind by an interrupted build or failed cleanup. Unrelated folders with that name -follow the workspace ignore rules. Missing build-context metadata stops snapshot -creation; run `devsy up` to refresh it. Tar target prefixes and the volume restore -format are unchanged. +`.devsyignore` rules apply to the workspace mount and not to the container image. Files they exclude are missing from the snapshot. If snapshot creation reports missing build-context metadata, run `devsy up` to refresh it. diff --git a/sites/docs-devsy-sh/content/docs/getting-started/install.mdx b/sites/docs-devsy-sh/content/docs/getting-started/install.mdx index b388814bc1..5a73723fa3 100644 --- a/sites/docs-devsy-sh/content/docs/getting-started/install.mdx +++ b/sites/docs-devsy-sh/content/docs/getting-started/install.mdx @@ -5,12 +5,9 @@ sidebar_label: Install Devsy import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; -Devsy comes in two forms that share the same workflow: +Devsy comes as a desktop app and a CLI. Both do the same things. Use the desktop app if you want a UI and the CLI for scripting. -- **Devsy Desktop** - a guided app for creating and managing workspaces. Start here if you want a UI. -- **Devsy CLI** - the same workflow from a terminal, for automation and scripting. - -Install either one below, then head to the [Quick Start](./quickstart.mdx). +Install one, then follow the [Quick Start](./quickstart.mdx). ## Install Devsy Desktop @@ -26,18 +23,12 @@ Download the build for your platform: For earlier versions, see the [GitHub releases page](https://github.com/devsy-org/devsy/releases). - -The DEB and RPM packages declare their runtime dependencies; the AppImage and Flatpak bundle theirs. Most modern desktop distros run the AppImage as-is (tested on Debian 12+, Ubuntu 22.04+, Fedora 36+, openSUSE Leap 15.3+, Tumbleweed, and Arch). - -If the AppImage fails to launch, install FUSE and the GTK/Electron runtime libraries: - -- Debian/Ubuntu: `sudo apt-get install libfuse2 libgtk-3-0 libnotify4 libnss3 libxss1 libxtst6 xdg-utils libatspi2.0-0` -- Fedora: `sudo dnf install fuse-libs gtk3 libnotify nss libXScrnSaver libXtst xdg-utils at-spi2-core` -- openSUSE: `sudo zypper in libfuse2 gtk3 libnotify4 mozilla-nss libXss1 libXtst6 xdg-utils` + +The DEB and RPM packages declare their dependencies, and the AppImage and Flatpak bundle theirs. If the AppImage does not start, install FUSE 2 (`libfuse2` on Debian and Ubuntu) and try again. -Devsy Desktop needs [WebView 2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/?form=MA13LH). It ships with recent versions of Windows - install it only if the app fails to open. +If the app does not open, install [WebView 2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/?form=MA13LH). Recent versions of Windows include it. ## Install Devsy CLI @@ -48,11 +39,11 @@ On macOS or Linux, the quickest option is the install script: curl -L https://devsy.sh/install.sh | sh ``` -The script detects your OS and CPU architecture, downloads the latest CLI build from [GitHub releases](https://github.com/devsy-org/devsy/releases), verifies its SHA-256 checksum when the release publishes one, and installs `devsy` into `/usr/local/bin` (or `~/.local/bin` when `/usr/local/bin` isn't writable). Re-run it any time to get the latest release. On Windows, use the PowerShell command in the Windows tab below. +The script downloads the latest CLI for your OS and architecture from [GitHub releases](https://github.com/devsy-org/devsy/releases), checks its SHA-256 checksum when the release publishes one, and installs `devsy` into `/usr/local/bin`. If it cannot write there and `sudo` is not available, it installs into `~/.local/bin`. Run it again to update. On Windows, use the PowerShell command in the Windows tab below. Two environment variables customize the script: -- `DEVSY_VERSION` installs a specific release instead of the latest: `curl -L https://devsy.sh/install.sh | DEVSY_VERSION=v1.19.0 sh` +- `DEVSY_VERSION` installs a specific release instead of the latest: `curl -L https://devsy.sh/install.sh | DEVSY_VERSION=vX.Y.Z sh` - `DEVSY_INSTALL_DIR` installs somewhere other than the default: `curl -L https://devsy.sh/install.sh | DEVSY_INSTALL_DIR="$HOME/bin" sh` On macOS or Linux, you can also install with [Homebrew](https://brew.sh): @@ -63,7 +54,7 @@ brew install devsy-org/homebrew-tap/devsy Upgrade later with `brew upgrade devsy`. -To download a binary yourself, run the command for your platform below. You can also install the CLI later from Devsy Desktop. +To download a binary yourself, use the command for your platform below. @@ -106,12 +97,8 @@ curl -L -o devsy "https://github.com/devsy-org/devsy/releases/latest/download/de -Confirm the CLI is on your `PATH`: +Check that the CLI is on your `PATH`: ```bash devsy --version ``` - -## Next step - -Create your first workspace in the [Quick Start](./quickstart.mdx). diff --git a/sites/docs-devsy-sh/content/docs/getting-started/update.mdx b/sites/docs-devsy-sh/content/docs/getting-started/update.mdx index f6363f563b..3016fa4897 100644 --- a/sites/docs-devsy-sh/content/docs/getting-started/update.mdx +++ b/sites/docs-devsy-sh/content/docs/getting-started/update.mdx @@ -5,9 +5,9 @@ sidebar_label: Update Devsy ## Devsy Desktop -Devsy Desktop checks GitHub for new releases shortly after launch and every few hours while running. When an update is available, it downloads in the background and prompts you to restart. After you restart, Devsy runs the latest version. +Devsy Desktop checks GitHub for new releases while it runs. When one is available it downloads in the background and asks you to restart. -If you installed Devsy from a `.deb` or `.rpm` package, update through your package manager instead: [download the latest package](https://github.com/devsy-org/devsy/releases/latest/) and install it again. +If you installed from a `.deb` or `.rpm` package, [download the latest package](https://github.com/devsy-org/devsy/releases/latest/) and install it again. ## Devsy CLI @@ -17,4 +17,4 @@ If you installed with Homebrew, upgrade with: brew upgrade devsy ``` -Otherwise, re-run the install script (`curl -L https://devsy.sh/install.sh | sh`) or the manual command from [Install Devsy CLI](./install.mdx#install-devsy-cli) to download the latest version. +Otherwise, run the install script again (`curl -L https://devsy.sh/install.sh | sh`) or repeat the manual command from [Install Devsy CLI](./install.mdx#install-devsy-cli). diff --git a/sites/docs-devsy-sh/content/docs/how-it-works/deploying-workspaces.mdx b/sites/docs-devsy-sh/content/docs/how-it-works/deploying-workspaces.mdx index eb0de2f035..a9dba5b8fd 100644 --- a/sites/docs-devsy-sh/content/docs/how-it-works/deploying-workspaces.mdx +++ b/sites/docs-devsy-sh/content/docs/how-it-works/deploying-workspaces.mdx @@ -3,84 +3,59 @@ title: How Devsy Deploys Workspaces sidebar_label: Deploying workspaces --- -Devsy deploys workspaces using the "up" command, when executed Devsy builds a devcontainer, if not already available, then uses the provider to deploy the devcontainer to a workspace. Below is a sequence diagram -of the main stages of the "up" command. +`devsy workspace up` builds the devcontainer if needed and uses the provider to start it.
Devsy Up Sequence
Devsy up - Sequence Diagram
-First Devsy checks if we need to create/start a machine to deploy the devcontainer to. Next we pull the source code and .devcontainer.json source from git or a local file and use this with the local environment -to build the workspace. Building is done by the agent since we need access to build tools such as docker buildx/BuildKit (Docker, Apple, Microsandbox drivers) or the dockerless in-cluster builder (Kubernetes and -other drivers without a local container daemon), i.e. `devsy agent workspace build`. The workspace now contains everything needed, so Devsy sets up a SSH connection to the Devsy agent running alongside the -container's control plane. +1. If the provider uses a machine, Devsy creates or starts it. +2. Devsy pulls the source and the `devcontainer.json` from Git or a local folder. +3. The agent builds the workspace image (see [Building](#building)). +4. The agent starts the devcontainer through the driver, for example the Docker daemon or the Kubernetes API. +5. Devsy starts a daemon that stops the machine or container when it is idle, sets up credentials, and opens your IDE. -The agent receives "devsy agent workspace up" with the workspace spec serialised as workspace-info and uses the driver's control plane (the Kubernetes API for k8s, the docker/podman daemon for the Docker driver, -the local `container` CLI for Apple, its own sandbox client for Microsandbox) to start the devcontainer. Once started Devsy deploys a daemon to monitor activity, optionally sets up any platform access for pro -users then optionally retrieves credentials from the local environment before launching the IDE. Once the IDE has started the deployment process has complete, Devsy's agent daemon will continue to monitor the -workspace to put the machine or container to sleep when not in use. +With `devsy workspace up --from-snapshot `, Devsy restores a [snapshot](../developing-in-workspaces/workspace-snapshots.mdx) and skips the build. -Alternatively, `devsy workspace up --from-snapshot ` skips this build-and-deploy flow entirely: it restores a previously saved [workspace snapshot](../developing-in-workspaces/workspace-snapshots.mdx)'s container -filesystem and volumes directly, so no devcontainer build is needed. +## Machines -## Connecting to machines - -In Devsy, machines are the infrastructure that run your devcontainer. Providers like GCP, AWS, and DigitalOcean are considered "machine" providers because they first set up a virtual machine (VM) to host your container. - -When you start a workspace with Devsy, such as running `devsy workspace up`, Devsy uses a selected provider and starts your devcontainer. -If the provider requires a virtual machine (VM), Devsy determines whether to create one. It uses your local environment's credentials and the corresponding CLI tool (e.g., `aws` for AWS or `az` for Azure) to set up the VM. -Once the VM is running, Devsy connects to it through the provider's secure tunnel. Below are examples of providers and their secure tunnels. +Machine providers, such as AWS, GCP, and DigitalOcean, create a VM to host the container. Devsy uses the CLI tool and credentials on your computer, such as `aws` or `az`, to create it, then connects through the cloud's own tunnel: - AWS: [Instance Connect](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-set-up.html) -- Google Cloud (GCP): [Cloud IAP (Identity-Aware Proxy)](https://cloud.google.com/security/products/iap) +- Google Cloud: [Cloud IAP](https://cloud.google.com/security/products/iap) - Azure: [Azure Bastion](https://learn.microsoft.com/en-us/azure/bastion/bastion-overview) - -Alternatively, you can use [SSH tunneling](https://www.ssh.com/academy/ssh/tunneling-example) to connect to your machines, if supported by your setup. - +You can use [SSH tunneling](https://www.ssh.com/academy/ssh/tunneling-example) instead, if your setup supports it. -The Devsy agent starts a SSH server using the STDIO of the secure tunnel in order for your local Devsy CLI/UI to forward ports over the SSH connection. Once this is done Devsy starts your local -IDE and connects it to the devcontainer via SSH. +The agent runs an SSH server over the tunnel, so the client can forward ports and connect your IDE.
Devsy Architecture
Devsy - Component Diagram
-## Connecting to Kubernetes +## Kubernetes -Devsy works the same with kubernetes as with Machines, the key difference is the secure tunnel is set up using the kubernetes control plane, so a separate machine-level agent is not necessary -to be run on the kubernetes node. Instead the Kubernetes driver talks to the Kubernetes API directly (pod exec/attach, the same mechanism `kubectl exec` uses under the hood) to start and connect -a workspace using a devcontainer. +Kubernetes works the same way, but the tunnel is the Kubernetes API (pod exec and attach), so nothing extra runs on the node.
Devsy Architecture
Devsy - Container Diagram Kubernetes
-Devsy often has to build workspaces even when an "image" is specified in .devcontainer.json. This is because the devcontainer can contain "features" the cause the Dockerfile to be extended. -When this happens, or simply when "build" is used in .devcontainer.json, Devsy falls back to its "dockerless" builder since the Kubernetes driver has no local container daemon to build with: -the workspace pod's main container runs the dockerless build image, builds your image in userspace (see [Reduce build times with a cache](../tutorials/reduce-build-times-with-cache.mdx) -for more on remote caching), then execs into your devcontainer's own entrypoint in place. While building, if REGISTRY_CACHE has been specified in the context options, the dockerless builder will -download existing build layers from the registry to reduce the overall build time. +## Building -
- Devsy Architecture 2 -
Devsy - Component Diagram Kubernetes Build Process
-
+Devsy reads `devcontainer.json`, adds any features as build stages on the base Dockerfile, and builds an OCI image. Features mean a build is often needed even when the file only names an image. -## Building workspaces - -Devsy provides the ability to build workspaces by taking a devcontainer.json and a Git repository to compile an OCI-compliant image with everything you need to develop -against using local tools. +Where there is a local container daemon, Devsy builds with `docker buildx` or its built-in BuildKit client. Where there is none, as with Kubernetes, it uses the dockerless builder, which builds in the workspace pod without a daemon. You can push the image to a registry to cache it. See [Reduce build times with a cache](../tutorials/reduce-build-times-with-cache.mdx).
Devsy Architecture
Devsy - Container Diagram
-It does this by parsing the devcontainer.json, extracting the "features" and appending them as build stages to the base Dockerfile. The container is then built, depending on the driver -this could be docker buildx or Devsy's internal BuildKit client (Docker, Apple, and Microsandbox drivers), or the dockerless in-cluster builder (Kubernetes and other drivers without a local -container daemon), and deployed with the configuration defined by your context. Optionally once the container is built, it can be pushed to a registry to cache for -other developers or in case you rebuild your workspace later. See [Reduce build times with a cache](../tutorials/reduce-build-times-with-cache.mdx). +
+ Devsy Architecture 2 +
Devsy - Component Diagram Kubernetes Build Process
+
diff --git a/sites/docs-devsy-sh/content/docs/how-it-works/overview.mdx b/sites/docs-devsy-sh/content/docs/how-it-works/overview.mdx index a46c9a5e1e..a07407a8d4 100644 --- a/sites/docs-devsy-sh/content/docs/how-it-works/overview.mdx +++ b/sites/docs-devsy-sh/content/docs/how-it-works/overview.mdx @@ -3,26 +3,17 @@ title: How it works sidebar_label: Overview --- -Devsy provisions workspaces on any infrastructure. It wraps the CLI tools you already use - `docker`, `gcloud`, and others - to deploy your development environment and run the dev container, or talks to a provider's API directly (for example, the Kubernetes driver uses the Kubernetes API rather than shelling out to `kubectl`). When creating a workspace, Devsy deploys an agent to both the host machine and the container to handle port forwarding, credential forwarding, and log streaming. The agent acts as a control plane across your development environment. - -Devsy uses a client-agent architecture. The client deploys its own agent, which hosts a gRPC server and an SSH server. This resembles a browser-server architecture where the front end is delivered to a remote host. Two practical wins: - -- No version conflict between client and server - you only install the client. -- No infrastructure to manage. - -For easier debugging, Devsy pipes the agent's STDIO to your local shell so you can see what's happening locally and inside the container. - -Below is a high level overview of how Devsy uses your local environment, a source repo and a devcontainer to deploy your workspace to the cloud. +Devsy has a client and an agent. The client is the CLI or desktop app on your machine. When you create a workspace, the client installs its own agent on the host and inside the container, so you only ever install the client. The agent forwards ports, forwards credentials, and streams logs, and it runs an SSH server that your IDE connects to.
Devsy Architecture
Devsy - Component Diagram
-Devsy connects to the workspace through a vendor-specific channel called the **tunnel**. When you run `devsy workspace up`, Devsy picks a provider based on your context and starts your devcontainer. Machine providers create a VM first if needed. Once the devcontainer is running, Devsy deploys the agent into it. +When you run `devsy workspace up`, Devsy picks a provider, starts the devcontainer, and deploys the agent into it. Machine providers create a VM first if needed. Providers wrap the tools you already use, such as `docker` or `gcloud`, or call an API directly, as the Kubernetes driver does. -The tunnel's transport depends on the provider - AWS uses Instance Connect, Kubernetes uses the Kubernetes API's exec/attach mechanism, and so on. The Devsy agent starts an SSH server over the tunnel's STDIO so the local CLI/UI can forward ports. Devsy then opens your local IDE and connects it to the devcontainer over SSH. +The client reaches the agent through a **tunnel**, and the transport depends on the provider. AWS uses Instance Connect and Kubernetes uses pod exec. The agent runs an SSH server over the tunnel, and Devsy opens your IDE over that SSH connection. Port forwarding works only while an IDE or SSH session is open. -Port forwarding requires an active IDE or SSH session - Devsy needs the agent's SSH server, which only runs while one of those connections is open. +To skip the build, create a workspace from a saved [snapshot](../developing-in-workspaces/workspace-snapshots.mdx) with `devsy workspace up --from-snapshot`. -Instead of building from a devcontainer each time, you can also create a workspace from a previously saved [workspace snapshot](../developing-in-workspaces/workspace-snapshots.mdx) with `devsy workspace up --from-snapshot`, which restores the container filesystem and volumes directly and skips the build step entirely. +For what happens during `up`, see [How Devsy deploys workspaces](./deploying-workspaces.mdx). diff --git a/sites/docs-devsy-sh/content/docs/managing-machines/machine-diagnostics.mdx b/sites/docs-devsy-sh/content/docs/managing-machines/machine-diagnostics.mdx index ffcea2a4d4..8e7f17029c 100644 --- a/sites/docs-devsy-sh/content/docs/managing-machines/machine-diagnostics.mdx +++ b/sites/docs-devsy-sh/content/docs/managing-machines/machine-diagnostics.mdx @@ -3,100 +3,41 @@ title: Machine Diagnostics sidebar_label: Machine Diagnostics --- -Devsy can report the health and recent activity of the inactivity daemon that -runs on a machine. This is useful when a workspace did not stop as expected or -when a machine's automatic shutdown needs investigation. +Use diagnostics when a machine did not stop when you expected. They report on the inactivity daemon that runs on the machine. ```sh devsy machine diagnostics ``` -The command reports the provider's machine state separately from the Devsy -daemon state, its most recent patrol, and the configured workspaces. Use JSON -when integrating diagnostics with another tool: +The output separates the provider's machine state from the daemon's state, and lists the last patrol and each workspace. Add `--result-format json` for scripts. -```sh -devsy machine diagnostics --result-format json -``` - -The plain-text workspace table shows the machine shutdown state for every -workspace and identifies the current shutdown candidate. Devsy runs a -machine-level inactivity action only when every discovered workspace is idle -and none is busy, invalid, or configured without auto-stop. The candidate time -is therefore an eligibility point, not a promise that a machine will stop at -that exact second. - -## Recent diagnostic events +## When a machine stops -Use `machine logs` to show the same structured diagnostic events in a compact -log-style view: - -```sh -devsy machine logs -``` +The daemon stops a machine only when every workspace on it is idle. A workspace that is busy, invalid, or has auto-stop turned off blocks the stop. An inactivity timeout must be a positive duration such as `30m`. -Use `devsy machine logs --follow` to poll for new events every -five seconds until interrupted. Collection has a 30-second timeout and resumes -from the remote cursor, reporting session resets and retention gaps. With -`--result-format json`, each poll writes one JSON response on its own line. -Delivery depends on connectivity and remote retention; this is not an instant -push stream. Desktop refreshes diagnostics every 30 seconds while the machine -detail page is visible and the machine is running, preserving the last known -snapshot through collection failures. +The shutdown candidate shown for a workspace is when it becomes eligible, not a scheduled stop time. New activity moves it, and other workspaces can still block the machine. -Events cover daemon starts and stops, workspace discovery, inactivity deadlines, -and shutdown outcomes. They are not an SSH shell, journald output, Docker logs, -or provider control-plane logs. +## Fields -Diagnostic events are redacted before being written on the machine and retained -within a fixed storage limit. Older events can therefore be rotated; the CLI -and Desktop indicate when an event history gap is detected. - -If a machine is stopped, Devsy does not start it merely to collect diagnostics. -Desktop keeps the last successfully collected snapshot and indicates that it is -historic until the machine is running again. - -## Interpreting the snapshot - -Provider state, daemon health, and snapshot freshness answer different questions: - -| Field | What it tells you | +| Field | Meaning | | --- | --- | -| Provider state | The provider's most recently reported machine state. | -| Daemon health | Whether the daemon's most recently recorded operation succeeded. | -| Snapshot freshness | Whether the remote daemon updated its snapshot recently; not proof of current connectivity. | -| Last patrol | When the daemon last evaluated workspace inactivity. Startup alone does not count as a patrol. | -| Last daemon error | The most recent recorded failure in this daemon session, retained after recovery. Its timestamp distinguishes it from a current failure. | -| Shutdown candidate | All discovered workspace checks permit an inactivity action. Provider state still determines whether the machine actually stopped. | +| Provider state | The last machine state the provider reported. | +| Daemon health | Whether the daemon's last operation succeeded. | +| Snapshot freshness | Whether the daemon updated its snapshot recently. It does not prove the machine is reachable now. | +| Last patrol | When the daemon last checked workspace inactivity. | +| Last daemon error | The latest failure in this daemon session. It stays after recovery, so check its timestamp. | +| Shutdown candidate | Every workspace check allows a stop. The provider state shows whether the machine actually stopped. | -A busy workspace, disabled auto-stop, unavailable workspace state, or invalid -timeout blocks automatic shutdown. An inactivity timeout must be a positive -duration, such as `30m`. An active workspace shows its deadline, but that time -is not a promise: subsequent activity can move it, and other workspaces can -still block the machine action. +## Events -## Event meanings and troubleshooting +```sh +devsy machine logs +``` -Event identifiers remain stable for integrations. Routine lifecycle transitions -use `info`; an invalid workspace configuration uses `warn`; patrol and shutdown -command failures use `error`. Workspace discovery/removal means the daemon found -or lost configuration on disk, not that a provider created or deleted a machine. +This shows recent daemon events: starts and stops, workspace discovery, inactivity deadlines, and shutdown results. Add `--follow` to keep polling for new ones. These are diagnostic events only, not shell, Docker, or provider logs. Older events are rotated out, and the output tells you when it detects a gap. -`shutdown.started` records an attempt. `shutdown.succeeded` means the configured -command returned successfully, not that the provider confirmed shutdown. -`shutdown.failed` records a failed command and makes the snapshot degraded. -An abrupt shutdown may prevent a final event from being written; absence of a -completion event does not prove failure. Repeated failures can represent retries -on later patrols. +`shutdown.succeeded` means the stop command returned successfully, not that the provider confirmed the machine stopped. A missing completion event does not prove failure, because an abrupt shutdown can prevent it from being written. -If diagnostics are stale or unavailable, check the provider state and connection -first. For permission errors, verify the installed daemon reader ownership. For -invalid configuration, correct the workspace settings before expecting auto-stop. -For a command failure, inspect the event's error code and the daemon's operator -logs; user-facing events deliberately avoid raw command output and secrets. +Devsy does not start a stopped machine to collect diagnostics. It only collects while you ask for it, through the CLI or an open machine page in the desktop app, which keeps the last snapshot for a stopped machine. -The host does not collect every machine continuously in the background. CLI -follow and the visible Desktop machine page collect on demand. Remote retention -is bounded, and Desktop keeps up to 2,000 collected events per machine and -context. Gaps and session resets are possible; these views are diagnostic aids, -not a durable audit log or an exactly-once event delivery system. +If diagnostics are stale or unavailable, check the provider state and connection first. diff --git a/sites/docs-devsy-sh/content/docs/managing-machines/what-are-machines.mdx b/sites/docs-devsy-sh/content/docs/managing-machines/what-are-machines.mdx index 777c9e097e..e6e1bd5978 100644 --- a/sites/docs-devsy-sh/content/docs/managing-machines/what-are-machines.mdx +++ b/sites/docs-devsy-sh/content/docs/managing-machines/what-are-machines.mdx @@ -3,10 +3,9 @@ title: What are Machines? sidebar_label: What are Machines? --- -A [Machine Provider](../managing-providers/what-are-providers.mdx) is responsible for provisioning machines to host your workspace. -For cloud providers, these machines are typically virtual machines (VMs). Devsy manages the lifecycle of these machines, including creation and deletion of a workspace. +A machine is the VM a [machine provider](../managing-providers/what-are-providers.mdx) creates to host your workspace. Devsy manages its lifecycle, including creating and deleting it with the workspace. -You can directly manage all the machines in the various workspaces using: +To work with machines directly, use: ```sh devsy machine diff --git a/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx b/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx index 838bb0fa16..2b56b217b6 100644 --- a/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx +++ b/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx @@ -3,7 +3,7 @@ title: Manage Providers sidebar_label: Manage Providers --- -Devsy providers include: +Providers you can add: - [Docker (docker)](https://github.com/devsy-org/devsy/tree/main/providers/docker) - [Podman (podman)](https://github.com/devsy-org/devsy/tree/main/providers/podman) @@ -18,376 +18,166 @@ Devsy providers include: - [Azure (azure)](https://github.com/devsy-org/devsy-provider-azure) - [Digital Ocean (digitalocean)](https://github.com/devsy-org/devsy-provider-digitalocean) -Install these providers with the Devsy CLI: +List what is available from the CLI: -``` -devsy provider add docker -``` - -List available providers using the command: - -``` +```sh devsy provider list --available ``` -## Adding a Provider +## Add a provider ### Devsy Desktop -Open the Providers view and click **Add**. The provider wizard has four steps: - -1. **Select** - pick a built-in preset, or enter a GitHub link, `provider.yaml` URL, or local file path in the **Provider Source** field below the presets. -2. **Configure** - fill in provider-specific options (the form is generated from the provider's schema). -3. **Initialize** - Devsy runs the provider init and streams logs. -4. **Done** - review the result. Failures show the underlying error. - -The ProviderSheet (click any provider in the list) exposes edit settings, switch version, update, delete, rename, set as default, and re-initialize. - - - The Desktop Application calls `devsy provider add PROVIDER` under the hood. - - -#### Custom Providers +Open **Providers** and click **Add**. The wizard has four steps: -In the Select step, type one of the following into the **Provider Source** field below the preset grid: +1. **Select.** Pick a preset, or enter a GitHub link, a `provider.yaml` URL, or a local path under **Provider Source**. +2. **Configure.** Fill in the options. The form comes from the provider's schema. +3. **Initialize.** Devsy runs the provider init and streams the logs. +4. **Done.** Review the result. A failure shows the underlying error. -- A GitHub link to the provider's project -- A URL to a `provider.yaml` -- A file path to a `provider.yaml` +Click a provider in the list to edit its settings, switch version, update, re-initialize, rename, set it as default, or delete it. ### Devsy CLI -Install any provider from the list with: - ```sh devsy provider add docker -devsy provider add podman -devsy provider add kubernetes -devsy provider add apple -devsy provider add microsandbox -devsy provider add lima -devsy provider add orbstack -devsy provider add ssh -devsy provider add aws -devsy provider add azure -devsy provider add gcloud -devsy provider add digitalocean ``` - - You can use the `--name` flag to add multiple providers of the same type with - different options, for example `devsy provider add aws --name aws-gpu -o - AWS_INSTANCE_TYPE=p3.8xlarge` - - -#### From GitHub - -You can specify a custom provider, directly from GitHub, by using the format -`my-username/repo`, so for example: +Use `--name` to add the same provider more than once with different options: ```sh -devsy provider add devsy-org/devsy-provider-terraform +devsy provider add aws --name aws-gpu -o AWS_INSTANCE_TYPE=p3.8xlarge ``` -Devsy will search the latest release for a `provider.yaml` and download that automatically. This should work for private GitHub repositories where Devsy will use the local https credentials to connect to the GitHub repository. - -If you want to install the provider from a different release, you can do the following: +**From GitHub.** Devsy downloads the `provider.yaml` from the latest release. It uses your local HTTPS credentials, so private repositories work. Add `@` and a tag for another release. ```sh +devsy provider add devsy-org/devsy-provider-terraform devsy provider add my-org/my-repo@v0.0.1 ``` -#### From Local Path - -If you have locally downloaded providers, you can also add them directly to -Devsy, by pointing to the file path of `provider.yaml` manifest: +**From a local path or URL.** ```sh devsy provider add ../devsy-provider-mock/provider.yaml -``` - -#### From URL - -You can also specify the URL to the `provider.yaml` file, for example: - -```sh devsy provider add https://github.com/devsy-org/devsy-provider-ssh/releases/download/v0.0.3/provider.yaml ``` -## Set Provider Options - -Each provider defines its own options, so they differ from provider to provider. - -### Desktop Options - -To manage options from the app, head over the `Providers` section, and click -`Edit` on the provider you want to configure. - -### CLI Options +## Set provider options -Set options during the `add` or `init` phase: +Each provider has its own options. In the desktop app, open **Providers** and click **Edit** on a provider. With the CLI, set options when you add or initialize: ```sh devsy provider add -o KEY=value -``` - -or - -```sh devsy provider init -o KEY=value ``` -To manage options later, list the current values with: +List the options and their current values: ```sh devsy provider get ``` -An example output for the AWS Provider is: - -``` - NAME | REQUIRED | DESCRIPTION | DEFAULT | VALUE -----------------------------+----------+--------------------------------+-------------------------+-------------------------- -AGENT_PATH | false | The path where to inject the | /var/lib/toolbox/devsy | /var/lib/toolbox/devsy - | | Devsy agent to. | | -AWS_ACCESS_KEY_ID | false | The AWS access key id | | -AWS_AMI | false | The disk image to use. | | -AWS_DISK_SIZE | false | The disk size to use. | 40 | 40 -AWS_INSTANCE_TYPE | false | The machine type to use. | c5.xlarge | c5.xlarge -AWS_REGION | true | The AWS cloud region to create | | us-west-2 - | | the VM in, e.g. us-west-1 | | -AWS_SECRET_ACCESS_KEY | false | The AWS secret access key | | -AWS_VPC_ID | false | The vpc id to use. | | -INACTIVITY_TIMEOUT | false | If defined, will automatically | 10m | 10m - | | stop the VM after the | | - | | inactivity period. | | -INJECT_DOCKER_CREDENTIALS | false | If Devsy should inject docker | true | true - | | credentials into the remote | | - | | host. | | -INJECT_GIT_CREDENTIALS | false | If Devsy should inject git | true | true - | | credentials into the remote | | - | | host. | | -``` - -This table is an overview. Change any option with: - -```sh -devsy provider set --option = -``` - -For example, to change the disk size from 40GB to 120GB: +Change one later: ```sh -devsy provider set aws --option AWS_DISK_SIZE=120 +devsy provider set --option KEY=VALUE ``` -Run `devsy provider get aws` again to confirm - the `VALUE` column for `AWS_DISK_SIZE` now reads `120`. - - -## Docker Provider: Contexts and Daemon Endpoints - -Devsy follows standard Docker CLI context and endpoint semantics when running workspaces with the Docker provider. - -### Context Preservation - -When Devsy configures credentials for Docker, it automatically preserves your existing Docker client configuration (`config.json`) and stored context metadata (`contexts/`). This ensures that non-default Docker contexts-such as those managed by Docker Desktop (`desktop-linux`), OrbStack (`orbstack`), or custom remote endpoints-remain active and accessible during workspace creation and execution. +## Docker provider -### Explicit Context Selection (`DOCKER_CONTEXT`) +Devsy follows the Docker CLI's rules for contexts and daemon endpoints. It keeps your existing Docker `config.json` and contexts, so contexts from Docker Desktop, OrbStack, or a remote endpoint keep working. -You can target a specific Docker context explicitly: +Devsy picks the connection in the same order as the Docker CLI: -- Via provider option: - ```sh - devsy provider set docker -o DOCKER_CONTEXT= - ``` -- Via environment variable: - ```sh - DOCKER_CONTEXT= devsy workspace up - ``` +1. `DOCKER_CONTEXT` +2. `DOCKER_HOST` +3. The active context in `$DOCKER_CONFIG/config.json`, or `~/.docker/config.json` when `DOCKER_CONFIG` is not set +4. The local socket, `unix:///var/run/docker.sock` -When set, `DOCKER_CONTEXT` takes precedence over both `DOCKER_HOST` and the persisted current context set in `config.json`. +Set `DOCKER_CONTEXT` or `DOCKER_HOST` as a provider option or as an environment variable: -### Explicit Daemon Targeting (`DOCKER_HOST`) - -To direct Docker commands directly to a specific socket or remote daemon endpoint without using a context, configure `DOCKER_HOST`: - -- Via provider option: - ```sh - devsy provider set docker -o DOCKER_HOST=ssh://user@docker-host - ``` -- Via environment variable: - ```sh - DOCKER_HOST=ssh://user@docker-host devsy workspace up - ``` +```sh +devsy provider set docker -o DOCKER_CONTEXT= +devsy provider set docker -o DOCKER_HOST=ssh://user@docker-host +``` -For remote TCP daemons, enable mutual TLS authentication by configuring `DOCKER_TLS_VERIFY=1` and pointing `DOCKER_CERT_PATH` to your client certificates. +For a remote TCP daemon with mutual TLS, set `DOCKER_TLS_VERIFY=1` and point `DOCKER_CERT_PATH` at your client certificates. ### Rancher Desktop -Devsy supports Rancher Desktop through the Docker provider when Rancher Desktop uses the **Moby** container engine. It follows the same Docker context semantics described above; Rancher Desktop typically provides its CLI at `~/.rd/bin/docker` and uses the `rancher-desktop` context. On macOS, Devsy automatically checks that CLI location when `docker` is not available on the application `PATH`. - -You can configure both values explicitly: +Rancher Desktop works with the Docker provider when it uses the Moby engine. If you use `containerd`, switch to Moby. On macOS Devsy looks for the CLI at `~/.rd/bin/docker` when `docker` is not on your `PATH`. You can set both values yourself: ```sh devsy provider set docker -o DOCKER_PATH="$HOME/.rd/bin/docker" devsy provider set docker -o DOCKER_CONTEXT=rancher-desktop ``` -For troubleshooting, verify the CLI and context directly, then inspect the Devsy provider configuration: - -```sh -"$HOME/.rd/bin/docker" context ls -"$HOME/.rd/bin/docker" context inspect rancher-desktop -"$HOME/.rd/bin/docker" --context rancher-desktop info -devsy provider get docker -``` - -If Rancher Desktop is configured for `containerd`, switch it to Moby before using Devsy's Docker provider. Rancher Desktop `containerd`/`nerdctl` parity is not yet validated by this release. - -### Precedence - -Devsy resolves the active Docker connection in the same order as the Docker CLI: -1. `DOCKER_CONTEXT` (explicit context selection) -2. `DOCKER_HOST` (explicit daemon endpoint) -3. Persisted active context in `$DOCKER_CONFIG/config.json` when `DOCKER_CONFIG` is set, and `~/.docker/config.json` otherwise (used for context resolution and credential preservation) -4. Default local Unix socket (`unix:///var/run/docker.sock`) - -## Single Machine Provider +## Single machine -By default, Devsy will use a separate machine for each workspace using the same provider, -you can enable `Reuse machine` in a provider in order to use a single machine for all workspaces. - -In **the desktop app** the option is available in the option management interface for the provider -(see section above) - -In **the CLI** you can set this option using: +By default each workspace gets its own machine. To share one machine between all workspaces on a provider, turn on **Reuse machine** in the provider's options in the desktop app, or run: ```sh devsy provider init --single-machine ``` -## Default Provider - -When you add a provider, you can mark it as the **default provider**. Devsy then uses it for any workspace you create without specifying another. +## Default provider -In **the desktop app**, you can set a provider to be default in the option management interface for the provider -(see section above) - -In **the CLI** you can set this option using: +Devsy uses the default provider for workspaces that do not name one. Set it in the provider's options in the desktop app, or run: ```sh devsy provider use ``` -## Updating a Provider's Version or Source +## Update a provider -### List available versions +Show available versions. Add `--prerelease` to include pre-releases and `--no-cache` to skip the version cache. ```sh devsy provider versions ``` -The table shows the published tag, date, and whether it's the currently-installed version. Pass `--prerelease` to include pre-releases and `--no-cache` to bypass the version cache. - -### Re-fetch the current source +Fetch the provider's source again. Without a pinned tag this pulls the latest release. With a pinned tag it fetches that same version. ```sh devsy provider set-source ``` -Re-resolves the provider's existing source. If the source is a registry entry or a GitHub repo without a pinned tag, this pulls the latest release. If the source is already pinned (e.g. `github.com/org/repo@v0.1.0`), it re-fetches that same version - use `--version` to move to a different one. - -### Pin to a specific version +Pin a version, or replace the source: ```sh devsy provider set-source --version v0.2.0 -``` - -Equivalent inline form (works for GitHub-hosted providers): - -```sh -devsy provider set-source github.com/my-org/my-repo@v0.2.0 -``` - -### Point at a different source - -The `set-source` command also replaces the provider's source entirely - registry name, GitHub repo, URL, or local path: - -```sh devsy provider set-source my-org/my-repo devsy provider set-source https://path/to/provider.yaml devsy provider set-source ../path-to/provider.yaml ``` -### Desktop - -Open the Providers sidebar, select a provider, and use the ProviderSheet: - -- **Select version** - pick a tag from the versions dropdown to switch versions. -- **Update** - jump to the latest release. The button surfaces an "Update available" banner when one is detected. -- **Initialize** - re-run provider init (handy after upgrades). - -Existing workspaces continue to use the version they were created with. Rebuild a workspace (`devsy workspace up --recreate`) to pick up the new provider. - -## Removing a Provider - -### Devsy Desktop - -Navigate to the 'Providers' view and click on the trash icon of the provider -you want to remove. +In the desktop app, use the provider's **Select version**, **Update**, and **Initialize** actions. -If a workspace is currently using the provider, you'll be prompted to first -remove that workspace, in order to then remove the provider. +Existing workspaces keep the provider version they were created with. Recreate one with `devsy workspace up --recreate` to pick up the new version. -### Devsy CLI +## Remove a provider -Remove an installed provider with: +In the desktop app, click the trash icon on the provider. If a workspace uses it, Devsy asks you to remove that workspace first. With the CLI: ```sh -devsy provider delete +devsy provider delete ``` - Remember first to delete any workspace related to this provider first, or move - them to another provider, else you'll not be able to interact with the - workspace until you re-install the provider used. +Delete or move the provider's workspaces first. Otherwise you cannot use them until you add the provider again. -## Renaming a Provider - -You can rename a provider using the `devsy provider rename` command. All workspaces and machines using the provider continue to work under the new name. Provider configuration, options, and state are fully preserved. - -### CLI +## Rename a provider -```bash +```sh devsy provider rename ``` -#### Example - -```bash -devsy provider rename my-docker local-docker -``` - -### Constraints - -- The new name must be unique - it cannot match an existing provider. -- Provider names can only contain lowercase letters, numbers, and dashes, up to 32 characters. -- Pro providers (proxy/daemon) cannot be renamed. They are managed by the platform. -- Workspaces bound to the provider must be stopped before renaming. - -### What happens - -- The provider is moved to the new name with all options and settings intact. -- All workspaces and machines associated with the provider are updated to reference the new name. -- If the provider was the default, the default is updated to the new name. -- If any step fails, the entire operation is rolled back to the original state. - -### GUI +Workspaces, machines, options, and the default setting follow the new name. If any step fails, Devsy rolls the rename back. -1. Navigate to the **Providers** section. -2. Select the provider you want to rename. -3. In the provider's configuration page, edit the **Provider Name** field. -4. Click **Update Options** to save. +- The new name must be unique and can use lowercase letters, numbers, and dashes, up to 32 characters. +- Pro providers cannot be renamed. +- Stop the provider's workspaces first. -Devsy will update the provider and all associated workspaces automatically. +In the desktop app, edit **Provider Name** in the provider's configuration and click **Update Options**. diff --git a/sites/docs-devsy-sh/content/docs/managing-providers/what-are-providers.mdx b/sites/docs-devsy-sh/content/docs/managing-providers/what-are-providers.mdx index 0ce149a8d6..66333e52ec 100644 --- a/sites/docs-devsy-sh/content/docs/managing-providers/what-are-providers.mdx +++ b/sites/docs-devsy-sh/content/docs/managing-providers/what-are-providers.mdx @@ -3,24 +3,11 @@ title: What are Providers? sidebar_label: What are Providers? --- -A provider is the CLI program Devsy uses to create, manage, and run workspaces on a given backend. This model is what lets Devsy target any infrastructure - local, cloud, Kubernetes, or remote SSH - without changing how you work. +A provider tells Devsy where and how to run workspaces: your machine, a cloud, Kubernetes, or an SSH host. Each provider is a `provider.yaml` that declares its options, binaries, and commands. -Each provider is defined by a `provider.yaml` that declares the options, configuration, binaries, and commands Devsy needs to create workspaces on that backend. +To use one, see [Manage providers](./manage-providers.mdx). To build one, see [How to develop a provider](../developing-providers/quickstart.mdx). -To get started, see [Manage providers](./manage-providers.mdx). To build your own, see [How to develop a provider](../developing-providers/quickstart.mdx). +## Provider types -## Provider Types - -Devsy supports two kinds of providers: - -### Machine providers - -Machine providers create and manage a VM for the workspace, then run the container on it. They also handle the VM lifecycle - starting, stopping, and deleting it as needed. The AWS provider is one example, using EC2 instances to run the environment. - -### Non-machine providers - -Non-machine providers run the workspace container directly on the target, with no VM to manage. Docker, Podman, Kubernetes, and SSH are examples. - -## Manage Providers - -See [Manage Providers](./manage-providers.mdx) for how to add, configure, update, remove, and rename Devsy providers. +- **Machine providers** create a VM for the workspace, run the container on it, and start, stop, and delete the VM as needed. AWS is an example. +- **Non-machine providers** run the container directly on the target. Docker, Podman, Kubernetes, and SSH are examples. diff --git a/sites/docs-devsy-sh/content/docs/troubleshooting/linux-troubleshooting.mdx b/sites/docs-devsy-sh/content/docs/troubleshooting/linux-troubleshooting.mdx index fba11ec990..0541550692 100644 --- a/sites/docs-devsy-sh/content/docs/troubleshooting/linux-troubleshooting.mdx +++ b/sites/docs-devsy-sh/content/docs/troubleshooting/linux-troubleshooting.mdx @@ -3,133 +3,95 @@ title: Linux Troubleshooting sidebar_label: Linux Troubleshooting --- -This purpose of this page is to outline any known issues with using devsy on Linux and provide known workarounds / fixes. +Known issues and fixes on Linux. -### File permission issues when using a local directory and a remoteUser (or containerUser) +### Files owned by an unknown user after using a local folder -When up'ing a workspace using a local directory, that also specifies a remote container user (via devcontainer.json), the ownership of the directory will change -to the remote user. Since this remote user is in a different user namespace, the ownership will appear as a unknown user. To fix this, simply chown the directory -back to the local user, such as `sudo chown -R $(id -un):$(id -gn) .`. The reason this is necessary is by default, when a new user is created by the container runtime, -such as docker, all files from the host file system will be owned by root during the overlay. For your dev environment to be useful remotely, Devsy needs to -chown the workspace to the remote user. Once the workspace has stopped, you need to change the ownership back. In general local direcotories are typically used -for development, once the devcontainer is working it is better to push the workspace to a git repo and use this. - -### Using FISH shell - -Custom configurations in config.fish file run every time a fish -c command is called, so this processes somewhat get on the way of devsy agent workspace up. - -The solution is to move the customizations inside the if status is-interactive case. - -From this +When you start a workspace from a local folder and `devcontainer.json` sets `remoteUser` or `containerUser`, Devsy changes the folder's ownership to that user so the container can write to it. On the host the owner then shows as an unknown user. After the workspace stops, restore it: +```sh +sudo chown -R $(id -un):$(id -gn) . ``` -if status is-interactive - # Commands to run in interactive sessions can go here -end -eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" -# customizations -``` +Local folders suit early work. Once the devcontainer works, push it to a Git repository and use that instead. + +### Fish shell -to this +Anything in `config.fish` runs on every `fish -c` call, which can interfere with `devsy agent workspace up`. Move your customizations inside the `if status is-interactive` block: ``` if status is-interactive - # Commands to run in interactive sessions can go here eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - # customizations end ``` -### Using SELinux +### SELinux -If you are running SELinux and try to start a workspace with a mounted volume, you may recieve a "Permission Denied" even if the ownership of the files are correct. To resolve -append `:Z` to your volume definitions, like so +With SELinux, a mounted volume can fail with "Permission denied" even when ownership is correct. Add `:Z` to the volume: -``` +```json { - // some fields - "workspaceMount": "", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "runArgs": [ - // other args "--volume=${localWorkspaceFolder}:/workspaces/${localWorkspaceFolderBasename}:Z" ] } ``` -### ENAMETOOLONG error when opening a workspace in vscode +### `ENAMETOOLONG` when opening a workspace in VS Code -There is a [known issue](https://github.com/devsy-org/devsy/issues/1045) where some linux distros use a large PATH to find SSH and causes the connection string to be too long. The workaround is to specify -the SSH binary explicitly in vscode. +Some distributions have a very long `PATH`, which makes the SSH connection string too long. Set the SSH binary explicitly in VS Code. See [issue #1045](https://github.com/devsy-org/devsy/issues/1045). -### Docker socket permission denied +### Docker permission denied or daemon unreachable -If `devsy workspace up` fails with a permission denied error connecting to `docker.sock`, your user is not a member of the `docker` group. Add yourself and re-login: +If `devsy workspace up` fails with a permission error on `docker.sock`, add your user to the `docker` group and log in again: -```bash +```sh sudo usermod -aG docker $USER ``` -If Devsy reports that the Docker daemon is unreachable, start the daemon: +If the daemon is not running, start it: -```bash +```sh sudo systemctl start docker ``` -These failures surface as `code: "UNKNOWN"` with the underlying OS/daemon error text preserved in `message` - see the [Structured CLI errors](./troubleshooting.mdx) reference for details. - ### Podman -#### Rootless socket path +#### Rootless socket -Rootless Podman places its socket at `$XDG_RUNTIME_DIR/podman/podman.sock`. If Devsy cannot connect, it will fail with a "connection refused" or "no such file" style error against that socket path (surfaced as `code: "UNKNOWN"` with the real error text in `message`). Either start the user socket with `systemctl --user start podman.socket`, or set `PODMAN_HOST` explicitly: +Rootless Podman uses the socket `$XDG_RUNTIME_DIR/podman/podman.sock`. If Devsy cannot connect, start the user socket: -```bash -devsy provider set podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/podman.sock +```sh +systemctl --user start podman.socket ``` -#### `podman compose` vs `docker-compose` - -`podman compose` is not a built-in implementation - Podman looks for an externally installed Compose provider (`podman-compose`, or a standalone `docker-compose` binary) and delegates to it. If your `devcontainer.json` or workspace scripts call `docker-compose` directly, they will fail once `docker-compose` itself is not installed. Install a provider first, for example: +Or point Devsy at it: -```bash -sudo apt-get install -y podman-compose +```sh +devsy provider set podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/podman.sock ``` -`docker-compose-plugin` is not a substitute here - it installs the `docker compose` subcommand of the Docker CLI, not a standalone `docker-compose` executable, and it pulls in Docker as a dependency, which defeats the point of a Docker-free Podman setup. - -Verify a provider is available before relying on `podman compose`: +#### `podman compose` -```bash -podman compose version -which docker-compose podman-compose -``` +`podman compose` hands off to an external provider, either `podman-compose` or a standalone `docker-compose`. Install one: -Once a provider is installed, update references to `docker-compose` to use `podman compose`, or add a shell alias as a stopgap: - -```bash -alias docker-compose='podman compose' +```sh +sudo apt-get install -y podman-compose ``` -`devsy workspace up` handles this automatically - Devsy's compose helper detects Podman via the `ContainerRuntime` interface. The alias is only needed for scripts that run inside the workspace itself. - -#### BuildKit not available +Devsy handles this itself when it starts a workspace. You only need it for scripts that run inside the workspace and call `docker-compose`. -Podman uses buildah internally for `podman build`. Dockerfiles with the `# syntax=docker/dockerfile:1` pragma or BuildKit-specific `RUN --mount` syntax will fail. Remove the syntax pragma and restructure affected `RUN` steps to avoid BuildKit mounts. Most standard Dockerfiles build without changes. +#### BuildKit syntax -#### Volume mount permissions in rootless mode +`podman build` uses buildah, so Dockerfiles with the `# syntax=docker/dockerfile:1` line or `RUN --mount` fail. Remove the syntax line and avoid BuildKit mounts. -Rootless Podman maps UIDs through user namespaces. Files created inside the container appear owned by `nobody` on the host. +#### Volume permissions in rootless mode -**With SELinux**: append `:Z` to volume mounts (see [Using SELinux](#using-selinux) above). +Rootless Podman maps user IDs, so files created in the container can appear owned by `nobody` on the host. With SELinux, use `:Z` as above. Without it, fix ownership: -**Without SELinux**: fix ownership with `podman unshare`: - -```bash +```sh podman unshare chown -R $(id -u):$(id -g) /path/to/volume ``` - -If rootless UID mapping is too restrictive for your workflow, run the container as root using `sudo podman` instead. diff --git a/sites/docs-devsy-sh/content/docs/troubleshooting/troubleshooting.mdx b/sites/docs-devsy-sh/content/docs/troubleshooting/troubleshooting.mdx index 16cc7ba4a5..37743c12d0 100644 --- a/sites/docs-devsy-sh/content/docs/troubleshooting/troubleshooting.mdx +++ b/sites/docs-devsy-sh/content/docs/troubleshooting/troubleshooting.mdx @@ -3,59 +3,56 @@ title: Troubleshooting sidebar_label: Troubleshooting --- -This purpose of this page is to outline any known issues with using devsy and provide known workarounds / fixes. +Known issues and workarounds. For Linux-specific problems, see [Linux troubleshooting](./linux-troubleshooting.mdx). ### Utilities not found in PATH -If Devsy Desktop reports that it cannot find utilities in the PATH, you may need to wrap the call in a shell. Something like - -``` -#! /usr/bin/env sh +If Devsy Desktop cannot find tools such as `docker` in your `PATH`, start it through your shell. On macOS: +```sh +#!/usr/bin/env sh exec $SHELL -c 'exec /Applications/Devsy.app/Contents/MacOS/Devsy' ``` -### Port forwarding not working when NOT using an ide +### Port forwarding does not work without an IDE -Devsy relies on an active SSH session to perform port forwarding to the local host. When running Devsy without an IDE, such as `--ide none`, -an active SSH session needs to be open using `devsy workspace ssh {workspace}` (unless you are specifying forwarded ports using docker compose). +Port forwarding needs an open SSH session. With `--ide none`, keep one open with `devsy workspace ssh WORKSPACE_NAME`. Ports declared in Docker Compose do not need it. -### Structured CLI errors +### Reading CLI errors -Devsy classifies common failures and prints a stable error `code` alongside a `message`. Errors are emitted as a JSON object matching: +Pass `--log-output json` to get errors as JSON with a stable `code` and a `message`. Some errors also include a `hint` and a `context` object. ```json { "code": "UNKNOWN", - "message": "exit status 1: Cannot connect to the Docker daemon" + "message": "exit status 1: something failed" } ``` -This happens automatically whenever Devsy detects a non-interactive/machine consumer (for example, stderr is not a TTY, `--log-output json` or `logfmt` is set, or Devsy Desktop invokes the CLI) - human-readable output is used otherwise. Pass `--log-output json` (or `logfmt`) explicitly to force structured errors, or `--log-output text` to force human-readable ones. - -There are only four stable codes: - | Code | Meaning | |---|---| -| `RATE_LIMITED` | An upstream API rate-limited the request. Wait and retry, or authenticate for a higher limit. | -| `PANIC` | Devsy recovered from an internal panic; the message contains the recovered value. | -| `BUILD_FAILED_RECOVERABLE` | The devcontainer build failed in a way that can be retried (e.g. with `--recovery`). | -| `UNKNOWN` | Devsy could not classify the error into one of the above; the raw underlying error text is preserved verbatim in `message`. | - -In practice, most environment-level failures - such as "Docker is not running," "permission denied connecting to docker.sock," or "Podman user socket unavailable" - do not have a dedicated code today. They surface as `code: "UNKNOWN"` with the original OS or daemon error text preserved in `message`. Re-run with `--debug` to see the full original error chain. +| `RATE_LIMITED` | An upstream API rate-limited the request. Wait and retry, or authenticate. | +| `BUILD_FAILED_RECOVERABLE` | The devcontainer build failed in a way that can be retried, for example with `--recovery`. | +| `docker_daemon_unreachable` | Docker is not running or not reachable. | +| `canceled` | The operation was canceled. | +| `deadline_exceeded` | The operation timed out. | +| `unlock_required`, `unlock_failed` | The secrets store is locked, or unlocking it failed. | +| `secret_backend_unavailable` | The secrets backend could not be reached. | +| `secret_store_corrupt` | The secrets store could not be read. | +| `secret_not_found` | The requested secret does not exist. | +| `PANIC` | Devsy hit an internal error. Please report it. | +| `UNKNOWN` | The error was not classified. The original text is in `message`. | + +Run with `--debug` to see the full error chain. ### Windows: `line 2: $'\r': command not found` -Windows line endings break shell scripts inside the container. Add the following to `.gitattributes`: +Windows line endings break shell scripts inside the container. Add this to `.gitattributes`: ``` *.sh eol=lf ``` -### NeoVim: `$TERM` issues over SSH - -NeoVim can misbehave when `$TERM` isn't set correctly over the SSH provider. A workaround is documented in [issue #1187](https://github.com/devsy-org/devsy/issues/1187). - -### VS Code Browser workspace fails to open on first create +### Neovim: `$TERM` issues over SSH -Earlier versions of Devsy could race when bootstrapping the workspace metadata file used by the VS Code Browser tunnel, causing the first browser session to fail right after `devsy workspace up --ide openvscode`. This is fixed - if you previously hit this, re-run `devsy workspace up` on the affected workspace. When Devsy exits because the workspace could not be located, it returns exit code `75`, which parent processes (including Devsy Desktop) treat as a transient signal and retry. +See [issue #1187](https://github.com/devsy-org/devsy/issues/1187) for a workaround. diff --git a/sites/docs-devsy-sh/content/docs/what-is-devsy.mdx b/sites/docs-devsy-sh/content/docs/what-is-devsy.mdx index d419d00504..0116109ba4 100644 --- a/sites/docs-devsy-sh/content/docs/what-is-devsy.mdx +++ b/sites/docs-devsy-sh/content/docs/what-is-devsy.mdx @@ -1,28 +1,22 @@ --- title: What is Devsy? sidebar_label: What is Devsy? -description: Devsy runs devcontainer-based developer workspaces as Docker containers, Kubernetes pods, or microVMs on local machines, remote SSH hosts, or public and private clouds. +description: Devsy runs devcontainer-based developer workspaces on your machine, a remote host, Kubernetes, or a cloud. --- -Devsy enables organizations to scale their engineering operations through standardized, trusted development environments. Environments run as containers, Kubernetes pods, or hardware-isolated microVMs, defined by a [devcontainer.json](https://containers.dev/) that lives alongside your source. [Devsy providers](./managing-providers/what-are-providers) provision those environments on a developer's machine, any reachable remote host, or in a public or private cloud, and you can extend Devsy with your own custom providers. +Devsy creates development workspaces from a [devcontainer.json](https://containers.dev/) that lives in your repository. A workspace runs as a container, a Kubernetes pod, or a microVM, and your IDE connects to it.
Animated demo of launching Devsy, connecting to a workspace, and opening it in an IDE
Devsy
-Devsy connects each developer's local IDE to the infrastructure where the work runs. The same workspace can live on a laptop, a cloud machine, or a shared remote host, and Devsy creates and manages every workspace the same way. That consistency lets a team standardize on one environment definition and move between backends without re-learning their tooling. +Where a workspace runs is decided by a [provider](./managing-providers/what-are-providers). Use a provider for your own machine, an SSH host, Kubernetes, or a cloud. You can also [write your own](./developing-providers/quickstart). Every workspace is created and managed the same way regardless of provider. ## Why Devsy? -Devsy implements the open [DevContainer standard](https://containers.dev/), so the environment definition your team commits remains portable across every backend Devsy supports. - -For engineering organizations, Devsy delivers: -* **Standardized environments**: Define a workspace once in `devcontainer.json` and give every engineer the same toolchain, dependencies, and configuration. New hires are productive on day one instead of spending days on setup. -* **Cost efficiency at scale**: Run workspaces on the infrastructure you already pay for, and let Devsy shut down idle machines so you spend only on capacity in use. -* **No vendor lock-in**: Choose the infrastructure that fits each team - local, cloud, Kubernetes, or remote SSH hosts. Switch a workspace's provider with a single command, with no rewrite of your environment definition. -* **Flexible development**: Engineers get the same experience locally and remotely, from quick prototyping on a laptop to heavy builds on a cloud machine. -* **Cross-IDE support**: VS Code and its variants and the full JetBrains suite are supported out of the box; any other editor can connect over SSH. -* **Extensible**: Devsy is open source and extensible. If a provider doesn't exist for your platform, you can build one. -* **Rich feature set**: Prebuilds, inactivity-based shutdown, and Git and Docker credential sync are built in, with more capabilities on the way. -* **Desktop app and CLI**: The desktop application gives engineers a guided way to manage workspaces, while the CLI drives automation and platform integration across your organization. +- **One environment definition.** `devcontainer.json` is the open standard, so the same file works on every provider. +- **Your infrastructure.** Run workspaces on machines you already pay for. Machine providers can stop idle machines with an [inactivity timeout](./developing-in-workspaces/inactivity-timeout). +- **No lock-in.** Move a workspace to another provider without changing its definition. +- **Your editor.** VS Code, the JetBrains IDEs, and any editor that can connect over SSH. +- **Desktop app and CLI.** The desktop app is for everyday use. The CLI is for automation.