Skip to content
Open
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
7c6a066
initial support
jmcphers Nov 5, 2025
0b9e35b
mount workspace at /workspaces
jmcphers Nov 5, 2025
53e1d38
don't rely on netcat
jmcphers Nov 5, 2025
0e6d91a
build and rebuild in a terminal
jmcphers Nov 5, 2025
ed19e4d
beginning of devcontainer view registration
jmcphers Nov 6, 2025
ffb0230
improve server installer, work on rebuild
jmcphers Nov 6, 2025
999344a
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Nov 6, 2025
0741554
updates for container treeview
jmcphers Nov 7, 2025
8196673
offer to reopen in container; remove dev volumes for now
jmcphers Nov 7, 2025
02b96e0
impl show container log
jmcphers Nov 7, 2025
2575f5a
start, stop, attach
jmcphers Nov 7, 2025
9049270
connection test
jmcphers Nov 7, 2025
c03e9f3
clean all unimplemented commands
jmcphers Nov 7, 2025
0d3f4ea
better compat with barebones images (still need glibc tho)
jmcphers Nov 7, 2025
67bb39c
trap errors when building container
jmcphers Nov 7, 2025
2fe4237
persistence of workspace path for rebuild
jmcphers Nov 10, 2025
18f78c0
handle pending rebuilds
jmcphers Nov 10, 2025
b647aba
remove error trap after build succeeds
jmcphers Nov 10, 2025
caf4c77
encode devcontainer authority more thoroughly
jmcphers Nov 10, 2025
194043c
mapping local/remote workspaces for trust
jmcphers Nov 10, 2025
e9b7f44
encoding url in authority is not going to work
jmcphers Nov 10, 2025
bce0a70
use positron dialogs for modal prompts
jmcphers Nov 10, 2025
1593dc9
let docker assign container names
jmcphers Nov 10, 2025
dfebc3e
use vscode api to read files from inside container
jmcphers Nov 10, 2025
3c6eb7c
fix a couple other problematic usages of nodejs fs api
jmcphers Nov 10, 2025
975b919
show formatted remote status indicator
jmcphers Nov 10, 2025
b06d636
continue to improve workspace/container mapping
jmcphers Nov 13, 2025
bd7ec8d
remove unused details view; update resource formatter
jmcphers Nov 14, 2025
8d5acd3
don't try to use docker with a remote
jmcphers Nov 14, 2025
753d32b
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Nov 14, 2025
d8cf279
improve terminal experience for rebuild
jmcphers Nov 14, 2025
bff5263
show rebuild commands (WIP)
jmcphers Nov 14, 2025
89a383e
action bar options for rebuild/reopen commands
jmcphers Nov 14, 2025
306a13d
icons for rebuild/reopen commands
jmcphers Nov 14, 2025
109b8a7
more reopen fixes; add log viewer for install errors
jmcphers Nov 14, 2025
4c5c171
simplify dev container
jmcphers Nov 14, 2025
3accef7
don't show attach command when already attached
jmcphers Nov 14, 2025
4715be0
clean up logging
jmcphers Nov 15, 2025
3786067
update lockfile
positron-bot[bot] Nov 15, 2025
0d69508
remove positron markers from positron files
jmcphers Nov 15, 2025
50a2c48
mark strings for loc
positron-bot[bot] Nov 15, 2025
5f1e396
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Nov 17, 2025
9a794c4
update branding
jmcphers Nov 18, 2025
2e3c637
refresh view before declaring removal/stop complete
jmcphers Nov 18, 2025
28c6a5b
use more integrated terminal building commands
jmcphers Nov 18, 2025
b816930
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Nov 18, 2025
c42400f
eliminate node-pty
jmcphers Nov 19, 2025
c94af21
add webpack config for release builds
jmcphers Nov 19, 2025
3c034a7
progress towards supporting windows
jmcphers Nov 19, 2025
588782a
support .devcontainer.json at project root
jmcphers Nov 19, 2025
ed36b2f
better error when installation fails
jmcphers Nov 19, 2025
cfe8636
improved server download error propagation
jmcphers Nov 19, 2025
cbd790a
add a default download url
jmcphers Nov 19, 2025
0e56762
show progress while installing server
jmcphers Nov 20, 2025
75775e5
add opt-in feature.
jmcphers Nov 20, 2025
de2337f
add some readmes & note license for src/spec
jmcphers Nov 20, 2025
e24777f
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Nov 21, 2025
db41d14
activate dynamically when enabled
jmcphers Nov 21, 2025
905c9e2
update link; remove unused buildProgress.ts
jmcphers Nov 21, 2025
4a51585
store pending rebuild in workspace state
jmcphers Nov 21, 2025
21c54b7
basic support for features
jmcphers Nov 21, 2025
e71259b
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Nov 24, 2025
5558a17
more robust execution of lifestyle hooks
jmcphers Nov 24, 2025
04e142d
better filter for devcontainer.json
jmcphers Nov 25, 2025
26c45c2
smoother startup if server is already installed
jmcphers Nov 25, 2025
457fda4
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Dec 2, 2025
beca44a
make setting less experimentaly
jmcphers Dec 2, 2025
42b6e8e
remove an unused setting and a lot of unused strings
jmcphers Dec 2, 2025
27949bd
remove remaining unused settings
jmcphers Dec 2, 2025
fb18c48
clean up readme
jmcphers Dec 2, 2025
d24cbc8
disarm CLI in bundled code
jmcphers Dec 2, 2025
c16ad84
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Dec 2, 2025
29e47dc
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Dec 5, 2025
f96f676
support mounts defined with JSON
jmcphers Dec 6, 2025
cb2ae26
disarm all commands when feature is off
jmcphers Dec 6, 2025
f17870b
use error marker instead of exit code
jmcphers Dec 8, 2025
8f2a8f2
better error reporting when failing to detect docker
jmcphers Dec 8, 2025
10b1120
Merge remote-tracking branch 'origin/main' into feature/dev-containers
jmcphers Dec 8, 2025
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
1 change: 1 addition & 0 deletions build/gulpfile.extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const compilations = [
'extensions/positron-catalog-explorer/tsconfig.json',
'extensions/positron-code-cells/tsconfig.json',
'extensions/positron-connections/tsconfig.json',
'extensions/positron-dev-containers/tsconfig.json',
'extensions/positron-duckdb/tsconfig.json',
'extensions/positron-environment/tsconfig.json',
'extensions/positron-ipywidgets/renderer/tsconfig.json',
Expand Down
1 change: 1 addition & 0 deletions build/npm/dirs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const dirs = [
'extensions/positron-code-cells',
'extensions/positron-copilot-chat',
'extensions/positron-connections',
'extensions/positron-dev-containers',
'extensions/positron-duckdb',
'extensions/positron-environment',
'extensions/positron-ipywidgets',
Expand Down
103 changes: 103 additions & 0 deletions extensions/positron-dev-containers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Dev Containers Extension for Positron

## Overview

The Dev Containers extension enables you to open any folder or repository inside a Docker container and take advantage of Positron's full feature set within that containerized environment. This allows you to define your project's dependencies declaratively, install them in a lightweight container, and run the entire project inside the container with a consistent, reproducible development environment.

For compatibility with VS Code, this extension uses most of the same command IDs and setting names from VS Code's version of the extension. The extension itself is novel code, with the exception of the contents of the `spec` folder, which is adapted from the MIT-licensed [dev container reference implementation](https://github.com/devcontainers/cli).

## Requirements

- Docker or Podman installed and running
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna use OrbStack, wish me luck

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it worked! (it's basically the same as docker haha)

- A workspace with a `.devcontainer.json` or `.devcontainer/devcontainer.json` file

## Configuration

Enable the extension in your settings:

```json
{
"dev.containers.enable": true
}
```

## Usage

### Opening a Folder in a Container

1. Open a folder that contains a `.devcontainer.json` file
2. Click the notification prompt, or
3. Use the command palette: **Dev Containers: Reopen in Container**

### Attaching to a Running Container

1. Open the Remote Explorer view
2. Expand the "Dev Containers" section
3. Right-click a running container and select "Attach in Current Window" or "Attach in New Window"

### Rebuilding a Container

When you've made changes to your `devcontainer.json` or `Dockerfile`:

- **Dev Containers: Rebuild Container** - Rebuild using cache
- **Dev Containers: Rebuild Without Cache** - Full rebuild from scratch
- **Dev Containers: Rebuild and Reopen in Container** - Rebuild and automatically reopen

### Key Components

#### Extension Entry Point (`extension.ts`)
- Activates the extension when enabled
- Registers commands, views, and authority resolvers
- Initializes core managers and services
- Handles pending rebuild requests

#### Remote Authority Resolver (`remote/authorityResolver.ts`)
- Resolves `dev-container://` and `attached-container://` URIs
- Manages connections to containers
- Handles workspace folder resolution
- Implements VS Code's remote development protocol

#### Connection Manager (`remote/connectionManager.ts`)
- Manages active connections to containers
- Tracks connection state and lifecycle
- Handles connection failures and recovery
- Coordinates with port forwarding

#### Dev Container Manager (`container/devContainerManager.ts`)
- Creates and starts containers from `devcontainer.json`
- Handles container building and rebuilding
- Manages container lifecycle (start, stop, remove)
- Retrieves container information and logs

#### Server Installer (`server/serverInstaller.ts`)
- Downloads the Positron server for the container platform
- Installs and configures the server inside containers
- Generates connection tokens for secure communication
- Handles server updates and versioning

#### Workspace Mapping Storage (`common/workspaceMappingStorage.ts`)
- Persists mappings between container IDs and workspace paths
- Enables proper workspace resolution across window reloads
- Provides cleanup for stale mappings

### Remote Development Flow

1. **User Action**: User invokes "Reopen in Container"
2. **Container Setup**: Extension reads `devcontainer.json` and creates/starts container
3. **Server Installation**: Positron server is downloaded and installed in container
4. **Authority Resolution**: VS Code resolves the remote authority and establishes connection
5. **Workspace Mapping**: Extension maps local paths to container paths
6. **Port Forwarding**: Necessary ports are forwarded from container to host
7. **Connected**: User can now work with code inside the container

## Known Limitations

- Requires glibc-based Linux since Positron Server builds of Linux require glibc (e.g. Alpine will not work)
- Doesn't support "Create from template"; you need to create Dockerfiles / devcontainer JSON files by hand
- Doesn't support development volumes (popular feature from VS Code's implementation, used for e.g. faster I/O)
- Container management views and features are not available if you are inside a container/remote
- Currently experimental and requires explicit enablement
- Requires Docker or Podman to be installed and running
- GPU support is platform-dependent
- Some features have limited support in containers

17 changes: 17 additions & 0 deletions extensions/positron-dev-containers/extension.webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2025 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

//@ts-check

'use strict';

const withDefaults = require('../shared.webpack.config.mjs').default;

module.exports.default = withDefaults({
context: __dirname,
entry: {
extension: './src/extension.ts',
}
});
Loading
Loading