This project demonstrates how to bundle VS Code extensions into a Dev Container base image and install them when connecting via VS Code Web or Desktop.
- Dockerfile: Downloads extension
.vsixfiles from the VS Code Marketplace during image build - devcontainer.json: Installs the bundled extensions using two different approaches
This example demonstrates two methods for installing bundled extensions:
"customizations": {
"vscode": {
"extensions": [
"/opt/vscode-extensions/prettier-vscode.vsix"
]
}
}| Pros | Cons |
|---|---|
| Installed automatically when VS Code connects | Schema validation warning (undocumented feature) |
| Works with VS Code Web and Desktop | Not part of official devcontainer spec |
No dependency on code CLI availability |
May break in future VS Code versions |
| Reliable across different environments |
"postAttachCommand": "code --install-extension /opt/vscode-extensions/gitlens.vsix --force"| Pros | Cons |
|---|---|
Uses documented code CLI |
code CLI only available in VS Code terminal context |
| No schema warnings | Does not work in all environments (e.g., Gitpod) |
| Runs on every VS Code attach | Requires VS Code to inject the CLI |
Note: The code CLI is injected by VS Code when it attaches. It is not available during:
postCreateCommand(container creation phase)postStartCommand(container start phase)- External terminal sessions
Use postAttachCommand instead of postCreateCommand for CLI-based installation.
- Extensions array (recommended): More reliable across environments, works without CLI dependency
- postAttachCommand: Use when you need documented behavior and your environment supports the
codeCLI
.devcontainer/Dockerfile- Downloads Prettier and GitLens to/opt/vscode-extensions/.devcontainer/devcontainer.json- Demonstrates both installation approaches
To add a different extension:
- Find the extension on the VS Code Marketplace
- Add the download command to
Dockerfile:curl -fsSL "https://marketplace.visualstudio.com/_apis/public/gallery/publishers/{publisher}/vsextensions/{extension-name}/{version}/vspackage" \ -o /opt/vscode-extensions/{name}.vsix.gz \ && gunzip /opt/vscode-extensions/{name}.vsix.gz - Add the extension to
devcontainer.jsonusing either approach
- GitHub Issue #8827 - Schema warning for file path extensions (confirmed working but undocumented)
- Devcontainer Lifecycle - Order of lifecycle hooks