Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A workspace is a containerized development environment that holds a project's so

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 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.
A workspace keeps its state when you stop and restart it. While it is running, it is reachable over SSH at `WORKSPACE_NAME.devsy`. Devsy can open it in a local IDE if you select one.

## Create a workspace

Expand All @@ -21,7 +21,7 @@ Open **Workspaces** and click **Create**. The wizard has five steps:
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.
5. **Launch.** Devsy creates the workspace and streams progress, then opens your IDE if you selected one.

The desktop app runs `devsy workspace up` for you.

Expand Down Expand Up @@ -122,7 +122,7 @@ Only the project folder and mounted volumes survive. Everything else in the cont

## Reset a workspace

A reset starts from a clean slate. It pulls the latest Git changes or uploads your local folder again, and it keeps nothing.
A reset pulls the latest Git changes or uploads your local folder again. For local-folder workspaces, it removes and re-seeds Devsy-managed named workspace volumes. Bind mounts and unmanaged volumes are not removed.

```sh
devsy workspace up my-workspace --reset
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,20 @@ SSH agent forwarding never exposes your private key. It does let anything in the

## Git

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:
Devsy provides HTTPS credentials through a [git credential helper](https://git-scm.com/docs/gitcredentials). To turn off this credential injection in the default context:

```sh
devsy context set default -o SSH_INJECT_GIT_CREDENTIALS=false
```

SSH agent forwarding is separate and enabled by default (`SSH_AGENT_FORWARDING=true`). To disable it in the default context:

```sh
devsy context set default -o SSH_AGENT_FORWARDING=false
```

Disabling HTTPS credential injection does not disable SSH agent forwarding.

## Docker

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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ Pass the repository with `--dotfiles`:
devsy workspace up https://github.com/example/repo --dotfiles https://github.com/my-user/my-dotfiles-repo
```

Devsy then looks in the repository for one of these install scripts and runs the first it finds:
Devsy then looks in the repository for one of these install scripts and uses the first that completes successfully, trying the next script if one fails:

- `install.sh`, `install`
- `bootstrap.sh`, `bootstrap`, `script/bootstrap`
- `setup.sh`, `setup`, `setup/setup`

If there is none, Devsy links every hidden file (names starting with `.`) into the container's `$HOME`.
If no script succeeds, Devsy links hidden files (names starting with `.`) into the container's `$HOME`. It skips directories, so `.config/` needs an install script.

To run a different script, name it:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Option values can be used in this section.

## Stopping idle environments

Devsy tracks whether anyone is connected and stops the environment after the timeout. Nothing is erased. Devsy starts it again when the user returns.
Devsy tracks whether anyone is connected and stops the environment after the timeout. Devsy starts it again when the user returns. State persists only if the provider preserves the storage. A shutdown command that deletes the machine must keep workspace data separately, for example on a persistent volume.

### Non-machine providers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ exec:
exit 1
fi
command: |-
ssh -oStrictHostKeyChecking=no -p ${PORT} "${EXTRA_FLAGS}" "${HOST}" "${COMMAND}"
ssh -oStrictHostKeyChecking=no -p ${PORT} ${EXTRA_FLAGS} "${HOST}" "${COMMAND}"
```
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This walkthrough targets an x86-64 host and guest image. Download the official I

### New Ubuntu 22.04 Virtual machine

With Virtualbox running, open the new virtual machine dialog with 'Machine' > 'New...'.
With VirtualBox running, open the new virtual machine dialog with 'Machine' > 'New...'.

### New virtual machine dialog

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ On macOS or Linux, the quickest option is the install script:
curl -L https://devsy.sh/install.sh | sh
```

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.
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 a matching checksum entry and `sha256sum` or `shasum` are available (otherwise it skips verification), 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:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: What are Machines?
sidebar_label: What are Machines?
---

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.
A machine is the VM a [machine provider](../managing-providers/what-are-providers.mdx) creates to host your workspace. Devsy creates and deletes a dedicated machine with its workspace. A shared machine can host several workspaces and remains until its last workspace is deleted.

To work with machines directly, use:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Show available versions. Add `--prerelease` to include pre-releases and `--no-ca
devsy provider versions <name>
```

Fetch the provider's source again. Without a pinned tag this pulls the latest release. With a pinned tag it fetches that same version.
Fetch the provider's source again. Registry entries and unpinned GitHub repositories resolve to the latest release; a pinned tag fetches that version. Local paths and direct `provider.yaml` URLs reload that source.

```sh
devsy provider set-source <name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ devsy provider set podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/
sudo apt-get install -y podman-compose
```

Devsy handles this itself when it starts a workspace. You only need it for scripts that run inside the workspace and call `docker-compose`.
Install this on the host that runs Podman to support Compose-based workspaces. It does not install Compose inside the workspace container. If workspace scripts call `docker-compose` or `podman compose`, install those tools separately in the container.

#### BuildKit syntax

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ If Devsy Desktop cannot find tools such as `docker` in your `PATH`, start it thr

```sh
#!/usr/bin/env sh
exec $SHELL -c 'exec /Applications/Devsy.app/Contents/MacOS/Devsy'
exec "$SHELL" -lic 'exec /Applications/Devsy.app/Contents/MacOS/Devsy'
```

### Port forwarding does not work without an IDE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Docker provider via WSL
sidebar_label: Docker provider via WSL
---

This tutorial runs a Docker engine inside WSL2 and connects Devsy, running on Windows, to it over SSH. Docker and the project files stay in the WSL filesystem for speed, while Devsy and the editor run on Windows.
This tutorial runs a Docker engine inside WSL2 and connects Devsy, running on Windows, to it over SSH. Docker runs inside WSL, while Devsy and the editor run on Windows. Keep local project files on a Windows drive so Devsy can translate their mount paths into WSL paths.

## Install Docker in WSL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,17 @@ podman machine start

### Windows

Podman runs inside WSL2.
Install the [Windows Podman client](https://podman.io/docs/installation) and its WSL2-backed machine. Run Podman and Devsy from Windows, not from an executable installed only inside a WSL distribution.

1. In PowerShell as Administrator, run `wsl --install` and restart when asked.
2. In your WSL terminal, run `sudo apt-get update && sudo apt-get install -y podman`.
3. Start the rootless API socket. If your distro has systemd:
In PowerShell, initialize and start the machine if it does not already exist:

```bash
systemctl --user enable --now podman.socket
ls -la $XDG_RUNTIME_DIR/podman/podman.sock
```

Without systemd, start the service so it survives closing the terminal:

```bash
setsid nohup podman system service --time=0 unix://$XDG_RUNTIME_DIR/podman/podman.sock >/tmp/podman-service.log 2>&1 &
```
```powershell
podman machine init
podman machine start
podman info
```

4. Note the socket path. You need it for `PODMAN_HOST` below.
Use the Windows named pipe from `podman machine inspect` for `PODMAN_HOST`, as described below. A Unix socket inside WSL is not a Windows endpoint. Check `podman system connection list` and make the connection for this machine the default: Devsy uses the native Podman client as well as the Docker-compatible API.

## Add the provider

Expand All @@ -61,36 +54,55 @@ devsy provider add podman
| Option | Default | Description |
|--------|---------|-------------|
| `PODMAN_PATH` | `podman` | Path to the `podman` binary, if it is not on `PATH`. |
| `PODMAN_HOST` | unset | Podman socket or TCP address. Required on Windows, for example `unix:///run/user/<UID>/podman/podman.sock`, where `<UID>` is the output of `id -u`. |
| `PODMAN_HOST` | unset | Podman API endpoint. On Windows, use the machine named pipe in `npipe:////./pipe/<pipe-name>` form, not a Unix socket inside WSL. On Linux and macOS, use `unix://` followed by the socket path. |
| `PODMAN_ELEVATION` | `none` | Run `podman` through `pkexec`, `sudo` or `doas` to reach a rootful socket the current user cannot access. Leave it as `none` for rootless Podman. `pkexec` needs a desktop session with a polkit agent, so use `sudo` or `doas` on headless hosts. |
| `INACTIVITY_TIMEOUT` | unset | Stop the container after this idle time, for example `10m` or `1h`. |

Set options when adding the provider, or later:
For a provider you already added, update its options:

```bash
devsy provider add podman -o PODMAN_PATH=/usr/local/bin/podman
devsy provider set podman --option PODMAN_PATH=/usr/local/bin/podman
devsy provider get podman
```

Alternatively, set the option during the initial add instead of running the plain add command above:

```bash
devsy provider add podman -o PODMAN_PATH=/usr/local/bin/podman
```

## Rootless and rootful

Rootless is the default and the recommended setup. Containers run as your user. Use rootful only when a container must bind-mount root-owned paths or needs network setups such as macvlan.

On macOS and Windows, switch the Podman machine mode:

For a new machine:

```bash
podman machine init --rootful my-rootful-machine # a new machine
podman machine set --rootful # change the existing machine
podman machine stop && podman machine start
podman machine init --rootful my-rootful-machine
podman machine start --update-connection my-rootful-machine
```

Or switch the existing default machine:

```bash
podman machine stop
podman machine set --rootful
podman machine start
```

Switching mode does not delete images, containers or volumes. They are hidden while the other mode is active and return when you switch back.

On Linux, to reach a rootful socket without running everything as root, set `PODMAN_ELEVATION` to `sudo` or `doas`.

<Callout>
After switching a macOS or Windows machine to rootful, set `PODMAN_HOST` to the rootful socket. Run `podman machine inspect` and read `.ConnectionInfo.PodmanSocket.Path`. Keep `PODMAN_ELEVATION` as `none`, because the machine connection is already authenticated.
After switching modes, run `podman machine inspect <machine-name>` for the machine you started and update `PODMAN_HOST`:

- **macOS:** use `unix://` followed by `.ConnectionInfo.PodmanSocket.Path`.
- **Windows:** read `.ConnectionInfo.PodmanPipe.Path` and use `npipe:////./pipe/<pipe-name>`, replacing `<pipe-name>` with the name after `\\.\pipe\` in that path.

Check `podman system connection list` and select the connection for the same machine and rootful/rootless mode with `podman system connection default <connection-name>`. `PODMAN_HOST` selects the Docker-compatible API; the native Podman CLI uses its own default connection. Keep `PODMAN_ELEVATION` as `none`, because the machine connection is already authenticated.
</Callout>

## Start a workspace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ With the Docker provider, the Docker daemon needs the containerd image store. Me
}
```

Restart Docker, then check that the storage driver is `containerd`:
Restart Docker, then check that the containerd image store is active. The output should include `driver-type io.containerd.snapshotter.v1`:

```
docker info --format '{{.DriverStatus}}'
Expand All @@ -49,4 +49,4 @@ Devsy reads your Dockerfile and `devcontainer.json`, finds the files that affect

## Builds in Kubernetes

With the Kubernetes driver and no container runtime on your machine, Devsy builds the image in the cluster with Kaniko. Kaniko builds in userspace without root, which avoids the risks of Docker in Docker.
With the Kubernetes driver and no container runtime on your machine, Devsy builds the image in the cluster with Kaniko. Kaniko builds in userspace without a Docker daemon. Whether it can run without root depends on the base image and Dockerfile commands.
2 changes: 1 addition & 1 deletion sites/docs-devsy-sh/content/docs/what-is-devsy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ Where a workspace runs is decided by a [provider](./managing-providers/what-are-

- **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.
- **No lock-in.** Recreate a workspace on another provider with the same definition. Transferring container and volume state requires a snapshot; a metadata-only import does not copy that state.
- **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.
Loading