diff --git a/.codesandbox/tasks.json b/.codesandbox/tasks.json
new file mode 100644
index 00000000..070c279c
--- /dev/null
+++ b/.codesandbox/tasks.json
@@ -0,0 +1,25 @@
+{
+ // These tasks will run in order when initializing your CodeSandbox project.
+ "setupTasks": [
+ {
+ "name": "Install dependencies",
+ "command": "bundle install"
+ }
+ ],
+
+ // These tasks can be run from CodeSandbox. Running one will open a log in the app.
+ "tasks": {
+ "bundle exec jekyll serve": {
+ "name": "bundle exec jekyll serve",
+ "command": "bundle exec jekyll serve --host 0.0.0.0",
+ "runAtStart": true,
+ "preview": {
+ "port": 4000
+ }
+ },
+ "ruby:typecheck": {
+ "name": "Typecheck",
+ "command": "solargraph typecheck"
+ }
+ }
+}
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
deleted file mode 100644
index 19e72747..00000000
--- a/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,14 +0,0 @@
-# [Choice] Debian OS version (use bullseye on local arm64/Apple Silicon): bullseye, buster
-ARG VARIANT=bullseye
-FROM mcr.microsoft.com/vscode/devcontainers/jekyll:0-${VARIANT}
-
-# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
-ARG NODE_VERSION="none"
-RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
-
-# [Optional] Uncomment this section to install additional OS packages.
-# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
-# && apt-get -y install --no-install-recommends
-
-# [Optional] Uncomment this line to install global node packages.
-# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1
\ No newline at end of file
diff --git a/.devcontainer/base.Dockerfile b/.devcontainer/base.Dockerfile
deleted file mode 100644
index 9e3296a6..00000000
--- a/.devcontainer/base.Dockerfile
+++ /dev/null
@@ -1,26 +0,0 @@
-# [Choice] Debian OS version (use 2.7-bullseye on local arm64/Apple Silicon): 2.7-bullseye, 2.7-buster
-ARG VARIANT=2.7-bullseye
-FROM mcr.microsoft.com/vscode/devcontainers/ruby:${VARIANT}
-COPY library-scripts/meta.env /usr/local/etc/vscode-dev-containers
-
-# ENV Variables required by Jekyll
-ENV LANG=en_US.UTF-8 \
- LANGUAGE=en_US:en \
- TZ=Etc/UTC \
- LC_ALL=en_US.UTF-8 \
- LANG=en_US.UTF-8 \
- LANGUAGE=en_US
-
-# Install bundler, latest jekyll, and github-pages for older jekyll
-RUN gem install bundler jekyll github-pages
-
-# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
-ARG NODE_VERSION="none"
-RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
-
-# [Optional] Uncomment this section to install additional OS packages.
-# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
-# && apt-get -y install --no-install-recommends
-
-# [Optional] Uncomment this line to install global node packages.
-# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index dffec322..55618006 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,23 +1,16 @@
-// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
-// https://github.com/microsoft/vscode-dev-containers/tree/v0.231.6/containers/jekyll
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/jekyll
{
"name": "Jekyll",
- "build": {
- "dockerfile": "Dockerfile",
- "args": {
- // Update 'VARIANT' to pick a Debian OS version: bullseye, buster
- // Use bullseye when on local arm64/Apple Silicon.
- "VARIANT": "bullseye",
- // Enable Node.js: pick the latest LTS version
- "NODE_VERSION": "lts/*"
- }
- },
-
- // Set *default* container specific settings.json values on container create.
- "settings": {},
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
+ "image": "mcr.microsoft.com/devcontainers/jekyll:2",
- // Add the IDs of extensions you want installed when the container is created.
- "extensions": [],
+ // Features to add to the dev container. More info: https://containers.dev/features.
+ "features": {
+ "ghcr.io/devcontainers/features/node:1": {
+ "version": "latest"
+ }
+ },
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
@@ -25,11 +18,14 @@
4000,
// Live reload server
35729
- ],
+ ]
+
+ // Uncomment the next line to run commands after the container is created.
+ // "postCreateCommand": "jekyll --version"
- // Use 'postCreateCommand' to run commands after the container is created.
- "postCreateCommand": "sh .devcontainer/post-create.sh",
+ // Configure tool-specific properties.
+ // "customizations": {},
- // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
- "remoteUser": "vscode"
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
+ // "remoteUser": "root"
}
diff --git a/.devcontainer/fetch-index.sh b/.devcontainer/fetch-index.sh
deleted file mode 100755
index a5a2aba6..00000000
--- a/.devcontainer/fetch-index.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-pushd /tmp
- curl -LO https://github.com/oras-project/oras/releases/download/v0.13.0/oras_0.13.0_linux_amd64.tar.gz
- mkdir -p oras-install/
- tar -zxf oras_0.13.0_*.tar.gz -C oras-install/
- mv oras-install/oras /usr/local/bin/
- rm -rf oras_0.13.0_*.tar.gz oras-install/
-popd
-
-cd /workspaces/devcontainers.github.io/_data
-oras pull ghcr.io/devcontainers/index:latest
-cp devcontainer-index.json ../static/
\ No newline at end of file
diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh
deleted file mode 100644
index 8c25f3d5..00000000
--- a/.devcontainer/post-create.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-# Install the version of Bundler.
-if [ -f Gemfile.lock ] && grep "BUNDLED WITH" Gemfile.lock > /dev/null; then
- cat Gemfile.lock | tail -n 2 | grep -C2 "BUNDLED WITH" | tail -n 1 | xargs gem install bundler -v
-fi
-
-# If there's a Gemfile, then run `bundle install`
-# It's assumed that the Gemfile will install Jekyll too
-if [ -f Gemfile ]; then
- bundle install
-fi
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..5dc46e6b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+* text=auto eol=lf
+*.{cmd,[cC][mM][dD]} text eol=crlf
+*.{bat,[bB][aA][tT]} text eol=crlf
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..f33a02cd
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for more information:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+# https://containers.dev/guide/dependabot
+
+version: 2
+updates:
+ - package-ecosystem: "devcontainers"
+ directory: "/"
+ schedule:
+ interval: weekly
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..d15e0353
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,35 @@
+
+
+## What type of PR is this?
+
+- [ ] Add a new dev container collection
+- [ ] Update to an existing dev container collection
+- [ ] Documentation/spec update
+- [ ] Other containers.dev site update (UX, layout, etc)
+
+## Related Issues
+
+
+
+- Related Issue #
+- Closes #
+
+## Description
+
+_Please replace this line with a description of your PR._
+
+### Collection checklist
+_If your PR contributes a new collection, please utilize this checklist:_
+- [ ] Collection name
+- [ ] Maintainer name
+- [ ] Maintainer contact link (i.e. link to a GitHub repo, email)
+- [ ] Repository URL
+- [ ] OCI Reference
+- [ ] I acknowledge that this collection provides new functionality, distinct from the existing collections part of this index.
\ No newline at end of file
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index e94d6eb2..858414d1 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -36,6 +36,12 @@ jobs:
mv oras-install/oras /usr/local/bin/
rm -rf oras_0.13.0_*.tar.gz oras-install/
+ - name: Fetch devcontainer-control-manifest.json
+ run: |
+ cd _data
+ oras pull ghcr.io/devcontainers/control-manifest:latest
+ cp devcontainer-control-manifest.json ../static/
+
- name: Fetch devcontainer-index.json
run: |
cd _data
@@ -52,7 +58,7 @@ jobs:
destination: ./_site
- name: Upload artifact
- uses: actions/upload-pages-artifact@v1
+ uses: actions/upload-pages-artifact@v3
# Deployment job
deploy:
@@ -64,4 +70,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
- uses: actions/deploy-pages@v1
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index 535fbe39..df8ee589 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@ npm-debug.log
_site
spec-generator/node_modules
spec-generator/out
-devcontainer-index.json
\ No newline at end of file
+devcontainer-index.json
+devcontainer-control-manifest.json
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index 29414965..84cb538e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source "https://rubygems.org/"
ruby RUBY_VERSION
-gem "jekyll", "3.6.2"
+gem "jekyll", "3.9.3"
# to use GitHub Pages
# gem "github-pages", group: :jekyll_plugins
@@ -11,7 +11,10 @@ group :jekyll_plugins do
gem "jemoji"
gem "github-pages"
gem "jekyll-remote-theme"
+ gem "jekyll-feed"
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
-gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
\ No newline at end of file
+gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
+
+gem 'webrick', '~> 1.7'
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
index 4d917c7d..248f6025 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,231 +1,268 @@
-GEM
- remote: https://rubygems.org/
- specs:
- activesupport (4.2.9)
- i18n (~> 0.7)
- minitest (~> 5.1)
- thread_safe (~> 0.3, >= 0.3.4)
- tzinfo (~> 1.1)
- addressable (2.5.2)
- public_suffix (>= 2.0.2, < 4.0)
- coffee-script (2.4.1)
- coffee-script-source
- execjs
- coffee-script-source (1.11.1)
- colorator (1.1.0)
- concurrent-ruby (1.0.5)
- ethon (0.11.0)
- ffi (>= 1.3.0)
- execjs (2.7.0)
- faraday (0.15.2)
- multipart-post (>= 1.2, < 3)
- ffi (1.9.25)
- forwardable-extended (2.6.0)
- gemoji (3.0.0)
- github-pages (170)
- activesupport (= 4.2.9)
- github-pages-health-check (= 1.3.5)
- jekyll (= 3.6.2)
- jekyll-avatar (= 0.5.0)
- jekyll-coffeescript (= 1.0.2)
- jekyll-default-layout (= 0.1.4)
- jekyll-feed (= 0.9.2)
- jekyll-gist (= 1.4.1)
- jekyll-github-metadata (= 2.9.3)
- jekyll-mentions (= 1.2.0)
- jekyll-optional-front-matter (= 0.3.0)
- jekyll-paginate (= 1.1.0)
- jekyll-readme-index (= 0.2.0)
- jekyll-redirect-from (= 0.12.1)
- jekyll-relative-links (= 0.5.2)
- jekyll-sass-converter (= 1.5.0)
- jekyll-seo-tag (= 2.3.0)
- jekyll-sitemap (= 1.1.1)
- jekyll-swiss (= 0.4.0)
- jekyll-theme-architect (= 0.1.0)
- jekyll-theme-cayman (= 0.1.0)
- jekyll-theme-dinky (= 0.1.0)
- jekyll-theme-hacker (= 0.1.0)
- jekyll-theme-leap-day (= 0.1.0)
- jekyll-theme-merlot (= 0.1.0)
- jekyll-theme-midnight (= 0.1.0)
- jekyll-theme-minimal (= 0.1.0)
- jekyll-theme-modernist (= 0.1.0)
- jekyll-theme-primer (= 0.5.2)
- jekyll-theme-slate (= 0.1.0)
- jekyll-theme-tactile (= 0.1.0)
- jekyll-theme-time-machine (= 0.1.0)
- jekyll-titles-from-headings (= 0.5.0)
- jemoji (= 0.8.1)
- kramdown (= 1.14.0)
- liquid (= 4.0.0)
- listen (= 3.0.6)
- mercenary (~> 0.3)
- minima (= 2.1.1)
- rouge (= 2.2.1)
- terminal-table (~> 1.4)
- github-pages-health-check (1.3.5)
- addressable (~> 2.3)
- net-dns (~> 0.8)
- octokit (~> 4.0)
- public_suffix (~> 2.0)
- typhoeus (~> 0.7)
- html-pipeline (2.8.0)
- activesupport (>= 2)
- nokogiri (>= 1.4)
- i18n (0.9.5)
- concurrent-ruby (~> 1.0)
- jekyll (3.6.2)
- addressable (~> 2.4)
- colorator (~> 1.0)
- jekyll-sass-converter (~> 1.0)
- jekyll-watch (~> 1.1)
- kramdown (~> 1.14)
- liquid (~> 4.0)
- mercenary (~> 0.3.3)
- pathutil (~> 0.9)
- rouge (>= 1.7, < 3)
- safe_yaml (~> 1.0)
- jekyll-avatar (0.5.0)
- jekyll (~> 3.0)
- jekyll-coffeescript (1.0.2)
- coffee-script (~> 2.2)
- coffee-script-source (~> 1.11.1)
- jekyll-default-layout (0.1.4)
- jekyll (~> 3.0)
- jekyll-feed (0.9.2)
- jekyll (~> 3.3)
- jekyll-gist (1.4.1)
- octokit (~> 4.2)
- jekyll-github-metadata (2.9.3)
- jekyll (~> 3.1)
- octokit (~> 4.0, != 4.4.0)
- jekyll-mentions (1.2.0)
- activesupport (~> 4.0)
- html-pipeline (~> 2.3)
- jekyll (~> 3.0)
- jekyll-optional-front-matter (0.3.0)
- jekyll (~> 3.0)
- jekyll-paginate (1.1.0)
- jekyll-readme-index (0.2.0)
- jekyll (~> 3.0)
- jekyll-redirect-from (0.12.1)
- jekyll (~> 3.3)
- jekyll-relative-links (0.5.2)
- jekyll (~> 3.3)
- jekyll-remote-theme (0.3.1)
- jekyll (~> 3.5)
- rubyzip (>= 1.2.1, < 3.0)
- jekyll-sass-converter (1.5.0)
- sass (~> 3.4)
- jekyll-seo-tag (2.3.0)
- jekyll (~> 3.3)
- jekyll-sitemap (1.1.1)
- jekyll (~> 3.3)
- jekyll-swiss (0.4.0)
- jekyll-theme-architect (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-cayman (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-dinky (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-hacker (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-leap-day (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-merlot (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-midnight (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-minimal (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-modernist (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-primer (0.5.2)
- jekyll (~> 3.5)
- jekyll-github-metadata (~> 2.9)
- jekyll-seo-tag (~> 2.2)
- jekyll-theme-slate (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-tactile (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-theme-time-machine (0.1.0)
- jekyll (~> 3.5)
- jekyll-seo-tag (~> 2.0)
- jekyll-titles-from-headings (0.5.0)
- jekyll (~> 3.3)
- jekyll-watch (1.5.1)
- listen (~> 3.0)
- jemoji (0.8.1)
- activesupport (~> 4.0, >= 4.2.9)
- gemoji (~> 3.0)
- html-pipeline (~> 2.2)
- jekyll (>= 3.0)
- kramdown (1.14.0)
- liquid (4.0.0)
- listen (3.0.6)
- rb-fsevent (>= 0.9.3)
- rb-inotify (>= 0.9.7)
- mercenary (0.3.6)
- mini_portile2 (2.3.0)
- minima (2.1.1)
- jekyll (~> 3.3)
- minitest (5.11.3)
- multipart-post (2.0.0)
- net-dns (0.8.0)
- nokogiri (1.8.2)
- mini_portile2 (~> 2.3.0)
- octokit (4.9.0)
- sawyer (~> 0.8.0, >= 0.5.3)
- pathutil (0.16.1)
- forwardable-extended (~> 2.6)
- public_suffix (2.0.5)
- rb-fsevent (0.10.3)
- rb-inotify (0.9.10)
- ffi (>= 0.5.0, < 2)
- rouge (2.2.1)
- rubyzip (1.2.1)
- safe_yaml (1.0.4)
- sass (3.5.6)
- sass-listen (~> 4.0.0)
- sass-listen (4.0.0)
- rb-fsevent (~> 0.9, >= 0.9.4)
- rb-inotify (~> 0.9, >= 0.9.7)
- sawyer (0.8.1)
- addressable (>= 2.3.5, < 2.6)
- faraday (~> 0.8, < 1.0)
- terminal-table (1.8.0)
- unicode-display_width (~> 1.1, >= 1.1.1)
- thread_safe (0.3.6)
- typhoeus (0.8.0)
- ethon (>= 0.8.0)
- tzinfo (1.2.5)
- thread_safe (~> 0.1)
- unicode-display_width (1.4.0)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- github-pages
- jekyll (= 3.6.2)
- jekyll-remote-theme
- jemoji
- tzinfo-data
-
-RUBY VERSION
- ruby 2.7.6p219
-
-BUNDLED WITH
- 2.3.24
+GEM
+ remote: https://rubygems.org/
+ specs:
+ activesupport (7.0.4.3)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ addressable (2.8.4)
+ public_suffix (>= 2.0.2, < 6.0)
+ coffee-script (2.4.1)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.11.1)
+ colorator (1.1.0)
+ commonmarker (0.23.9)
+ concurrent-ruby (1.2.2)
+ dnsruby (1.70.0)
+ simpleidn (~> 0.2.1)
+ em-websocket (0.5.3)
+ eventmachine (>= 0.12.9)
+ http_parser.rb (~> 0)
+ ethon (0.16.0)
+ ffi (>= 1.15.0)
+ eventmachine (1.2.7)
+ execjs (2.8.1)
+ faraday (2.7.4)
+ faraday-net_http (>= 2.0, < 3.1)
+ ruby2_keywords (>= 0.0.4)
+ faraday-net_http (3.0.2)
+ ffi (1.15.5)
+ forwardable-extended (2.6.0)
+ gemoji (3.0.1)
+ github-pages (228)
+ github-pages-health-check (= 1.17.9)
+ jekyll (= 3.9.3)
+ jekyll-avatar (= 0.7.0)
+ jekyll-coffeescript (= 1.1.1)
+ jekyll-commonmark-ghpages (= 0.4.0)
+ jekyll-default-layout (= 0.1.4)
+ jekyll-feed (= 0.15.1)
+ jekyll-gist (= 1.5.0)
+ jekyll-github-metadata (= 2.13.0)
+ jekyll-include-cache (= 0.2.1)
+ jekyll-mentions (= 1.6.0)
+ jekyll-optional-front-matter (= 0.3.2)
+ jekyll-paginate (= 1.1.0)
+ jekyll-readme-index (= 0.3.0)
+ jekyll-redirect-from (= 0.16.0)
+ jekyll-relative-links (= 0.6.1)
+ jekyll-remote-theme (= 0.4.3)
+ jekyll-sass-converter (= 1.5.2)
+ jekyll-seo-tag (= 2.8.0)
+ jekyll-sitemap (= 1.4.0)
+ jekyll-swiss (= 1.0.0)
+ jekyll-theme-architect (= 0.2.0)
+ jekyll-theme-cayman (= 0.2.0)
+ jekyll-theme-dinky (= 0.2.0)
+ jekyll-theme-hacker (= 0.2.0)
+ jekyll-theme-leap-day (= 0.2.0)
+ jekyll-theme-merlot (= 0.2.0)
+ jekyll-theme-midnight (= 0.2.0)
+ jekyll-theme-minimal (= 0.2.0)
+ jekyll-theme-modernist (= 0.2.0)
+ jekyll-theme-primer (= 0.6.0)
+ jekyll-theme-slate (= 0.2.0)
+ jekyll-theme-tactile (= 0.2.0)
+ jekyll-theme-time-machine (= 0.2.0)
+ jekyll-titles-from-headings (= 0.5.3)
+ jemoji (= 0.12.0)
+ kramdown (= 2.3.2)
+ kramdown-parser-gfm (= 1.1.0)
+ liquid (= 4.0.4)
+ mercenary (~> 0.3)
+ minima (= 2.5.1)
+ nokogiri (>= 1.13.6, < 2.0)
+ rouge (= 3.26.0)
+ terminal-table (~> 1.4)
+ github-pages-health-check (1.17.9)
+ addressable (~> 2.3)
+ dnsruby (~> 1.60)
+ octokit (~> 4.0)
+ public_suffix (>= 3.0, < 5.0)
+ typhoeus (~> 1.3)
+ html-pipeline (2.14.3)
+ activesupport (>= 2)
+ nokogiri (>= 1.4)
+ http_parser.rb (0.8.0)
+ i18n (1.12.0)
+ concurrent-ruby (~> 1.0)
+ jekyll (3.9.3)
+ addressable (~> 2.4)
+ colorator (~> 1.0)
+ em-websocket (~> 0.5)
+ i18n (>= 0.7, < 2)
+ jekyll-sass-converter (~> 1.0)
+ jekyll-watch (~> 2.0)
+ kramdown (>= 1.17, < 3)
+ liquid (~> 4.0)
+ mercenary (~> 0.3.3)
+ pathutil (~> 0.9)
+ rouge (>= 1.7, < 4)
+ safe_yaml (~> 1.0)
+ jekyll-avatar (0.7.0)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-coffeescript (1.1.1)
+ coffee-script (~> 2.2)
+ coffee-script-source (~> 1.11.1)
+ jekyll-commonmark (1.4.0)
+ commonmarker (~> 0.22)
+ jekyll-commonmark-ghpages (0.4.0)
+ commonmarker (~> 0.23.7)
+ jekyll (~> 3.9.0)
+ jekyll-commonmark (~> 1.4.0)
+ rouge (>= 2.0, < 5.0)
+ jekyll-default-layout (0.1.4)
+ jekyll (~> 3.0)
+ jekyll-feed (0.15.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-gist (1.5.0)
+ octokit (~> 4.2)
+ jekyll-github-metadata (2.13.0)
+ jekyll (>= 3.4, < 5.0)
+ octokit (~> 4.0, != 4.4.0)
+ jekyll-include-cache (0.2.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-mentions (1.6.0)
+ html-pipeline (~> 2.3)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-optional-front-matter (0.3.2)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-paginate (1.1.0)
+ jekyll-readme-index (0.3.0)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-redirect-from (0.16.0)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-relative-links (0.6.1)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-remote-theme (0.4.3)
+ addressable (~> 2.0)
+ jekyll (>= 3.5, < 5.0)
+ jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
+ rubyzip (>= 1.3.0, < 3.0)
+ jekyll-sass-converter (1.5.2)
+ sass (~> 3.4)
+ jekyll-seo-tag (2.8.0)
+ jekyll (>= 3.8, < 5.0)
+ jekyll-sitemap (1.4.0)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-swiss (1.0.0)
+ jekyll-theme-architect (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-cayman (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-dinky (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-hacker (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-leap-day (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-merlot (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-midnight (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-minimal (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-modernist (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-primer (0.6.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-github-metadata (~> 2.9)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-slate (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-tactile (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-time-machine (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-titles-from-headings (0.5.3)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-watch (2.2.1)
+ listen (~> 3.0)
+ jemoji (0.12.0)
+ gemoji (~> 3.0)
+ html-pipeline (~> 2.2)
+ jekyll (>= 3.0, < 5.0)
+ kramdown (2.3.2)
+ rexml
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ liquid (4.0.4)
+ listen (3.8.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ mercenary (0.3.6)
+ minima (2.5.1)
+ jekyll (>= 3.5, < 5.0)
+ jekyll-feed (~> 0.9)
+ jekyll-seo-tag (~> 2.1)
+ minitest (5.18.0)
+ nokogiri (1.14.3-x86_64-linux)
+ racc (~> 1.4)
+ octokit (4.25.1)
+ faraday (>= 1, < 3)
+ sawyer (~> 0.9)
+ pathutil (0.16.2)
+ forwardable-extended (~> 2.6)
+ public_suffix (4.0.7)
+ racc (1.6.2)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ rexml (3.2.5)
+ rouge (3.26.0)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.3.2)
+ safe_yaml (1.0.5)
+ sass (3.7.4)
+ sass-listen (~> 4.0.0)
+ sass-listen (4.0.0)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
+ sawyer (0.9.2)
+ addressable (>= 2.3.5)
+ faraday (>= 0.17.3, < 3)
+ simpleidn (0.2.1)
+ unf (~> 0.1.4)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ typhoeus (1.4.0)
+ ethon (>= 0.9.0)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.8.2)
+ unicode-display_width (1.8.0)
+ webrick (1.8.1)
+
+PLATFORMS
+ x86_64-linux
+
+DEPENDENCIES
+ github-pages
+ jekyll (= 3.9.3)
+ jekyll-feed
+ jekyll-remote-theme
+ jemoji
+ tzinfo-data
+ webrick (~> 1.7)
+
+RUBY VERSION
+ ruby 3.2.2p53
+
+BUNDLED WITH
+ 2.4.10
diff --git a/README.md b/README.md
index 5b35dcb2..ad707b3b 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ You may build GitHub Pages sites with [Jekyll](https://jekyllrb.com/), which is
You may review this repo's dev container in the [`.devcontainer`](https://github.com/devcontainers/containers.dev/tree/gh-pages/.devcontainer) folder.
-It is from this [Jekyll definition](https://github.com/microsoft/vscode-dev-containers/tree/main/containers/jekyll).
+It is from this [Jekyll Dev Container Template](https://github.com/devcontainers/templates/tree/main/src/jekyll).
### Steps to build and run
diff --git a/_config.yml b/_config.yml
index be76bda5..f8cf0b94 100644
--- a/_config.yml
+++ b/_config.yml
@@ -7,6 +7,7 @@ description: >
url: https://devcontainers.github.io # the base hostname & protocol for your site
git_address: https://github.com/devcontainers/devcontainers.github.io
git_edit_address: https://github.com/devcontainers/devcontainers.github.io/settings/pages/blob/gh-pages
+theme_color: 2753E3
# Build settings
markdown: kramdown
@@ -15,6 +16,7 @@ highlighter: rouge
plugins:
- github-pages
- jemoji
+ - jekyll-feed
exclude:
@@ -33,7 +35,7 @@ defaults:
type: posts
values:
layout: post
- sectionid: blog
+ sectionid: guide
- scope:
path: _docs
@@ -56,7 +58,7 @@ collections:
permalink: /:collection/:path/
output: true
posts:
- permalink: /blog/:year/:month/:day/:title/
+ permalink: /guide/:title
output: true
implementors:
permalink: /:collection/:path/
diff --git a/_data/collection-index.yml b/_data/collection-index.yml
index 3feb8b5c..61fd55ae 100644
--- a/_data/collection-index.yml
+++ b/_data/collection-index.yml
@@ -8,6 +8,11 @@
contact: https://github.com/devcontainers/templates/issues
repository: https://github.com/devcontainers/templates
ociReference: ghcr.io/devcontainers/templates
+- name: Azure SQL Database Dev Container Templates
+ maintainer: Azure SQL Developer Experiences Team
+ contact: https://github.com/microsoft/azuresql-devcontainers/issues
+ repository: https://github.com/microsoft/azuresql-devcontainers
+ ociReference: ghcr.io/microsoft/azuresql-devcontainers
- name: Iterative Tools for Machine Learning Features
maintainer: Iterative, Inc
contact: https://github.com/iterative/features/issues
@@ -28,21 +33,11 @@
contact: https://github.com/meaningful-ooo/devcontainer-features/issues
repository: https://github.com/meaningful-ooo/devcontainer-features
ociReference: ghcr.io/meaningful-ooo/devcontainer-features
-- name: Legacy Community Templates
- maintainer: Deprecated (No longer maintained)
- contact: https://github.com/microsoft/vscode-dev-containers/issues/1589
- repository: https://github.com/microsoft/vscode-dev-containers
- ociReference: ghcr.io/microsoft/vscode-dev-containers
- name: Assorted Features
maintainer: Mike Priscella
contact: https://github.com/mpriscella/features/issues
repository: https://github.com/mpriscella/features
ociReference: ghcr.io/mpriscella/features
-- name: DevContainers-Contrib Features
- maintainer: Daniel Braun
- contact: https://github.com/devcontainers-contrib/features/issues
- repository: https://github.com/devcontainers-contrib/features
- ociReference: ghcr.io/devcontainers-contrib/features
- name: Assorted Features
maintainer: eitsupi
contact: https://github.com/eitsupi/devcontainer-features/issues
@@ -83,8 +78,1063 @@
contact: https://github.com/joshspicer/features/issues
repository: https://github.com/joshspicer/features
ociReference: ghcr.io/joshspicer/features
-- name: pnpm (requires npm)
- maintainer: NicoVIII
- contact: https://github.com/NicoVIII/devcontainer-features/issues
- repository: https://github.com/NicoVIII/devcontainer-features
- ociReference: ghcr.io/NicoVIII/devcontainer-features
+- name: PHP Features
+ maintainer: Shyim
+ contact: https://github.com/shyim/devcontainers-features/issues
+ repository: https://github.com/shyim/devcontainers-features
+ ociReference: ghcr.io/shyim/devcontainers-features
+- name: Fun Features
+ maintainer: jungaretti
+ contact: https://github.com/jungaretti/features/issues
+ repository: https://github.com/jungaretti/features
+ ociReference: ghcr.io/jungaretti/features
+- name: libmsquic feature for HTTP/3 support
+ maintainer: tlc-sundown
+ contact: https://github.com/tlc-sundown/devcontainers-features/issues
+ repository: https://github.com/tlc-sundown/devcontainers-features
+ ociReference: ghcr.io/tlc-sundown/devcontainers-features
+- name: Assorted Features
+ maintainer: Enrico Secondulfo
+ contact: https://github.com/enricosecondulfo/devcontainer-features/issues
+ repository: https://github.com/enricosecondulfo/devcontainer-features
+ ociReference: ghcr.io/enricosecondulfo/devcontainer-features
+- name: SAML.to Development Container Features
+ maintainer: saml-to
+ contact: https://github.com/saml-to/devcontainer-features/issues
+ repository: https://github.com/saml-to/devcontainer-features
+ ociReference: ghcr.io/saml-to/devcontainer-features
+- name: Cloud Native development environment tools
+ maintainer: rjfmachado
+ contact: https://github.com/rjfmachado/devcontainer-features/issues
+ repository: https://github.com/rjfmachado/devcontainer-features
+ ociReference: ghcr.io/rjfmachado/devcontainer-features
+- name: Wiwa's features
+ maintainer: lukewiwa
+ contact: https://github.com/lukewiwa/features/issues
+ repository: https://github.com/lukewiwa/features
+ ociReference: ghcr.io/lukewiwa/features
+- name: Container and Kubernetes Development Features
+ maintainer: rio
+ contact: https://github.com/rio/features/issues
+ repository: https://github.com/rio/features
+ ociReference: ghcr.io/rio/features
+- name: Kusion Features
+ maintainer: KusionStack
+ contact: https://github.com/KusionStack/devcontainer-features/issues
+ repository: https://github.com/KusionStack/devcontainer-features
+ ociReference: ghcr.io/KusionStack/devcontainer-features
+- name: Édouard-lopez' Features
+ maintainer: edouard-lopez
+ contact: https://github.com/edouard-lopez/devcontainer-features/issues
+ repository: https://github.com/edouard-lopez/devcontainer-features
+ ociReference: ghcr.io/edouard-lopez/devcontainer-features
+- name: jlaundry Features
+ maintainer: jlaundry
+ contact: https://github.com/jlaundry/devcontainer-features/issues
+ repository: https://github.com/jlaundry/devcontainer-features
+ ociReference: ghcr.io/jlaundry/devcontainer-features
+- name: Assorted Features
+ maintainer: mikaello
+ contact: https://github.com/mikaello/devcontainer-features/issues
+ repository: https://github.com/mikaello/devcontainer-features
+ ociReference: ghcr.io/mikaello/devcontainer-features
+- name: Devcontainer Features
+ maintainer: jsburckhardt
+ contact: https://github.com/jsburckhardt/devcontainer-features/issues
+ repository: https://github.com/jsburckhardt/devcontainer-features
+ ociReference: ghcr.io/jsburckhardt/devcontainer-features
+- name: Oleksis' Dev Container Features
+ maintainer: oleksis
+ contact: https://github.com/oleksis/devcontainer-features/issues
+ repository: https://github.com/oleksis/devcontainer-features
+ ociReference: ghcr.io/oleksis/devcontainer-features
+- name: Psibase templates
+ maintainer: James-Mart
+ contact: https://github.com/gofractally/psibase-devcontainer-template/issues
+ repository: https://github.com/gofractally/psibase-devcontainer-template/issues
+ ociReference: ghcr.io/gofractally/psibase-devcontainer-template
+- name: Baskoro OSI devcontainer features
+ maintainer: Eki Baskoro
+ contact: https://github.com/ebaskoro/devcontainer-features/issues
+ repository: https://github.com/ebaskoro/devcontainer-features
+ ociReference: ghcr.io/ebaskoro/devcontainer-features
+- name: A collection of useful GitHub CodeSpace features
+ maintainer: Warren Buckley
+ contact: https://github.com/warrenbuckley/codespace-features/issues
+ repository: https://github.com/warrenbuckley/codespace-features
+ ociReference: ghcr.io/warrenbuckley/codespace-features
+- name: Roost Cluster
+ maintainer: Roost.ai (Harish Agrawal)
+ contact: https://github.com/roost-io/features/issues
+ repository: https://github.com/roost-io/features
+ ociReference: ghcr.io/roost-io/features
+- name: lentzi90 devcontainer features
+ maintainer: Lennart Jern
+ contact: https://github.com/lentzi90/features/issues
+ repository: https://github.com/lentzi90/features
+ ociReference: ghcr.io/lentzi90/features
+- name: Nextflow devcontainer features
+ maintainer: Rob Syme
+ contact: https://github.com/robsyme/features/issues
+ repository: https://github.com/robsyme/features
+ ociReference: ghcr.io/robsyme/features
+- name: Wasmtime + WASI Web Assembly features
+ contact: https://github.com/dev-wasm/dev-wasm-feature/issues
+ repository: https://github.com/dev-wasm/dev-wasm-feature
+ maintainer: Brendan Burns
+ ociReference: devwasm.azurecr.io/dev-wasm/dev-wasm-feature
+- name: shinepukur devcontainer features
+ maintainer: Shine Pukur
+ contact: https://github.com/shinepukur/devcontainer-features/issues
+ repository: https://github.com/shinepukur/devcontainer-features
+ ociReference: ghcr.io/shinepukur/devcontainer-features
+- name: msclock devcontainer features
+ maintainer: msclock
+ contact: https://github.com/msclock/features/issues
+ repository: https://github.com/msclock/features
+ ociReference: ghcr.io/msclock/features
+- name: Fig Dev Container Features
+ maintainer: grant0417
+ contact: https://github.com/withfig/features/issues
+ repository: https://github.com/withfig/features
+ ociReference: ghcr.io/withfig/features
+- name: Mamba Features
+ maintainer: mamba-org
+ contact: https://github.com/mamba-org/devcontainer-features/issues
+ repository: https://github.com/mamba-org/devcontainer-features
+ ociReference: ghcr.io/mamba-org/devcontainer-features
+- name: Astronomer Features
+ maintainer: fhoda
+ contact: https://github.com/astronomer/devcontainer-features/issues
+ repository: https://github.com/astronomer/devcontainer-features
+ ociReference: ghcr.io/astronomer/devcontainer-features
+- name: Devcontainer features by @EliiseS
+ maintainer: EliiseS
+ contact: https://github.com/EliiseS/devcontainer-features/issues
+ repository: https://github.com/EliiseS/devcontainer-features
+ ociReference: ghcr.io/eliises/devcontainer-features
+- name: Testing Automation Features & more
+ maintainer: Matthieu Fronton
+ contact: https://github.com/frntn/devcontainers-features/issues
+ repository: https://github.com/frntn/devcontainers-features
+ ociReference: ghcr.io/frntn/devcontainers-features
+- name: csutter's devcontainer templates
+ maintainer: csutter
+ contact: https://github.com/csutter/devcontainer-templates/issues
+ repository: https://github.com/csutter/devcontainer-templates
+ ociReference: ghcr.io/csutter/devcontainer-templates
+- name: Convenient features
+ maintainer: ChristopherMacGown
+ contact: https://github.com/ChristopherMacGown/devcontainer-features/issues
+ repository: https://github.com/ChristopherMacGown/devcontainer-features
+ ociReference: ghcr.io/christophermacgown/devcontainer-features
+- name: Devcontainer features by @Balazs
+ maintainer: Balazs23
+ contact: https://github.com/Balazs23/devcontainers-features/issues
+ repository: https://github.com/Balazs23/devcontainers-features
+ ociReference: ghcr.io/balazs23/devcontainers-features
+- name: Pwd9000-ML devcontainer templates
+ maintainer: Marcel Lupo @Pwd9000-ML
+ contact: https://github.com/Pwd9000-ML/devcontainer-templates/issues
+ repository: https://github.com/Pwd9000-ML/devcontainer-templates
+ ociReference: ghcr.io/pwd9000-ml/devcontainer-templates
+- name: mickeahlinder devcontainer features
+ maintainer: Mikael Ahlinder
+ contact: https://github.com/mickeahlinder/devcontainer-features/issues
+ repository: https://github.com/mickeahlinder/devcontainer-features
+ ociReference: ghcr.io/mickeahlinder/devcontainer-features
+- name: jckimble Dev Container / Codespaces Features
+ maintainer: James C Kimble Jr
+ contact: https://github.com/jckimble/devcontainer-features/issues
+ repository: https://github.com/jckimble/devcontainer-features
+ ociReference: ghcr.io/jckimble/devcontainer-features
+- name: IU LaTeX Container Templates
+ maintainer: Torben Wetter
+ contact: https://github.com/TorbenWetter/iu-latex-container-templates/issues
+ repository: https://github.com/TorbenWetter/iu-latex-container-templates
+ ociReference: ghcr.io/torbenwetter/iu-latex-container-templates
+- name: Python3 with Pyenv and Poetry
+ maintainer: Israel Rescalvo
+ contact: https://github.com/Standard-IO/devcontainers-templates/issues
+ repository: https://github.com/Standard-IO/devcontainers-templates
+ ociReference: ghcr.io/standard-io/devcontainers-templates
+- name: ROS Templates
+ maintainer: Kenji Brameld
+ contact: https://github.com/ijnek/ros-devcontainer-template/issues
+ repository: https://github.com/ijnek/ros-devcontainer-template
+ ociReference: ghcr.io/ijnek/ros-devcontainer-template
+- name: ROS 2 Workspace Templates
+ maintainer: Bruno-Pier Busque
+ contact: https://github.com/BrunoB81HK/ros2-workspace-devcontainer-template/issues
+ repository: https://github.com/BrunoB81HK/ros2-workspace-devcontainer-template
+ ociReference: ghcr.io/brunob81hk/ros2-workspace-devcontainer-template
+- name: Assorted Features
+ maintainer: r3dpoint
+ contact: https://github.com/r3dpoint/devcontainer-features/issues
+ repository: https://github.com/r3dpoint/devcontainer-features
+ ociReference: ghcr.io/r3dpoint/devcontainer-features
+- name: Swift Container Templates
+ maintainer: Swift Server Workgroup
+ contact: https://github.com/swift-server/swift-devcontainer-template/issues
+ repository: https://github.com/swift-server/swift-devcontainer-template
+ ociReference: ghcr.io/swift-server/swift-devcontainer-template
+- name: UNSW cs3231 OS Development
+ maintainer: Hamish Cox
+ contact: https://github.com/HamishWHC/cs3231-devcontainer/issues
+ repository: https://github.com/HamishWHC/cs3231-devcontainer
+ ociReference: ghcr.io/hamishwhc/cs3231-devcontainer
+- name: TRunk CLI Features (trunk.io)
+ maintainer: trunk-io
+ contact: https://github.com/trunk-io/devcontainer-feature/issues
+ repository: https://github.com/trunk-io/devcontainer-feature
+ ociReference: ghcr.io/trunk-io/devcontainer-feature
+- name: MultiversX Dev Container Templates
+ maintainer: MultiversX
+ contact: https://github.com/multiversx/mx-template-devcontainers/issues
+ repository: https://github.com/multiversx/mx-template-devcontainers
+ ociReference: ghcr.io/multiversx/mx-template-devcontainers
+- name: Swift Dev Container Features
+ maintainer: Joseph Heck/Adam Fowler
+ contact: https://github.com/swift-server-community/swift-devcontainer-features/issues
+ repository: https://github.com/swift-server-community/swift-devcontainer-features
+ ociReference: ghcr.io/swift-server-community/swift-devcontainer-features
+- name: Kvokka Dev Container Features
+ maintainer: kvokka
+ contact: https://github.com/kvokka/features/issues
+ repository: https://github.com/kvokka/features
+ ociReference: ghcr.io/kvokka/features
+- name: gickis Dev Container Features
+ maintainer: Andrii Tararaka
+ contact: https://github.com/gickis/devcontainer-features/issues
+ repository: https://github.com/gickis/devcontainer-features
+ ociReference: ghcr.io/gickis/devcontainer-features
+- name: sonikro Dev Container Features
+ maintainer: Jonathan Nagayoshi
+ contact: https://github.com/sonikro/devcontainer-features/issues
+ repository: https://github.com/sonikro/devcontainer-features
+ ociReference: ghcr.io/sonikro/devcontainer-features
+- name: Features by JasonTheDeveloper
+ maintainer: JasonTheDeveloper
+ contact: https://github.com/JasonTheDeveloper/features/issues
+ repository: https://github.com/JasonTheDeveloper/features
+ ociReference: ghcr.io/jasonthedeveloper/features
+- name: Templates by John Muchovej
+ maintainer: John Muchovej
+ contact: https://github.com/jmuchovej/devcontainers/issues
+ repository: https://github.com/jmuchovej/devcontainers
+ ociReference: ghcr.io/jmuchovej/templates
+- name: Features by dasiths
+ maintainer: Dasith Wijes
+ contact: https://dasith.me
+ repository: https://github.com/dasiths/devcontainer-features
+ ociReference: ghcr.io/dasiths/devcontainer-features
+- name: flexwie devcontainer features
+ maintainer: Felix Wieland
+ contact: https://github.com/flexwie/devcontainer-features/issues
+ repository: https://github.com/flexwie/devcontainer-features
+ ociReference: ghcr.io/flexwie/devcontainer-features
+- name: Rust on Nails
+ maintainer: Ian Purton
+ contact: https://github.com/purton-tech/rust-on-nails/issues
+ repository: https://github.com/purton-tech/rust-on-nails
+ ociReference: ghcr.io/purton-tech/rust-on-nails
+- name: ksh5022 devcontainer features
+ maintainer: Kevin Harrigan
+ contact: https://github.com/ksh5022/devcontainer-features/issues
+ repository: https://github.com/ksh5022/devcontainer-features
+ ociReference: ghcr.io/ksh5022/devcontainer-features
+- name: Dapr devcontainer features
+ maintainer: Dapr maintainers
+ contact: https://github.com/dapr/cli/issues
+ repository: https://github.com/dapr/cli
+ ociReference: ghcr.io/dapr/cli
+- name: Azutake Dev Container features
+ maintainer: Azutake
+ contact: https://github.com/azutake/devcontainer-features/issues
+ repository: https://github.com/azutake/devcontainer-features
+ ociReference: ghcr.io/azutake/devcontainer-features
+- name: Features by michidk
+ maintainer: Michael Lohr
+ contact: https://github.com/michidk/
+ repository: https://github.com/michidk/devcontainers-features
+ ociReference: ghcr.io/michidk/devcontainers-features
+- name: Integrated Circuit Design Environment Templates
+ maintainer: Curtis Mayberry
+ contact: https://github.com/curtisma/
+ repository: https://github.com/cascode-labs/viper-ic-devcontainers
+ ociReference: ghcr.io/cascode-labs/viper-ic-devcontainers
+- name: A powerful and handy feature that runs remote shell scripts
+ maintainer: Xiaowei Wang
+ contact: https://github.com/wxw-matt/devcontainer-features/issues
+ repository: https://github.com/wxw-matt/devcontainer-features
+ ociReference: ghcr.io/wxw-matt/devcontainer-features
+- name: Salesforce CLI Features
+ maintainer: Jason Vercellone
+ contact: https://github.com/vercellone/devcontainer-features/issues
+ repository: https://github.com/vercellone/devcontainer-features
+ ociReference: ghcr.io/vercellone/devcontainer-features
+- name: Features by joedmck
+ maintainer: Joe McKinnon
+ contact: https://github.com/joedmck/devcontainer-features/issues
+ repository: https://github.com/joedmck/devcontainer-features
+ ociReference: ghcr.io/joedmck/devcontainer-features
+- name: Features by CodeMan99
+ maintainer: Cody Taylor
+ contact: https://github.com/CodeMan99/features/issues
+ repository: https://github.com/CodeMan99/features
+ ociReference: ghcr.io/codeman99/features
+- name: Features by Favalos
+ maintainer: Fernando Avalos
+ contact: https://github.com/favalos/devcontainer-features/issues
+ repository: https://github.com/favalos/devcontainer-features
+ ociReference: ghcr.io/favalos/devcontainer-features
+- name: Community Templates
+ maintainer: devcontainers-community
+ contact: https://github.com/orgs/devcontainers-community/discussions
+ repository: https://github.com/devcontainers-community
+ ociReference: ghcr.io/devcontainers-community/templates
+- name: Community Features
+ maintainer: devcontainers-community
+ contact: https://github.com/orgs/devcontainers-community/discussions
+ repository: https://github.com/devcontainers-community
+ ociReference: ghcr.io/devcontainers-community/features
+- name: Community npm Features
+ maintainer: devcontainers-community
+ contact: https://github.com/devcontainers-community/npm-features/issues
+ repository: https://github.com/devcontainers-community/npm-features
+ ociReference: ghcr.io/devcontainers-community/npm-features
+- name: Rusty Features
+ maintainer: Lee-Orr
+ contact: https://github.com/lee-orr/rusty-dev-containers/issues
+ repository: https://github.com/lee-orr/rusty-dev-containers
+ ociReference: ghcr.io/lee-orr/rusty-dev-containers
+- name: Assorted Features
+ maintainer: Ivan Stasiuk
+ contact: https://github.com/brokeyourbike/devcontainer-features/issues
+ repository: https://github.com/brokeyourbike/devcontainer-features
+ ociReference: ghcr.io/brokeyourbike/devcontainer-features
+- name: Internet Computer Templates
+ maintainer: VVV Interactive | Internet Base
+ contact: https://github.com/vvv-interactive/ibdev/issues
+ repository: https://github.com/vvv-interactive/ibdev
+ ociReference: ghcr.io/vvv-interactive/ibdev
+- name: Features by Nikita Kurpas
+ maintainer: Nikita Kurpas
+ contact: https://github.com/NikitaKurpas/features/issues
+ repository: https://github.com/NikitaKurpas/features
+ ociReference: ghcr.io/nikitakurpas/features
+- name: Features by joshuanianji
+ maintainer: Joshua Ji
+ contact: https://github.com/joshuanianji/devcontainer-features/issues
+ repository: https://github.com/joshuanianji/devcontainer-features
+ ociReference: ghcr.io/joshuanianji/devcontainer-features
+- name: Features by nullcoder
+ maintainer: Thanan Traiongthawon
+ contact: https://github.com/nullcoder/devcontainer-features/issues
+ repository: https://github.com/nullcoder/devcontainer-features
+ ociReference: ghcr.io/nullcoder/devcontainer-features
+- name: Features by shepherdjerred
+ maintainer: Jerred Shepherd
+ contact: https://github.com/shepherdjerred/devcontainers-features/issues
+ repository: https://github.com/shepherdjerred/devcontainers-features
+ ociReference: ghcr.io/shepherdjerred/devcontainers-features
+- name: Features by jayree
+ maintainer: jayree
+ contact: https://github.com/jayree/devcontainer-features/issues
+ repository: https://github.com/jayree/devcontainer-features
+ ociReference: ghcr.io/jayree/devcontainer-features
+- name: Templates by jayree
+ maintainer: jayree
+ contact: https://github.com/jayree/devcontainer-templates/issues
+ repository: https://github.com/jayree/devcontainer-templates
+ ociReference: ghcr.io/jayree/devcontainer-templates
+- name: Features by bdsoha
+ maintainer: bdsoha
+ contact: https://github.com/bdsoha/devcontainers/issues
+ repository: https://github.com/bdsoha/devcontainers
+ ociReference: ghcr.io/bdsoha/devcontainers
+- name: Python3 with Pyenv and PDM
+ maintainer: Nafnix
+ contact: https://github.com/nafnix/devcontainers-templates/issues
+ repository: https://github.com/nafnix/devcontainers-templates
+ ociReference: ghcr.io/nafnix/devcontainers-templates
+- name: Data science with Python and R
+ maintainer: VS Code Data Science
+ contact: https://github.com/microsoft/datascience-py-r/issues
+ repository: https://github.com/microsoft/datascience-py-r
+ ociReference: ghcr.io/microsoft/datascience-py-r
+- name: Features by tomharvey
+ maintainer: Tom Harvey
+ contact: https://github.com/tomharvey/devcontainer-features/issues
+ repository: https://github.com/tomharvey/devcontainer-features
+ ociReference: ghcr.io/tomharvey/devcontainer-features
+- name: Azure Developer CLI Dev Container Feature
+ maintainer: Azure Developer CLI Team
+ contact: https://github.com/Azure/azure-dev/issues
+ repository: https://github.com/Azure/azure-dev
+ ociReference: ghcr.io/azure/azure-dev
+- name: Skyramp Dev Container Feature
+ maintainer: Skyramp, Inc.
+ contact: https://github.com/letsramp/devcontainer-features/issues
+ repository: https://github.com/letsramp/devcontainer-features
+ ociReference: ghcr.io/letsramp/devcontainer-features
+- name: Earthly Dev Container Features
+ maintainer: Earthly Technologies
+ contact: https://github.com/earthly/devcontainer-features/issues
+ repository: https://github.com/earthly/devcontainer-features
+ ociReference: ghcr.io/earthly/devcontainer-features
+- name: Runme Container Features
+ maintainer: Stateful, Inc.
+ contact: https://github.com/stateful/devcontainer-features/issues
+ repository: https://github.com/stateful/devcontainer-features
+ ociReference: ghcr.io/stateful/devcontainer-features
+- name: Wpdevenv Templates
+ maintainer: Wpdevenv
+ contact: https://github.com/wpdevenv/dev_container_templates/issues
+ repository: https://github.com/wpdevenv/dev_container_templates
+ ociReference: ghcr.io/wpdevenv/dev_container_templates
+- name: Native Dev Container Features
+ maintainer: John Chlark Sumatra
+ contact: https://github.com/itsmechlark/features/issues
+ repository: https://github.com/itsmechlark/features
+ ociReference: ghcr.io/itsmechlark/features
+- name: Assorted Features
+ maintainer: Marco Zaccaro
+ contact: https://github.com/marcozac/devcontainer-features/issues
+ repository: https://github.com/marcozac/devcontainer-features
+ ociReference: ghcr.io/marcozac/devcontainer-features
+- name: Features by Elan Hasson
+ maintainer: ElanHasson
+ contact: https://github.com/ElanHasson/devcontainer-features/issues
+ repository: https://github.com/ElanHasson/devcontainer-features
+ ociReference: ghcr.io/elanhasson/devcontainer-features
+- name: Python+MSSQL+Azure SQL Templates
+ maintainer: Azure Developer CLI Team
+ contact: https://github.com/Azure-Samples/python-ms-sql-devcontainer/issues
+ repository: https://github.com/Azure-Samples/python-ms-sql-devcontainer
+ ociReference: ghcr.io/azure-samples/python-ms-sql-devcontainer
+- name: Features by Tiwaloluwa Ojo
+ maintainer: Tiwaloluwa Ojo
+ contact: https://github.com/tiwaojo/features/issues
+ repository: https://github.com/tiwaojo/features
+ ociReference: ghcr.io/tiwaojo/features
+- name: Julia Language Features
+ maintainer: Julia Language Community
+ contact: https://github.com/JuliaLang/devcontainer-features/issues
+ repository: https://github.com/JuliaLang/devcontainer-features
+ ociReference: ghcr.io/julialang/devcontainer-features
+- name: Julia Language Templates
+ maintainer: Julia Language Community
+ contact: https://github.com/JuliaLang/devcontainer-templates/issues
+ repository: https://github.com/JuliaLang/devcontainer-templates
+ ociReference: ghcr.io/julialang/devcontainer-templates
+- name: Features by John Rowley
+ maintainer: John Rowley
+ contact: https://github.com/robbert229/devcontainer-features/issues
+ repository: https://github.com/robbert229/devcontainer-features
+ ociReference: ghcr.io/robbert229/devcontainer-features
+- name: AliuQ Templates
+ maintainer: AliuQ
+ contact: https://github.com/aliuq/devcontainers/issues
+ repository: https://github.com/aliuq/devcontainers
+ ociReference: ghcr.io/aliuq/devcontainers
+- name: Nordcom Group Inc.'s Dev Container Features
+ maintainer: Filiph Siitam Sandström
+ contact: https://github.com/NordcomInc/devcontainer-features/issues
+ repository: https://github.com/NordcomInc/devcontainer-features
+ ociReference: ghcr.io/nordcominc/devcontainer-features
+- name: Features by Maxim Slipenko
+ maintainer: Maxim Slipenko
+ contact: https://github.com/Maks1mS/devcontainers-features/issues
+ repository: https://github.com/Maks1mS/devcontainers-features
+ ociReference: ghcr.io/maks1ms/devcontainers-features
+- name: Container Structure Tests
+ maintainer: Ty Schlichenmeyer
+ contact: https://github.com/schlich/cst-devcontainer-feature/issues
+ repository: https://github.com/schlich/cst-devcontainer-feature
+ ociReference: ghcr.io/schlich/cst-devcontainer-feature
+- name: Rye
+ maintainer: Ty Schlichenmeyer
+ contact: https://github.com/schlich/devcontainer-features/issues
+ repository: https://github.com/schlich/devcontainer-features
+ ociReference: ghcr.io/schlich/devcontainer-features
+- name: Features by raucha
+ maintainer: raucha
+ contact: https://github.com/raucha/devcontainer-features/issues
+ repository: https://github.com/raucha/devcontainer-features
+ ociReference: ghcr.io/raucha/devcontainer-features
+- name: LINO PIMO SIGO Toolbox
+ maintainer: CGI France
+ contact: https://github.com/CGI-FR/lino-devcontainer/issues
+ repository: https://github.com/CGI-FR/lino-devcontainer/
+ ociReference: ghcr.io/cgi-fr/lino-devcontainer
+- name: Alpine DevContainer Features
+ maintainer: cirolosapio
+ contact: https://github.com/cirolosapio/devcontainers-features/issues
+ repository: https://github.com/cirolosapio/devcontainers-features
+ ociReference: ghcr.io/cirolosapio/devcontainers-features
+- name: Features by AudaciousTux
+ maintainer: audacioustux
+ contact: https://github.com/audacioustux/devcontainers/issues
+ repository: https://github.com/audacioustux/devcontainers
+ ociReference: ghcr.io/audacioustux/devcontainers
+- name: PlantUml DevContainer
+ maintainer: lnyousif
+ contact: https://github.com/lnyousif/plantuml-devcontainer/issues
+ repository: https://github.com/lnyousif/plantuml-devcontainer
+ ociReference: ghcr.io/lnyousif/plantuml-devcontainer
+- name: Features by xfrancois
+ maintainer: xfrancois
+ contact: https://github.com/xfrancois/devcontainers-features/issues
+ repository: https://github.com/xfrancois/devcontainers-features
+ ociReference: ghcr.io/xfrancois/devcontainers-features
+- name: Features by nucleuscloud
+ maintainer: nucleuscloud
+ contact: https://github.com/nucleuscloud/devcontainer-features/issues
+ repository: https://github.com/nucleuscloud/devcontainer-features
+ ociReference: ghcr.io/nucleuscloud/devcontainer-features
+- name: Awesome Features
+ maintainer: joshspicer
+ contact: https://github.com/joshspicer/more-features/issues
+ repository: https://github.com/joshspicer/more-features
+ ociReference: ghcr.io/joshspicer/more-features
+- name: Features by MarlonPassos-git
+ maintainer: MarlonPassos-git
+ contact: https://github.com/MarlonPassos-git/dev-container-features/issues
+ repository: https://github.com/MarlonPassos-git/dev-container-features
+ ociReference: ghcr.io/marlonpassos-git/dev-container-features
+- name: DevContainer Features by Paul Gilber
+ maintainer: Paul Gilber
+ contact: https://github.com/paul-gilber/devcontainer-features/issues
+ repository: https://github.com/paul-gilber/devcontainer-features
+ ociReference: ghcr.io/paul-gilber/devcontainer-features
+- name: Bats Features by Luigi Operoso
+ maintainer: brokenpip3
+ contact: https://github.com/brokenpip3/devcontainers-bats/issues
+ repository: https://github.com/brokenpip3/devcontainers-bats
+ ociReference: ghcr.io/brokenpip3/devcontainers-bats
+- name: Logic App Standard Template
+ maintainer: mcollier
+ contact: https://github.com/mcollier/logic-app-dev-container-template/issues
+ repository: https://github.com/mcollier/logic-app-dev-container-template
+ ociReference: ghcr.io/mcollier/logic-app-dev-container-template
+- name: Additional Dev Container Features by prulloac
+ maintainer: Pablo Ulloa
+ contact: https://github.com/prulloac/devcontainer-features/issues
+ repository: https://github.com/prulloac/devcontainer-features
+ ociReference: ghcr.io/prulloac/devcontainer-features
+- name: Additional Dev Container Templates by prulloac
+ maintainer: Pablo Ulloa
+ contact: https://github.com/prulloac/devcontainer-templates/issues
+ repository: https://github.com/prulloac/devcontainer-templates
+ ociReference: ghcr.io/prulloac/devcontainer-templates
+- name: Additional Dev Container Features by LumenPink
+ maintainer: lumenpink
+ contact: https://github.com/lumenpink/devcontainer-features/issues
+ repository: https://github.com/lumenpink/devcontainer-features
+ ociReference: ghcr.io/lumenpink/devcontainer-features
+- name: Templates by Mohd Shukri Hasan
+ maintainer: Mohd Shukri Hasan
+ contact: https://github.com/hsm207/devcontainer-templates/issues
+ repository: https://github.com/hsm207/devcontainer-templates
+ ociReference: ghcr.io/hsm207/devcontainer-templates
+- name: Radius Features (https://radapp.io/)
+ maintainer: radius-project
+ contact: https://github.com/radius-project/radius/issues
+ repository: https://github.com/radius-project/radius
+ ociReference: ghcr.io/radius-project/devcontainer-features
+- name: Dev Container Features by CASL0
+ maintainer: CASL0
+ contact: https://github.com/CASL0/devcontainer-features/issues
+ repository: https://github.com/CASL0/devcontainer-features
+ ociReference: ghcr.io/casl0/devcontainer-features
+- name: Development Container Features by goldsam
+ maintainer: goldsam
+ contact: https://github.com/goldsam/dev-container-features/issues
+ repository: https://github.com/goldsam/dev-container-features
+ ociReference: ghcr.io/goldsam/dev-container-features
+- name: Azure Functions Dev Container Templates
+ maintainer: Tatsuro Shibamura
+ contact: https://github.com/shibayan/devcontainers/issues
+ repository: https://github.com/shibayan/devcontainers
+ ociReference: ghcr.io/shibayan/devcontainers
+- name: Dev Container Templates by RSM HCD Engineering
+ maintainer: RSM HCD Engineering
+ contact: https://github.com/rsm-hcd
+ repository: https://github.com/rsm-hcd/devcontainer-templates
+ ociReference: ghcr.io/rsm-hcd/devcontainer-templates
+- name: Additional Dev Container Features by Georg Ofenbeck
+ maintainer: Georg Ofenbeck
+ contact: https://github.com/GeorgOfenbeck/features/issues
+ repository: https://github.com/GeorgOfenbeck/features
+ ociReference: ghcr.io/georgofenbeck/features
+- name: Dev Container Features by Niko Böckerman
+ maintainer: Niko Böckerman
+ contact: https://github.com/nikobockerman
+ repository: https://github.com/nikobockerman/devcontainer-features
+ ociReference: ghcr.io/nikobockerman/devcontainer-features
+- name: Bun.sh Runtime Dev Container Templates
+ maintainer: Marcos Gomes Neto
+ contact: https://github.com/marcosgomesneto/bun-devcontainers/issues
+ repository: https://github.com/marcosgomesneto/bun-devcontainers
+ ociReference: ghcr.io/marcosgomesneto/bun-devcontainers
+- name: Weik.io Dev Container Templates
+ maintainer: Mikael Koskinen
+ contact: https://github.com/weikio/devcontainer-templates/issues
+ repository: https://github.com/weikio/devcontainer-templates
+ ociReference: ghcr.io/weikio/devcontainer-templates
+- name: Dev Container Features by Hans Spaans
+ maintainer: Hans Spaans
+ contact: https://github.com/hspaans/devcontainer-features/issues
+ repository: https://github.com/hspaans/devcontainer-features
+ ociReference: ghcr.io/hspaans/devcontainer-features
+- name: Dev Container Templates by johnluicn
+ maintainer: johnluicn
+ contact: https://github.com/johnluicn/devcontainer-templates/issues
+ repository: https://github.com/johnluicn/devcontainer-templates
+ ociReference: ghcr.io/johnluicn/devcontainer-templates
+- name: Bob buildsystem and DevBox features
+ maintainer: Dirk Louwers
+ contact: https://github.com/dlouwers/devcontainer-features/issues
+ repository: https://github.com/dlouwers/devcontainer-features
+ ociReference: ghcr.io/dlouwers/devcontainer-features
+- name: Dev Container Features by kreemer
+ maintainer: kreemer
+ contact: https://github.com/kreemer/features/issues
+ repository: https://github.com/kreemer/features
+ ociReference: ghcr.io/kreemer/features
+- name: Dev Container Features by Vero
+ maintainer: Vero
+ contact: https://github.com/veronoicc/devcontainer-features/issues
+ repository: https://github.com/veronoicc/devcontainer-features
+ ociReference: ghcr.io/veronoicc/devcontainer-features
+- name: Dev Container Templates by joshuanianji
+ maintainer: joshuanianji
+ contact: https://github.com/joshuanianji/devcontainer-templates/issues
+ repository: https://github.com/joshuanianji/devcontainer-templates
+ ociReference: ghcr.io/joshuanianji/devcontainer-templates
+- name: OpenCodeCo Dev Containers goodies
+ maintainer: leocavalcante
+ contact: https://github.com/orgs/opencodeco/discussions
+ repository: https://github.com/opencodeco/devcontainers
+ ociReference: ghcr.io/opencodeco/devcontainers
+- name: Dev Container Features by Valentin
+ maintainer: Valentin Heiligers
+ contact: https://github.com/va-h/devcontainers-features/issues
+ repository: https://github.com/va-h/devcontainers-features
+ ociReference: ghcr.io/va-h/devcontainers-features
+- name: Alloy Dev Container Template
+ maintainer: heathprovost
+ contact: https://github.com/heathprovost/alloy-devcontainer-template/issues
+ repository: https://github.com/heathprovost/alloy-devcontainer-template
+ ociReference: ghcr.io/heathprovost/alloy-devcontainer-template
+- name: Arch Linux Dev Container Features
+ maintainer: Bart Venter
+ contact: https://github.com/bartventer/arch-devcontainer-features/issues
+ repository: https://github.com/bartventer/arch-devcontainer-features
+ ociReference: ghcr.io/bartventer/arch-devcontainer-features
+- name: BPMN and DMN linters
+ maintainer: Waqqas Jabbar
+ contact: https://github.com/waqqas/feature/issues
+ repository: https://github.com/waqqas/feature/
+ ociReference: ghcr.io/waqqas/feature
+- name: Veryl
+ maintainer: dalance
+ contact: https://github.com/veryl-lang/devcontainer-features/issues
+ repository: https://github.com/veryl-lang/devcontainer-features/
+ ociReference: ghcr.io/veryl-lang/devcontainer-features
+- name: Dev Container Features by dusansimic
+ maintainer: dusansimic
+ contact: https://github.com/dusansimic/devcontainer-features/issues
+ repository: https://github.com/dusansimic/devcontainer-features/
+ ociReference: ghcr.io/dusansimic/devcontainer-features
+- name: Dev Container Features (Cadu Ribeiro)
+ maintainer: Cadu Ribeiro
+ contact: https://github.com/duduribeiro/devcontainer-features/issues
+ repository: https://github.com/duduribeiro/devcontainer-features/
+ ociReference: ghcr.io/duduribeiro/devcontainer-features
+- name: Dev Container Features by skriptfabrik
+ maintainer: skriptfabrik
+ contact: https://github.com/skriptfabrik/devcontainer-features/issues
+ repository: https://github.com/skriptfabrik/devcontainer-features/
+ ociReference: ghcr.io/skriptfabrik/devcontainer-features
+- name: Dev Container Features by m4tchl0ck
+ maintainer: Adrian Rusznica
+ contact: https://github.com/m4tchl0ck/devcontainer-features/issues
+ repository: https://github.com/m4tchl0ck/devcontainer-features/
+ ociReference: ghcr.io/m4tchl0ck/devcontainer-features
+- name: Dev Container Features by nils-geistmann
+ maintainer: Nils Geistmann
+ contact: https://github.com/nils-geistmann/devcontainers-features/issues
+ repository: https://github.com/nils-geistmann/devcontainers-features/
+ ociReference: ghcr.io/nils-geistmann/devcontainers-features
+- name: OpenFGA CLI
+ maintainer: Andrew Porter
+ contact: https://github.com/partydrone/devcontainer/issues
+ repository: https://github.com/partydrone/devcontainer
+ ociReference: ghcr.io/partydrone/devcontainer/features
+- name: Dev Container Features by rafaph
+ maintainer: Raphael Castro
+ contact: https://github.com/rafaph/devcontainer-features/issues
+ repository: https://github.com/rafaph/devcontainer-features
+ ociReference: ghcr.io/rafaph/devcontainer-features
+- name: SPFx Dev Container
+ maintainer: Troy
+ contact: https://github.com/tpalacino/SPFx-dev-container/issues
+ repository: https://github.com/tpalacino/SPFx-dev-container
+ ociReference: ghcr.io/tpalacino/spfx-dev-container
+- name: GMkonan devcontainer features
+ maintainer: GMkonan
+ contact: https://github.com/GMkonan/fly-cli-feature/issues
+ repository: https://github.com/GMkonan/fly-cli-feature
+ ociReference: ghcr.io/gmkonan/fly-cli-feature
+- name: Dev Container Features by E-gineering
+ maintainer: E-gineering
+ contact: https://github.com/e-gineering/devcontainer-features/issues
+ repository: https://github.com/e-gineering/devcontainer-features
+ ociReference: ghcr.io/e-gineering/devcontainer-features
+- name: Dev Container Templates by E-gineering
+ maintainer: E-gineering
+ contact: https://github.com/e-gineering/devcontainer-templates/issues
+ repository: https://github.com/e-gineering/devcontainer-templates
+ ociReference: ghcr.io/e-gineering/devcontainer-templates
+- name: ROS2 devcontainer Template
+ maintainer: Tony Najjar
+ contact: https://github.com/tonynajjar/ros2_devcontainer_template/issues
+ repository: https://github.com/tonynajjar/ros2_devcontainer_template/
+ ociReference: ghcr.io/tonynajjar/ros2_devcontainer_template
+- name: Clojure devcontainer templates
+ maintainer: Carsten Behring
+ contact: https://github.com/scicloj/devcontainer-templates/issues
+ repository: https://github.com/scicloj/devcontainer-templates/
+ ociReference: ghcr.io/scicloj/devcontainer-templates
+- name: Synology devcontainer Templates
+ maintainer: ChaosWars
+ contact: https://github.com/ChaosWars/synology-features/issues
+ repository: https://github.com/ChaosWars/synology-features/
+ ociReference: ghcr.io/chaoswars/synology-features
+- name: Assorted Features
+ maintainer: tcaky
+ contact: https://github.com/tcaky/devcontainer-features/issues
+ repository: https://github.com/tcaky/devcontainer-features
+ ociReference: ghcr.io/tcaky/devcontainer-features
+- name: Dev & Container features
+ maintainer: LarsNieuwenhuizen
+ contact: https://github.com/LarsNieuwenhuizen/features/issues
+ repository: https://github.com/LarsNieuwenhuizen/features
+ ociReference: ghcr.io/larsnieuwenhuizen/features
+- name: Dev Container Features by enrico9034
+ maintainer: enrico9034
+ contact: https://github.com/enrico9034/devcontainer-features/issues
+ repository: https://github.com/enrico9034/devcontainer-features
+ ociReference: ghcr.io/enrico9034/devcontainer-features
+- name: Dev Container Templates by ThePhaseless
+ maintainer: ThePhaseless
+ contact: https://github.com/ThePhaseless/devcontainer-templates/issues
+ repository: https://github.com/ThePhaseless/devcontainer-templates
+ ociReference: ghcr.io/thephaseless/devcontainer-templates
+- name: Devcontainer Features by nikiforovall
+ maintainer: nikiforovall
+ contact: https://github.com/nikiforovall/devcontainer-features/issues
+ repository: https://github.com/nikiforovall/devcontainer-features
+ ociReference: ghcr.io/nikiforovall/devcontainer-features
+- name: Dev Container Templates by matheusfvesco
+ maintainer: matheusfvesco
+ contact: https://github.com/matheusfvesco/devcontainer-templates/issues
+ repository: https://github.com/matheusfvesco/devcontainer-templates
+ ociReference: ghcr.io/matheusfvesco/devcontainer-templates
+- name: Dennis Irsigler Dev Container Features
+ maintainer: dirsigler
+ contact: https://github.com/dirsigler/devcontainer-features/issues
+ repository: https://github.com/dirsigler/devcontainer-features
+ ociReference: ghcr.io/dirsigler/devcontainer-features
+- name: Dev Container Templates by sleter
+ maintainer: sleter
+ contact: https://github.com/sleter/mojo-devcontainer/issues
+ repository: https://github.com/sleter/mojo-devcontainer
+ ociReference: ghcr.io/sleter/mojo-devcontainer
+- name: Devcontainer features by sidecus
+ maintainer: sidecus
+ contact: https://github.com/sidecus/devcontainer-features/issues
+ repository: https://github.com/sidecus/devcontainer-features
+ ociReference: ghcr.io/sidecus/devcontainer-features
+- name: MATLAB Feature for DevContainers
+ maintainer: The MathWorks Inc.
+ contact: https://github.com/mathworks/devcontainer-features/issues
+ repository: https://github.com/mathworks/devcontainer-features
+ ociReference: ghcr.io/mathworks/devcontainer-features
+- name: Julian Pawlowski Dev Container Features
+ maintainer: Julian Pawlowski
+ contact: https://github.com/jpawlowski/devcontainer-features/issues
+ repository: https://github.com/jpawlowski/devcontainer-features
+ ociReference: ghcr.io/jpawlowski/devcontainer-features
+- name: pre-commit hooks(via pip) & sonarlint
+ maintainer: gvatsal60 (Vatsal Gupta)
+ contact: https://github.com/gvatsal60/dev-container-features/issues
+ repository: https://github.com/gvatsal60/dev-container-features
+ ociReference: ghcr.io/gvatsal60/dev-container-features
+- name: Devcontainer features by git-saj
+ maintainer: git-saj
+ contact: https://github.com/git-saj/devcontainer-features/issues
+ repository: https://github.com/git-saj/devcontainer-features
+ ociReference: ghcr.io/git-saj/devcontainer-features
+- name: Devcontainer features by Codefabrik
+ maintainer: Codefabrik GmbH
+ contact: https://github.com/code-fabrik/features/issues
+ repository: https://github.com/code-fabrik/features
+ ociReference: ghcr.io/code-fabrik/features
+- name: Devcontainer features by Juan Ayala
+ maintainer: Juan Ayala
+ contact: https://github.com/juan-ayala/devcontainer-features/issues
+ repository: https://github.com/juan-ayala/devcontainer-features
+ ociReference: ghcr.io/juan-ayala/devcontainer-features
+- name: Devcontainer templates by Juan Ayala
+ maintainer: Juan Ayala
+ contact: https://github.com/juan-ayala/devcontainer-templates/issues
+ repository: https://github.com/juan-ayala/devcontainer-templates
+ ociReference: ghcr.io/juan-ayala/devcontainer-templates
+- name: LocalStack DevContainer Feature
+ maintainer: LocalStack GmbH
+ contact: https://github.com/localstack/devcontainer-feature/issues
+ repository: https://github.com/localstack/devcontainer-feature
+ ociReference: ghcr.io/localstack/devcontainer-feature
+- name: LocalStack DevContainer Template
+ maintainer: LocalStack GmbH
+ contact: https://github.com/localstack/devcontainer-template/issues
+ repository: https://github.com/localstack/devcontainer-template
+ ociReference: ghcr.io/localstack/devcontainer-template
+- name: Dev Container features by Adaptavist
+ maintainer: Mark Gibson
+ contact: https://github.com/adaptavist/devcontainer-features/issues
+ repository: https://github.com/adaptavist/devcontainer-features
+ ociReference: ghcr.io/adaptavist/devcontainer-features
+- name: Dev Container features by phil-bell
+ maintainer: Phil Bell
+ contact: https://github.com/phil-bell/devcontainer-features/issues
+ repository: https://github.com/phil-bell/devcontainer-features
+ ociReference: ghcr.io/phil-bell/devcontainer-features
+- name: Dev Container Templates by Alex Wegener
+ maintainer: Alex Wegener
+ contact: https://github.com/lx-0/devcontainer-templates/issues
+ repository: https://github.com/lx-0/devcontainer-templates
+ ociReference: ghcr.io/lx-0/devcontainer-templates
+- name: Hauke's Features for Development Containers
+ maintainer: Hauke D
+ contact: https://github.com/haukex/devcontainer-features/issues
+ repository: https://github.com/haukex/devcontainer-features
+ ociReference: ghcr.io/haukex/devcontainer-features
+- name: Devcontainer features by vmvarela
+ maintainer: Victor M. Varela
+ contact: https://github.com/vmvarela/devcontainer-features/issues
+ repository: https://github.com/vmvarela/devcontainer-features
+- name: Crystal features
+ maintainer: Caesarovich
+ contact: https://github.com/Caesarovich/devcontainer-feature-crystal/issues
+ repository: https://github.com/Caesarovich/devcontainer-feature-crystal
+ ociReference: ghcr.io/caesarovich/devcontainer-feature-crystal
+- name: Dev Container Features by devcontainers-extra
+ maintainer: devcontainers-extra
+ contact: https://github.com/devcontainers-extra/features/issues
+ repository: https://github.com/devcontainers-extra/features
+ ociReference: ghcr.io/devcontainers-extra/features
+- name: devcontainer features by Bas Steins
+ maintainer: Bas Steins
+ contact: https://bas.codes
+ repository: https://github.com/bascodes/devcontainer-features
+ ociReference: ghcr.io/bascodes/devcontainer-features
+- name: devcontainer features by rhiroe
+ maintainer: rhiroe
+ contact: https://github.com/rhiroe/features/issues
+ repository: https://github.com/rhiroe/features
+ ociReference: ghcr.io/rhiroe/features
+- name: Development Container Features by aqua
+ maintainer: Shunsuke Suzuki
+ contact: https://github.com/aquaproj/devcontainer-features/issues
+ repository: https://github.com/aquaproj/devcontainer-features
+ ociReference: ghcr.io/aquaproj/devcontainer-features
+- name: devcontainer features by martinaskestad
+ maintainer: martinaskestad
+ contact: https://github.com/martinaskestad/features/issues
+ repository: https://github.com/martinaskestad/features
+ ociReference: ghcr.io/martinaskestad/features
+- name: devcontainer features for wolfi base docker image
+ maintainer: David Zucker
+ contact: https://github.com/davzucky/devcontainers-features-wolfi/issues
+ repository: https://github.com/davzucky/devcontainers-features-wolfi
+ ociReference: ghcr.io/davzucky/devcontainers-features-wolfi
+- name: Dev Container Features by ForWarD Software
+ maintainer: ForWarD Software
+ contact: https://github.com/forwardsoftware/devcontainer-features/issues
+ repository: https://github.com/forwardsoftware/devcontainer-features
+ ociReference: ghcr.io/forwardsoftware/devcontainer-features
+- name: devcontainer feature to install apt dependencies defined in an `Aptfile.dev` file.
+ maintainer: Viktor Schmidt
+ contact: https://github.com/viktorianer/devcontainer-features/issues
+ repository: https://github.com/viktorianer/devcontainer-features/tree/main/src/apt
+ ociReference: ghcr.io/viktorianer/devcontainer-features/apt
+- name: devcontainer features by ChaosWars
+ maintainer: ChaosWars
+ contact: https://github.com/ChaosWars/vscode-features/issues
+ repository: https://github.com/ChaosWars/vscode-features
+ ociReference: ghcr.io/chaoswars/vscode-features
+- name: Community features by devcontainer.community
+ maintainer: devcontainer.community
+ contact: https://devcontainer.community
+ repository: https://github.com/devcontainer-community/devcontainer-features
+ ociReference: ghcr.io/devcontainer-community/devcontainer-features
+- name: Additional Dev Container Features by braun-daniel
+ maintainer: Daniel Braun
+ contact: https://github.com/braun-daniel/devcontainer-features/issues
+ repository: https://github.com/braun-daniel/devcontainer-features
+ ociReference: ghcr.io/braun-daniel/devcontainer-features
+- name: Dev Container Features by Ivan Szkiba
+ maintainer: Ivan Szkiba
+ contact: https://github.com/szkiba/devcontainer-features/issues
+ repository: https://github.com/szkiba/devcontainer-features
+ ociReference: ghcr.io/szkiba/devcontainer-features
+- name: devcontainer features by TheDiveO
+ maintainer: TheDiveO
+ contact: https://github.com/thediveo/devcontainer-features/issues
+ repository: https://github.com/thediveo/devcontainer-features
+ ociReference: ghcr.io/thediveo/devcontainer-features
+- name: devcontainer features by .NET Aspire
+ maintainer: danmoseley
+ contact: https://github.com/dotnet/aspire-devcontainer-feature/issues
+ repository: https://github.com/dotnet/aspire-devcontainer-feature
+ ociReference: ghcr.io/dotnet/aspire-devcontainer-feature
+- name: devcontainer features by RouL
+ maintainer: Markus Zhang
+ contact: https://github.com/RouL/devcontainer-features/issues
+ repository: https://github.com/RouL/devcontainer-features
+ ociReference: ghcr.io/roul/devcontainer-features
+- name: devcontainer templates by techiro
+ maintainer: techiro
+ contact: https://github.com/techiro/devcontainer-template/issues
+ repository: https://github.com/techiro/devcontainer-template
+ ociReference: ghcr.io/techiro/devcontainer-template
+- name: Claude Code Feature
+ maintainer: Anthropic
+ contact: https://github.com/anthropics/devcontainer-features/issues
+ repository: https://github.com/anthropics/devcontainer-features
+ ociReference: ghcr.io/anthropics/devcontainer-features/claude-code
+- name: devcontainer templates by blooop
+ maintainer: Austin Gregg-Smith
+ contact: https://github.com/blooop/devcontainer-templates/issues
+ repository: https://github.com/blooop/devcontainer-templates
+ ociReference: ghcr.io/blooop/devcontainer-templates
+- name: devcontainer features by prplecake
+ maintainer: Matthew Jorgensen (prplecake)
+ contact: https://github.com/prplecake/devcontainer-features/issues
+ repository: https://github.com/prplecake/devcontainer-features
+ ociReference: ghcr.io/prplecake/devcontainer-features
+- name: Ziglang devcontainer Template
+ maintainer: fardragon
+ contact: https://github.com/fardragon/devcontainers-zig-template/issues
+ repository: https://github.com/fardragon/devcontainers-zig-template
+ ociReference: ghcr.io/fardragon/devcontainers-zig-template
+- name: TTCN-3-Devcontainer
+ maintainer: Muhammad Umair Khan
+ contact: https://github.com/m-umair-khan-dev/devcontainers/issues
+ repository: https://github.com/m-umair-khan-dev/devcontainers
+ ociReference: ghcr.io/m-umair-khan-dev/devcontainers/ttcn-3-devcontainer
+- name: Dev Container Features by Grafana Labs
+ maintainer: Grafana Labs
+ contact: https://github.com/grafana/devcontainer-features/issues
+ repository: https://github.com/grafana/devcontainer-features
+ ociReference: ghcr.io/grafana/devcontainer-features
+- name: Dev Container Features by httpdss
+ maintainer: httpdss
+ contact: https://github.com/httpdss/devcontainers-features/issues
+ repository: https://github.com/httpdss/devcontainers-features
+ ociReference: ghcr.io/httpdss/devcontainers-features
+- name: Axon Ivy devcontainer template
+ maintainer: axonivy
+ contact: https://github.com/axonivy/devcontainer-templates/issues
+ repository: https://github.com/axonivy/devcontainer-templates
+ ociReference: ghcr.io/axonivy/devcontainer-templates
+- name: Dev Container Features by Coder
+ maintainer: Coder
+ contact: https://github.com/coder/devcontainer-features/issues
+ repository: https://github.com/coder/devcontainer-features
+ ociReference: ghcr.io/coder/devcontainer-features
+- name: Dev Container Features by atty303
+ maintainer: atty303
+ contact: https://github.com/atty303/devcontainer-features/issues
+ repository: https://github.com/atty303/devcontainer-features
+ ociReference: ghcr.io/atty303/devcontainer-features
+- name: devcontainer features by MuhmdRaouf
+ maintainer: Mohammed Abdel Raouf (MuhmdRaouf)
+ contact: https://github.com/muhmdraouf/devcontainers-features/issues
+ repository: https://github.com/muhmdraouf/devcontainers-features
+ ociReference: ghcr.io/muhmdraouf/devcontainers-features
+- name: Dev Container Features by John Ajera
+ maintainer: John Ajera
+ contact: https://github.com/jajera/features/issues
+ repository: https://github.com/jajera/features
+ ociReference: ghcr.io/jajera/features
+- name: MrSimonEmms Dev Container Features
+ maintainer: MrSimonEmms
+ contact: https://github.com/mrsimonemms/devcontainers/issues
+ repository: https://github.com/mrsimonemms/devcontainers
+ ociReference: ghcr.io/mrsimonemms/devcontainers
+- name: HTTPie Feature
+ maintainer: Ferdinand Keller
+ contact: https://github.com/ferdinandkeller/features/issues
+ repository: https://github.com/ferdinandkeller/features
+ ociReference: ghcr.io/ferdinandkeller/features/httpie
+- name: Rojo Feature
+ maintainer: Ryan Luu
+ contact: https://github.com/RyanLua/features/issues
+ repository: https://github.com/RyanLua/features
+ ociReference: ghcr.io/ryanlua/features
+- name: Roblox Template
+ maintainer: Ryan Luu
+ contact: https://github.com/RyanLua/templates/issues
+ repository: https://github.com/RyanLua/templates
+ ociReference: ghcr.io/ryanlua/templates
+- name: Dev Container Features by Joe Bowbeer
+ maintainer: Joe Bowbeer
+ contact: https://github.com/joebowbeer/devcontainers-features/issues
+ repository: https://github.com/joebowbeer/devcontainers-features
+ ociReference: ghcr.io/joebowbeer/devcontainers-features
+- name: FEniCS
+ maintainer: schnellerhase
+ contact: https://github.com/schnellerhase/devcontainer-fenics/issues
+ repository: https://github.com/schnellerhase/devcontainer-fenics
+ ociReference: ghcr.io/schnellerhase/devcontainer-fenics/fenics
+ ociReference: ghcr.io/ryanlua/templates/roblox
+- name: W&B Catnip
+ maintainer: Weights and Biases
+ contact: https://github.com/wandb/catnip/issues
+ repository: https://github.com/wandb/catnip
+ ociReference: ghcr.io/wandb/catnip/feature
+- name: AcademicDocker template (R, Stata, LaTeX)
+ maintainer: Romain Ferrali
+ contact: https://github.com/rferrali/devcontainer-templates/issues
+ repository: https://github.com/rferrali/devcontainer-templates
+ ociReference: ghcr.io/rferrali/devcontainer-templates
+- name: Devcontainers templates by jhoareaumarion
+ maintainer: jhoareaumarion
+ contact: https://github.com/jhoareaumarion/devcontainers/issues
+ repository: https://github.com/jhoareaumarion/devcontainers
+ ociReference: ghcr.io/jhoareaumarion/devcontainers
+- name: devcontainer features by TakahashiNguyen
+ maintainer: ANh Nguyá»…n (TakahashiNguyen)
+ contact: https://github.com/TakahashiNguyen/devcontainer-features/issues
+ repository: https://github.com/TakahashiNguyen/devcontainer-features
+ ociReference: ghcr.io/takahashinguyen/devcontainer-features
+- name: olivierlemasle
+ maintainer: Olivier Lemasle
+ contact: https://github.com/olivierlemasle/devcontainers-features/issues
+ repository: https://github.com/olivierlemasle/devcontainers-features
+ ociReference: ghcr.io/olivierlemasle/devcontainers-features
+- name: BTP Dev Container Features
+ maintainer: Navin Krishnan
+ contact: https://github.com/navinkrishnan/devcontainer-features-btp/issues
+ repository: https://github.com/navinkrishnan/devcontainer-features-btp
+ ociReference: ghcr.io/navinkrishnan/devcontainer-features-btp
+- name: BTP CAP (Cloud Application Programming) Model Dev Templates
+ maintainer: Navin Krishnan
+ contact: https://github.com/navinkrishnan/devcontainer-templates-btp/issues
+ repository: https://github.com/navinkrishnan/devcontainer-templates-btp
+ ociReference: ghcr.io/navinkrishnan/devcontainer-templates-btp
diff --git a/_implementors/contributing.md b/_implementors/contributing.md
index 66bd95cc..8fc2edb4 100644
--- a/_implementors/contributing.md
+++ b/_implementors/contributing.md
@@ -3,22 +3,23 @@ layout: implementors
title: "How to contribute to the Development Container Specification"
shortTitle: "Contributing"
author: Microsoft
-index: 8
+index: 9
---
-We're excited for your contributions to the Dev Container Specification! This document outlines how you can get involved.
+We're excited for your contributions to the Dev Container Specification! This document outlines how you can get involved. We also welcome you to join our [community Slack channel](https://aka.ms/dev-container-community).
-## Contribution approaches
+## Spec Contribution approaches
-- Propose the change via an [issue](https://github.com/devcontainers/spec/issues) in the [spec repo](https://github.com/devcontainers/spec). Try to get early feedback before spending too much effort formalizing it.
-- More formally document the proposed change in terms of properties and their semantics. Look to format your proposal like our [devcontainer.json reference](../json_reference), which is a JSON with Comments (jsonc) format.
+If you'd like to contribute a change or addition to the spec, you may follow the guidance below:
+- Propose the change via an [issue](https://github.com/devcontainers/spec/issues) in this repository. Try to get early feedback before spending too much effort formalizing it.
+- More formally document the proposed change in terms of properties and their semantics. Look to format your proposal like our [devcontainer.json reference](https://aka.ms/devcontainer.json).
-Here is a sample proposal:
+Here is a sample:
| Property | Type | Description |
|:------------------|:------------|:------------|
| `image` | string | **Required** when using an image. The name of an image in a container registry ([DockerHub](https://hub.docker.com), [GitHub Container Registry](https://docs.github.com/packages/guides/about-github-container-registry), [Azure Container Registry](https://azure.microsoft.com/services/container-registry/)) that VS Code and other `devcontainer.json` supporting services / tools should use to create the dev container. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
- PRs to the [schema](https://github.com/microsoft/vscode/blob/main/extensions/configuration-editing/schemas/devContainer.schema.src.json), i.e code or shell scripts demonstrating approaches for implementation.
@@ -43,6 +44,20 @@ Tool-specific properties are contained in namespaces in the `"customizations"` p
You may propose adding a new namespace for a specific tool, and any properties specific to that tool.
+### Formatting Guidelines
+
+When contributing an official doc or referencing dev containers in your projects, please consider the following guidelines:
+
+- Refer to the spec as the "Development Container Specification"
+ - All capital letters
+ - Singular "Container" rather than plural "Containers"
+- The term "dev container" shouldn't be capitalized on its own
+ - It should only be capitalized when referring to an official tool title, like the VS Code Dev Containers extension
+- Signify `devcontainer.json` is a file type through backticks
+- Features and Templates should always be capitalized
+- Refer to the CLI as the "Dev Container CLI" (note the caps)
+- Use bolding for emphasis sprinkled throughout sections, rather than try to use it to always bold certain terms
+
## Review process
We use the following [labels](https://github.com/devcontainers/spec/labels) in the spec repo:
@@ -51,3 +66,11 @@ We use the following [labels](https://github.com/devcontainers/spec/labels) in t
- `finalization`: Proposals we intend to make part of the spec.
[Milestones](https://github.com/devcontainers/spec/milestones) use a "month year" pattern (i.e. January 2022). If a finalized proposal is added to a milestone, it is intended to be merged during that milestone.
+
+## Community Engagement
+
+There are several additional options to engage with the dev container community, such as asking questions, providing feedback, or engaging on how your team may use or contribute to dev containers:
+- [GitHub Discussions](https://github.com/devcontainers/spec/discussions): This is a great opportunity to connect with the community and maintainers of this project, without the requirement of contributing a change to the actual spec (which we see more in issues and PRs)
+- [Community Slack channel](https://aka.ms/dev-container-community): This is a great opportunity to connect with the community and maintainers
+- You can always check out the issues and PRs (and contribute new ones) across the repos in the [Dev Containers GitHub org](https://github.com/devcontainers) too!
+- Community collections: You can contribute your own [Templates](https://containers.dev/implementors/templates-distribution/#distribution) and [Features](https://containers.dev/implementors/features-distribution/#distribution) to our [community index](https://containers.dev/collections)!
\ No newline at end of file
diff --git a/_implementors/features-distribution.md b/_implementors/features-distribution.md
index 45ac4231..b01ac4c5 100644
--- a/_implementors/features-distribution.md
+++ b/_implementors/features-distribution.md
@@ -8,7 +8,7 @@ index: 6
**TL;DR Check out the [quick start repository](https://github.com/devcontainers/feature-template) to get started on distributing your own Dev Container Features.**
-This specification defines a pattern where community members and organizations can author and self-publish [Dev Container 'Features'](../features).
+This specification defines a pattern where community members and organizations can author and self-publish [Dev Container Features](../features).
Goals include:
@@ -17,13 +17,13 @@ Goals include:
- For users, provide the ability for a user to pin to a particular version (absolute, or semantic version) of a Feature to allow for consistent, repeatable environments.
- Provide the ability to standardize publishing such that [supporting tools](../../supporting) may implement their own mechanism to aid Feature discoverability as they see fit.
-> **Tip:** This section covers details on the Features specification. If you are looking for summarized information on creating your own Features, see the [template](https://github.com/devcontainers/feature-template) and [core Features](https://github.com/devcontainers/features) repositories.
+> **Tip:** This section covers details on the Features specification. If you are looking for summarized information on creating your own Features, check out the [quick start](https://github.com/devcontainers/feature-starter) and [core Features](https://github.com/devcontainers/features) repositories.
## Source Code
Features source code is stored in a git repository.
-For ease of authorship and maintenance, [1..n] features can share a single git repository. This set of Features is referred to as a "collection," and will share the same [`devcontainer-collection.json`](#devcontainer-collection.json) file and "namespace" (eg. `/`).
+For ease of authorship and maintenance, [1..n] features can share a single git repository. This set of Features is referred to as a "collection," and will share the same [`devcontainer-collection.json`](#devcontainer-collection-json) file and "namespace" (eg. `/`).
Source code for the set follows the example file structure below:
@@ -71,7 +71,7 @@ Features are distributed as tarballs. The tarball contains the entire contents o
The tarball is named `devcontainer-feature-.tgz`, where `` is the Feature's `id` field.
-A reference implementation for packaging and distributing Features is provided as a GitHub Action (https://github.com/devcontainers/action).
+A reference implementation for packaging and distributing Features is provided as a [GitHub Action](https://github.com/devcontainers/action).
### devcontainer-collection.json
@@ -81,7 +81,7 @@ The `devcontainer-collection.json` is an auto-generated metadata file.
| :--- | :--- | :--- |
| `sourceInformation` | object | Metadata from the implementing packaging tool. |
| `features` | array | The list of features that are contained in this collection.|
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
Each Features's `devcontainer-feature.json` metadata file is appended into the `features` top-level array.
@@ -89,7 +89,7 @@ Each Features's `devcontainer-feature.json` metadata file is appended into the `
There are several supported ways to distribute Features. Distribution is handled by the implementing packaging tool such as the [Dev Container CLI](https://github.com/devcontainers/cli) or [Dev Container Publish GitHub Action](https://github.com/marketplace/actions/dev-container-publish). See the [quick start repository](https://github.com/devcontainers/feature-template) for a full working example.
-A user references a distributed Feature in a `devcontainer.json` as defined in ['referencing a feature'](../features#referencing-a-feature).
+A user references a distributed Feature in a `devcontainer.json` as defined in ['referencing a Feature'](../features#referencing-a-feature).
### OCI Registry
@@ -97,7 +97,7 @@ An OCI registry that implements the [OCI Artifact Distribution Specification](ht
Each packaged Feature is pushed to the registry following the naming convention `//[:version]`, where version is the major, minor, and patch version of the Feature, according to the semver specification.
-> **Note:** The `namespace` is a unique indentifier for the collection of Features. There are no strict rules for the `namespace`; however, one pattern is to set `namespace` equal to source repository's `/`.
+> **Note:** The `namespace` is a unique identifier for the collection of Features. There are no strict rules for the `namespace`; however, one pattern is to set `namespace` equal to source repository's `/`.
A custom media type `application/vnd.devcontainers` and `application/vnd.devcontainers.layer.v1+tar` are used as demonstrated below.
@@ -116,7 +116,7 @@ ARTIFACT_PATH=devcontainer-feature-go.tgz
for VERSION in 1 1.2 1.2.3 latest
do
oras push ${REGISTRY}/${NAMESPACE}/${FEATURE}:${VERSION} \
- --manifest-config /dev/null:application/vnd.devcontainers \
+ --config /dev/null:application/vnd.devcontainers \
./${ARTIFACT_PATH}:application/vnd.devcontainers.layer.v1+tar
done
```
@@ -131,10 +131,39 @@ REGISTRY=ghcr.io
NAMESPACE=devcontainers/features
oras push ${REGISTRY}/${NAMESPACE}:latest \
- --manifest-config /dev/null:application/vnd.devcontainers \
+ --config /dev/null:application/vnd.devcontainers \
./devcontainer-collection.json:application/vnd.devcontainers.collection.layer.v1+json
```
+Additionally, an [annotation](https://github.com/opencontainers/image-spec/blob/main/annotations.md) named `dev.containers.metadata` should be populated on the manifest when published by an implementing tool. This annotation is the escaped JSON object of the entire `devcontainer-feature.json` as it appears during the [packaging stage](#packaging).
+
+An example manifest with the `dev.containers.metadata` annotation:
+
+```json
+{
+ "schemaVersion": 2,
+ "mediaType": "application/vnd.oci.image.manifest.v1+json",
+ "config": {
+ "mediaType": "application/vnd.devcontainers",
+ "digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "size": 0
+ },
+ "layers": [
+ {
+ "mediaType": "application/vnd.devcontainers.layer.v1+tar",
+ "digest": "sha256:738af5504b253dc6de51d2cb1556cdb7ce70ab18b2f32b0c2f12650ed6d2e4bc",
+ "size": 3584,
+ "annotations": {
+ "org.opencontainers.image.title": "devcontainer-feature-myFeature.tgz"
+ }
+ }
+ ],
+ "annotations": {
+ "dev.containers.metadata": "{\"name\": \"My Feature\",\"id\": \"myFeature\",\"version\": \"1.0.0\",\"dependsOn\": {\"ghcr.io/myotherFeature:1\": {\"flag\": true},\"features.azurecr.io/aThirdFeature:1\": {},\"features.azurecr.io/aFourthFeature:1.2.3\": {}}}"
+ }
+}
+```
+
### Directly referencing a tarball
A Feature can be referenced directly in a user's [`devcontainer.json`](../spec#a-hrefdevcontainerjson-namedevcontainerjson-classanchor-devcontainerjson-a) file by HTTPS URI that points to the tarball from the [package step](#packaging).
@@ -149,9 +178,9 @@ A local Feature is referenced in the devcontainer's `feature` object **relative
Additional constraints exists when including local Features in a project:
-* The project must have a `.devcontainer/` folder at the root of the [**project workspace folder**](/docs/specs/devcontainer-reference.md#project-workspace-folder).
+* The project must have a `.devcontainer/` folder at the root of the [**project workspace folder**](/implementors/spec/#project-workspace-folder).
-* A local Feature's source code **must** be contained within a sub-folder of the `.devcontainer/ folder`.
+* A local Feature's source code **must** be contained within a sub-folder of the `.devcontainer/` folder.
* The sub-folder name **must** match the Feature's `id` field.
diff --git a/_implementors/features.md b/_implementors/features.md
index ae1994a8..8c4ce517 100644
--- a/_implementors/features.md
+++ b/_implementors/features.md
@@ -6,15 +6,13 @@ author: Microsoft
index: 5
---
-Development container "Features" are self-contained, shareable units of installation code and development container configuration. The name comes from the idea that referencing one of them allows you to quickly and easily add more tooling, runtime, or library "Features" into your development container for you or your collaborators to use.
-
-> **Note:** While Features may be installed on top of any base image, the implementation of a Feature might restrict it to a subset of possible base images.
->
-> For example, some Features may be authored to work with a certain linux distro (e.g. debian-based images that use the `apt` package manager).
+**Development Container Features** are self-contained, shareable units of installation code and development container configuration. The name comes from the idea that referencing one of them allows you to quickly and easily add more tooling, runtime, or library "features" into your development container for you or your collaborators to use.
Feature metadata is captured by a `devcontainer-feature.json` file in the root folder of the feature.
-> **Tip:** This section covers details on the Features specification. If you are looking for summarized information on creating your own Features, see the [template](https://github.com/devcontainers/feature-template) and [core Features](https://github.com/devcontainers/features) repositories.
+> **Note:** While Features may be installed on top of any base image, the implementation of a Feature might restrict it to a subset of possible base images. For example, some Features may be authored to work with a certain Linux distro (e.g. debian-based images that use the `apt` package manager).
+>
+> This page covers details on the Features specification. If you are looking for summarized information on creating your own Features, check out the [quick start](https://github.com/devcontainers/feature-starter) and [core Features](https://github.com/devcontainers/features) repositories.
## Folder Structure
@@ -29,16 +27,20 @@ A Feature is a self contained entity in a folder with at least a `devcontainer-f
## devcontainer-feature.json properties
-the `devcontainer-feature.json` file defines information about the feature to be used by any supporting tools and the way the Feature will be executed.
+The `devcontainer-feature.json` file defines metadata about a given Feature.
+
+All properties are optional **except for `id`, `version`, and `name`**.
+
+[devContainerFeature.schema.json](https://github.com/devcontainers/spec/blob/main/schemas/devContainerFeature.schema.json) defines the schema for the `devcontainer-feature.json` file.
The properties of the file are as follows:
| Property | Type | Description |
| :--- | :--- | :--- |
-| `id` | string | ID of the feature/definition. The `id` should be unique in the context of the repository/published package where the feature exists and must match the name of the directory where the `devcontainer-feature.json` resides. |
-| `version` | string | The semantic version of the Feature. |
-| `name` | string | Name of the feature/definition. |
-| `description` | string | Description of the feature/definition. |
+| `id` | string | Required: Identifier of the Feature. Must be unique in the context of the repository where the Feature exists and must match the name of the directory where the `devcontainer-feature.json` resides. |
+| `version` | string | Required: The semantic version of the Feature (e.g: 1.0.0). |
+| `name` | string | Required: A "human-friendly" display name for the Feature. |
+| `description` | string | Description of the Feature. |
| `documentationURL` | string | Url that points to the documentation of the Feature. |
| `licenseURL` | string | Url that points to the license of the Feature. |
| `keywords` | array | List of strings relevant to a user that would search for this definition/Feature. |
@@ -50,8 +52,72 @@ The properties of the file are as follows:
| `securityOpt` | array | Sets container security options like updating the [seccomp profile](https://docs.docker.com/engine/security/seccomp/) when the Feature is used. |
| `entrypoint` | string | Set if the feature requires an "entrypoint" script that should fire at container start up. |
| `customizations` | object | Product specific properties, each namespace under `customizations` is treated as a separate set of properties. For each of this sets the object is parsed, values are replaced while arrays are set as a union. |
-| `installsAfter` | array | Array of ID's of Features that should execute before this one. Allows control for feature authors on soft dependencies between different Features. |
-{: .table .table-bordered .table-responsive}
+| `dependsOn` | object | An object (\**) of Feature dependencies that **must** be satisified before this Feature is installed. Elements follow the same semantics of the `features` object in `devcontainer.json`. [See *Installation Order* for further information](#installation-order). |
+| `installsAfter` | array | Array of ID's of Features (omitting a version tag) that should execute before this one. Allows control for Feature authors on soft dependencies between different Features. [See *Installation Order* for further information](#installation-order). |
+| `legacyIds` | array | Array of old IDs used to publish this Feature. The property is useful for renaming a currently published Feature within a single namespace. |
+| `deprecated` | boolean | Indicates that the Feature is deprecated, and will not receive any further updates/support. This property is intended to be used by the supporting tools for highlighting Feature deprecation. |
+| `mounts` | object | Defaults to unset. Cross-orchestrator way to add additional mounts to a container. Each value is an object that accepts the same values as the [Docker CLI `--mount` flag](https://docs.docker.com/engine/reference/commandline/run/#mount). The Pre-defined [devcontainerId](/implementors/json_reference#variables-in-devcontainerjson) variable may be referenced in the value. For example: `"mounts": [{ "source": "dind-var-lib-docker", "target": "/var/lib/docker", "type": "volume" }]` |
+{: .table .table-bordered}
+
+(**) The ID must refer to either a Feature (1) published to an OCI registry, (2) a Feature Tgz URI, or (3) a Feature in the local file tree. Deprecated Feature identifiers (i.e GitHub Release) are not supported and the presence of this property may be considered a fatal error or ignored. For [local Features (ie: during development)](../features-distribution#addendum-locally-referenced), you may also depend on other local Features by providing a relative path to the Feature, relative to folder containing the active `devcontainer.json`. This behavior of Features within this property again mirror the `features` object in `devcontainer.json`.
+
+
+### Lifecycle Hooks
+
+The following lifecycle hooks may be declared as properties of `devcontainer-feature.json`.
+
+| Property | Type|
+| :--- | :--- |
+| `onCreateCommand` | [string, array, object](/implementors/json_reference#formatting-string-vs-array-properties)|
+| `updateContentCommand` | [string, array, object](/implementors/json_reference#formatting-string-vs-array-properties)|
+| `postCreateCommand` | [string, array, object](/implementors/json_reference#formatting-string-vs-array-properties)|
+| `postStartCommand` | [string, array, object](/implementors/json_reference#formatting-string-vs-array-properties) |
+| `postAttachCommand` | [string, array, object](/implementors/json_reference#formatting-string-vs-array-properties) |
+{: .table .table-bordered}
+
+#### Behavior
+
+Each property mirrors the behavior of the matching property in [`devcontainer.json`](/implementors/json_reference#Lifecycle-scripts), including the behavior that commands are executed from the context of the [project workspace folder](/implementors/spec/#project-workspace-folder).
+
+For each lifecycle hook (in [Feature installation order](/implementors/features/#installation-order)), each command contributed by a Feature is executed in sequence (blocking the next command from executing). Commands provided by Features are always executed _before_ any user-provided lifecycle commands (i.e: in the `devcontainer.json`).
+
+If a Feature provides a given command with the [object syntax](/implementors/json_reference#formatting-string-vs-array-properties), all commands within that group are executed in parallel, but still blocking commands from subsequent Features and/or the `devcontainer.json`.
+
+> **Note**: These properties are stored within [image metadata](/implementors/spec/#merge-logic).
+
+#### Writing scripts to known container path
+
+It may be helpful for a Feature to write scripts to a known, persistent path within the container (i.e. for later use in a given lifecycle hook).
+
+Take for instance the `git-lfs` Feature, which [writes a script](https://github.com/devcontainers/features/blob/4fca96b5e8a4bfc93679098cb19d73c65ce571eb/src/git-lfs/install.sh#L190-L216) to `/usr/local/share/pull-git-lfs-artifacts.sh` during installation.
+
+##### install.sh
+```bash
+PULL_GIT_LFS_SCRIPT_PATH="/usr/local/share/pull-git-lfs-artifacts.sh"
+
+tee "$PULL_GIT_LFS_SCRIPT_PATH" > /dev/null \
+<< EOF
+#!/bin/sh
+set -e
+<...truncated...>
+EOF
+```
+
+This script is then executed during the [`postCreateCommand` lifecycle hook](https://github.com/devcontainers/features/blob/4fca96b5e8a4bfc93679098cb19d73c65ce571eb/src/git-lfs/devcontainer-feature.json#L23).
+
+##### devcontainer-feature.json
+```jsonc
+{
+ "id": "git-lfs",
+ "version": "1.1.0",
+ "name": "Git Large File Support (LFS)",
+ // <...truncated...>
+ "postCreateCommand": "/usr/local/share/pull-git-lfs-artifacts.sh",
+ "installsAfter": [
+ "ghcr.io/devcontainers/features/common-utils"
+ ]
+}
+```
### The `options` property
@@ -78,7 +144,7 @@ The options property contains a map of option IDs and their related configuratio
| `optionId.enum` | array | A strict list of allowed string values. Free-form values are **not** allowed. Omit when using `optionId.proposals`. |
| `optionId.default` | string or boolean | Default value for the option. |
| `optionId.description` | string | Description for the option. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
### User environment variables
@@ -88,11 +154,11 @@ Feature scripts run as the `root` user and sometimes need to know which user acc
Additionally, the home folders of the two users are passed to the Feature scripts as `_REMOTE_USER_HOME` and `_CONTAINER_USER_HOME` environment variables.
-The container user can be set with `containerUser` in the devcontainer.json and image metadata, `user` in the docker-compose.yml, `USER` in the Dockerfile, and can be passed down from the base image.
+The container user can be set with `containerUser` in the `devcontainer.json` and image metadata, `user` in the `docker-compose.yml`, `USER` in the Dockerfile, and can be passed down from the base image.
### Dev Container ID
-An identifier will be referred to as `${devcontainerId}` in the devcontainer.json and the Feature metadata and that will be replaced with the dev container's id. It should only be used in parts of the configuration and metadata that is not used for building the image because that would otherwise prevent pre-building the image at a time when the dev container's id is not known yet. Excluding boolean, numbers and enum properties the properties supporting `${devcontainerId}` in the Feature metadata are: `entrypoint`, `mounts`, `customizations`.
+An identifier will be referred to as `${devcontainerId}` in the `devcontainer.json` and the Feature metadata and that will be replaced with the dev container's id. It should only be used in parts of the configuration and metadata that is not used for building the image because that would otherwise prevent pre-building the image at a time when the dev container's id is not known yet. Excluding boolean, numbers and enum properties the properties supporting `${devcontainerId}` in the Feature metadata are: `entrypoint`, `mounts`, `customizations`.
Implementations can choose how to compute this identifier. They must ensure that it is unique among other dev containers on the same Docker host and that it is stable across rebuilds of dev containers. The identifier must only contain alphanumeric characters. We describe a way to do this below.
@@ -170,11 +236,11 @@ Below is a valid `features` object provided as an example.
}
```
-> Note: The `:latest` version annotation is added implicitly if omitted. To pin to a specific package version ([example](https://github.com/devcontainers/features/pkgs/container/features/go/versions)), append it to the end of the Feature.
+> **Note:** The `:latest` version annotation is added implicitly if omitted. To pin to a specific package version ([example](https://github.com/devcontainers/features/pkgs/container/features/go/versions)), append it to the end of the Feature.
An option's value can be provided as either a `string` or `boolean`, and should match what is expected by the feature in the `devcontainer-feature.json` file.
-As a shorthand, the value of a `feature` can be provided as a single string. This string is mapped to an option called `version`. In the example below, both examples are equivalent.
+As a shorthand, the value of the `features` property can be provided as a single string. This string is mapped to an option called `version`. In the example below, both examples are equivalent.
```jsonc
"features": {
@@ -189,7 +255,7 @@ As a shorthand, the value of a `feature` can be provided as a single string. Thi
}
```
-### Referencing a feature
+### Referencing a Feature
The `id` format specified dicates how a supporting tool will locate and download a given feature. `id` is one of the following:
@@ -198,11 +264,11 @@ The `id` format specified dicates how a supporting tool will locate and download
| `//[:]` | Reference to feature in OCI registry(*) | `ghcr.io/user/repo/go` `ghcr.io/user/repo/go:1` `ghcr.io/user/repo/go:latest`|
| `https://` | Direct HTTPS URI to a tarball. | `https://github.com/user/repo/releases/devcontainer-feature-go.tgz` |
| `./`| A relative directory(**) to folder containing a devcontainer-feature.json. | `./myGoFeature` |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
(*) OCI registry must implement the [OCI Artifact Distribution Specification](https://github.com/opencontainers/distribution-spec). Some implementors can be [found here](https://oras.land/implementors/).
-(**) The provided path is always relative to the folder containing the `devcontainer.json`. Further requirements are outlined in the [Locally Referenced Addendum](devcontainer-features-distribution#Addendum:-Locally-Referenced).
+(**) The provided path is always relative to the folder containing the `devcontainer.json`. Further requirements are outlined in the [Locally Referenced Addendum](../features-distribution#addendum-locally-referenced).
## Versioning
@@ -212,7 +278,7 @@ Tooling that handles releasing Features will not republish Features if that exac
## Authoring
-Features can be authored in a number of languages, the most straightforward being bash scripts. If a Feature is authored in a different language information about it should be included in the metadata so that users can make an informed choice about it.
+Features can be authored in a number of languages, the most straightforward being bash scripts. If a Feature is authored in a different language, information about it should be included in the metadata so that users can make an informed choice about it.
Reference information about the application required to execute the Feature should be included in `devcontainer-feature.json` in the metadata section.
@@ -222,7 +288,7 @@ If the Feature is included in a folder as part of the repository that contains `
## Release
-_For information on distributing Features, see [the dev container features distribution page](../features-distribution)._
+_For information on distributing Features, see the [Features distribution page](../features-distribution)._
## Execution
@@ -232,7 +298,7 @@ The `install.sh` script for each Feature should be executed as `root` during a c
To ensure that the appropriate shell is used, the execute bit should be set on `install.sh` and the file invoked directly (e.g. `chmod +x install.sh && ./install.sh`).
-> **Note:** It is recommended that Feature authers write `install.sh` using a shell available by default in their supported distributions (e.g., `bash` in Debian/Ubuntu or Fedora, `sh` in Alpine). In the event a different shell is required (e.g., `fish`), `install.sh` can be used to boostrap by checking for the presence of the desired shell, installing it if needed, and then invoking a secondary script using the shell.
+> **Note:** It is recommended that Feature authors write `install.sh` using a shell available by default in their supported distributions (e.g., `bash` in Debian/Ubuntu or Fedora, `sh` in Alpine). In the event a different shell is required (e.g., `fish`), `install.sh` can be used to boostrap by checking for the presence of the desired shell, installing it if needed, and then invoking a secondary script using the shell.
>
> The `install.sh` file can similarly be used to bootstrap something written in a compiled language like Go. Given the increasing likelihood that a Feature needs to work on both x86_64 and arm64-based devices (e.g., Apple Silicon Macs), `install.sh` can detect the current architecture (e.g., using something like `uname -m` or `dpkg --print-architecture`), and then invoke the right executable for that architecture.
@@ -240,53 +306,170 @@ To ensure that the appropriate shell is used, the execute bit should be set on `
By default, Features are installed on top of a base image in an order determined as optimal by the implementing tool.
-If any of the following properties are provided in the Feature's `devcontainer-feature.json`, or the user's `devcontainer.json`, the order indicated by these propert(ies) are respected (with decreasing precedence).
+If any of the following properties are provided in the Feature's `devcontainer-feature.json`, or the user's `devcontainer.json`, the order indicated by these propert(ies) are respected.
-1. The `overrideFeatureInstallOrder` property in user's `devcontainer.json`. Allows users to control the order of execution of their Features.
-2. The `installsAfter` property defined as part of a Feature's `devcontainer-feature.json`.
+* The `dependsOn` property defined as a part of a Feature's `devcontainer-feature.json`.
+* The `installsAfter` property defined as part of a Feature's `devcontainer-feature.json`.
+* The `overrideFeatureInstallOrder` property in user's `devcontainer.json`. Allows users to control the order of execution of their Features.
-#### (1) The `overrideFeatureInstallOrder` property
+#### dependsOn
-This property is declared by the user in their `devcontainer.json` file.
+The optional `dependsOn` property indicates a set of required, "hard" dependencies for a given Feature.
-Any un-versioned feature IDs listed in this array will be installed before all other Features, in the provided order. Any omitted Features will be installed in an order selected by the implementing tool, or ordered via the `installsAfter` property _after_ any Features listed in the `overrideFeatureInstallOrder` array, if applicable.
+The `dependsOn` property is declared in a Feature's `devcontainer-feature.json` metadata file. Elements of this property mirror the semantics of the `features` object in `devcontainer.json`. Therefore, all dependencies may provide the relevant options, or an empty object (eg: `"bar:123": {}`) if the Feature's default options are sufficient. Identical Features that provide different options are treated as _different_ Features (see [Feature equality](#definition-feature-equality) for more info).
-All un-versioned Feature `id`s provided in `overrideFeatureInstallOrder` must also exist in the `features` property of a user's `devcontainer.json`. For instance, all the Features which follows the OCI registry format would include everything except for the label that contains the version (`//` without the `:`).
+All Features indicated in the `dependsOn` property **must** be satisfied (a Feature [equal](#definition-feature-equality) to each dependency is present in the installation order) _before_ the given Feature is set to be installed. If any of the Features indicated in the `dependsOn` property cannot be installed (e.g due to circular dependency, failure to resolve the Feature, etc) the entire dev container creation should fail.
-Example:
+The `dependsOn` property must be evaluated recursively. Therefore, if a Feature dependency has its own `dependsOn` property, that Feature's dependencies must also be satisfied before the given Feature is installed.
+
+```json
+{
+ "name": "My Feature",
+ "id": "myFeature",
+ "version": "1.0.0",
+ "dependsOn": {
+ "foo:1": {
+ "flag": true
+ },
+ "bar:1.2.3": {},
+ "baz@sha256:a4cdc44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" {},
+ }
+}
```
- "features": {
- "ghcr.io/devcontainers/features/java:1",
- "ghcr.io/devcontainers/features/node:1",
- },
- "overrideFeatureInstallOrder": [
- "ghcr.io/devcontainers/features/node"
- ]
+
+In the snippet above, `myfeature` MUST be installed after `foo`, `bar`, and `baz`. If the Features provided via the `dependsOn` property declare their own dependencies, those must also be satisfied before the Feature is installed.
+
+#### installsAfter
+
+The `installsAfter` property indicates a "soft dependency" that influences the installation order of Features that are already queued to be installed. The effective behavior of this property is the same as `dependsOn`, with the following differences:
+
+- `installsAfter` is **not** evaluated recursively.
+- `installsAfter` only influences the installation order of Features that are **already set to be installed**. Any Feature not set to be installed after (1) resolving the `dependsOn` dependency tree or (2) indicated by the user's `devcontainer.json` should not be added to the installation list.
+- The Feature indicated by `installsAfter` can **not** provide options, nor are they able to be pinned to a specific version tag or digest. Resolution to the canonical name should still be performed (eg: If the Feature has been [renamed](#steps-to-rename-a-feature)).
+
+```
+{
+ "name": "My Feature",
+ "id": "myFeature",
+ "version": "1.0.0",
+ "installsAfter": [
+ "foo",
+ "bar"
+ ]
+}
```
-| Property | Type | Description |
-| :--- | :--- | :--- |
-| `overrideFeatureInstallOrder` | array | Array consisting of the Feature `id` (without the semantic version) of Features in the order the user wants them to be installed. |
-{: .table .table-bordered .table-responsive}
+In the snippet above, `myfeature` must be installed after `foo` and `bar` **if** the Feature is already queued to be installed. If `second` and `third` are not already queued to be installed, this dependency relationship should be ignored.
-#### (2) The `installsAfter` Feature property
+#### overrideFeatureInstallOrder
-This property is defined in an individual Feature's `devcontainer-feature.json` file by the feature author. `installsAfter` allows an author to provide the tooling hints on loose dependencies between Features.
+The `overrideFeatureInstallOrder` property of `devcontainer.json` is an array of Feature IDs that are to be installed in descending priority order as soon as its dependencies outlined above are installed.
-After `overrideFeatureInstallOrder` is resolved, any remaining Features that declare an `installsAfter` must be installed after the Features declared in the property, provided that the features have also been declared in the `features` property.
+> This property may not indicate an installation order that is inconsistent with the resolved dependency graph (see [dependency algorithm](#dependency-installation-order-algorithm)). If the `overrideFeatureInstallOrder` property is inconsistent with the dependency graph, the implementing tool should fail the dependency resolution step.
-| Property | Type | Description |
-| :--- | :--- | :--- |
-| `installsAfter` | array | Array consisting of the Feature `id` that should be installed before the given Feature. |
-{: .table .table-bordered .table-responsive}
+This evaluation is performed by assigning a [`roundPriority`](#2-assigning-round-priority) to all nodes that match match the Feature identifier (version omitted) present in the property.
+
+For example, given `n` Features in the `overrideFeatureInstallOrder` array, the orchestrating tool should assign a `roundPriority` of `n - idx` to each Feature, where `idx` is the zero-based index of the Feature in the array.
+
+For example:
+
+```javascript
+overrideFeatureInstallOrder = [
+ "foo",
+ "bar",
+ "baz"
+]
+```
+
+would result in the following `roundPriority` assignments:
+
+```javascript
+const roundPriority = {
+ "foo": 3,
+ "bar": 2,
+ "baz": 1
+}
+```
+
+This property must not influence the dependency relationship as defined by the dependency graph (see [dependency graph](#1-build-a-dependency-graph)) and shall only be evaulated at the round-based sorting step (see [round sort](#3-round-based-sorting)). Put another way, this property cannot "pull forward" a Feature until all of its dependencies (both soft and hard) have been installed. After a Feature's dependencies have been installed in other rounds, this property should "pull forward" each Feature as early as possible (given the order of identifiers in the array).
+
+Similar to `installsAfter`, this property's members may not provide options, nor are they able to be pinned to a specific version tag or digest.
+
+If a Feature is indicated in `overrideFeatureInstallOrder` but not a member of the dependency graph (it is not queued to be installed), the orchestrating tool may fail the dependency resolution step.
+
+> ## Definitions
+> ### Definition: Feature Equality
+
+>
+> This specification defines two Features as equal if both Features point to the same exact contents and are executed with > the same options.
+>
+> **For Features published to an OCI registry**, two Feature are identical if their manifest digests are equal, and the > options executed against the Feature are equal (compared value by value). Identical manifest digests implies that the tgz contents of the Feature and its entire `devcontainer-feature.json` are identical. If any of these conditions are not met, the Features are considered not equal.
+>
+> **For Features fetched by HTTPS URI**, two Features are identical if the contents of the tgz are identical (hash to the > same value), and the options executed against the Feature are equal (compared value by value). If any of these conditions are not met, the Features are considered not equal.
+>
+> **For local Features**, each Feature is considered unique and not equal to any other local Feature.
+>
+> ### Definition: Round Stable Sort
+
+>
+> To prevent non-deterministic behavior, the algorithm will sort each **round** according to the following rules:
+>
+> - Compare and sort each Feature lexiographically by their fully qualified resource name (For OCI-published Features, that means the ID without version or digest.). If the comparison is equal:
+> - Compare and sort each Feature from oldest to newest tag (`latest` being the "most new"). If the comparision is equal:
+> - Compare and sort each Feature by their options by:
+> - Greatest number of user-defined options (note omitting an option will default that value to the Feature's default value and is not considered a user-defined option). If the comparison is equal:
+> - Sort the provided option keys lexicographically. If the comparison is equal:
+> - Sort the provided option values lexicographically. If the comparision is equal:
+> - Sort Features by their canonical name (For OCI-published Features, the Feature ID resolved to the digest hash).
+>
+> If there is no difference based on these comparator rules, the Features are considered equal.
+
+> ## Dependency installation order algorithm
+>
+> An implementing tool is responsible for calculating the Feature installation order (or providing an error if no valid installation order can be resolved). The set of Features to be installed is the union of user-defined Features (those directly indicated in the user's `devcontainer.json` and their dependencies (those indicated by the `dependsOn` or `installsAfter` property, taking into account the user dev container's `overrideFeatureInstallOrder` property). The implmenting tool will perform the following steps:
+>
+> ### (1) Build a dependency graph
+>
+> From the user-defined Features, the orchestrating tool will build a dependency graph. The graph will be built by traversing the `dependsOn` and `installsAfter` properties of each Feature. The metadata for each dependency is then fetched and the node added as an edge to to the dependent Feature. For `dependsOn` dependencies, the dependency will be fed back into the worklist to be recursively resolved.
+>
+> An accumulator is maintained with all uniquely discovered and user-provided Features, each with a reference to its dependencies. If the exact Feature (see **Feature Equality**) has already been added to the accumulator, it will not be added again. The accumulator will be fed into (B3) after the Feature tree has been resolved.
+>
+> The graph may be stored as an adjacency list with two kinds of edges (1) `dependsOn` edges or "hard dependencies" and (2) `installsAfter` edges or "soft dependencies".
+>
+> ### (2) Assigning round priority
+>
+> Each node in the graph has an implicit, default `roundPriority` of 0.
+>
+> To influence installation order globally while still honoring the dependency graph of built in **(1)**, `roundPriority` values may be tweaks for each Feature. When each round is calculated in **(3)**, only the Features equal to the max `roundPriority` of that set will be committed (the remaining will be > uncommitted and reevaulated in subsequent rounds).
+>
+> The `roundPriority` is set to a non-zero value in the following instances:
+>
+> - If the [`devcontainer.json` contains an `overrideFeatureInstallOrder`](#overrideFeatureInstallOrder).
+>
+> #### (3) Round-based sorting
+>
+> Perform a sort on the result of **(1)** in rounds. This sort will rearrange Features, producing a sorted list of Features to install. The sort will be performed as follows:
+>
+> Start with all the elements from **(2)** in a `worklist` and an empty list `installationOrder`. While the `worklist` is not empty, iterate through each element in the `worklist` and check if all its dependencies (if any) are already members of `installationOrder`. If the check is true, add it to an intermediate list `round` If not, skip it. Equality is determined in **Feature Equality**.
+>
+> Then for each intermediate `round` list, commit to `installationOrder` only those nodes who share the maximum `roundPriority`. Return all nodes in `round` with a strictly lower `roundPriority` to the `worklist` to be reprocessed in subsequent iterations. If there are multiple nodes with the same `roundPriority`, commit them to `installationOrder` with a final sort according to **Round Stable Sort**.
+>
+> Repeat for as many rounds as necessary until `worklist` is empty. If there is ever a round where no elements are added to `installationOrder`, the algorithm should terminate and return an error. This indicates a circular dependency or other fatal error in the dependency graph. Implementations should attempt to provide the user with information about the error and possible mitigation strategies.
+>
+> ### Notes
+>
+> From an implementation point of view, `installsAfter` nodes may be added as a separate set of directed edges, just as `dependsOn` nodes are added as directed edges (see **(1)**). Before round-based installation and sorting **(3)**, an orchestrating tool should remove all `installsAfter` directed edges that do not correspond with a Feature in the `worklist` that is set to be installed. In each round, a Feature can then be installed if all its requirements (both `dependsOn` and `installsAfter` dependencies) have been fulfilled in previous rounds.
+>
+> An implemention should fail the dependency resolution step if the evaluation of the `installsAfter` property results in an inconsistent state (eg: a circular dependency).
+>
### Option Resolution
-A Feature's 'options' - specified as the value of a single Feature key/value pair in the user's `devcontainer.json` - are passed to the Feature as environment variables.
+A Feature's `options` - specified as the value of a single Feature key/value pair in the user's `devcontainer.json` - are passed to the Feature as environment variables.
A supporting tool will parse the `options` object provided by the user. If a value is provided for a Feature, it will be emitted to a file named `devcontainer-features.env` following the format `=`.
-To ensure a option that is valid as an environment variable, the follow substitutions are performed.
+To ensure a option that is valid as an environment variable, the follow substitutions are performed:
```javascript
(str: string) => str
@@ -330,7 +513,7 @@ The user's `devcontainer.json` declared the python Feature like so:
```jsonc
"features": {
- "python": {
+ "ghcr.io/devcontainers/features/python:1": {
"version": "3.10",
"pip": false
}
@@ -361,11 +544,51 @@ Pip? false
Optimize? true
```
+### Steps to rename a Feature
+
+1. Update the Feature [source code](./features-distribution.md#source-code) folder and the `id` property in the [devcontainer-feature.json properties](#devcontainer-featurejson-properties) to reflect the new `id`. Other properties (`name`, `documentationUrl`, etc.) can optionally be updated during this step.
+2. Add or update the `legacyIds` property to the Feature, including the previously used `id`.
+3. Bump the semantic version of the Feature.
+4. Rerun the `devcontainer features publish` command, or equivalent tool that implements the [Features distribution specification](./features-distribution.md#distribution).
+
+#### Example: Renaming a Feature
+
+Let's say we currently have a `docker-from-docker` Feature 👇
+
+Current `devcontainer-feature.json` :
+
+```jsonc
+{
+ "id": "docker-from-docker",
+ "version": "2.0.1",
+ "name": "Docker (Docker-from-Docker)",
+ "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-from-docker",
+ ....
+}
+```
+
+We'd want to rename this Feature to `docker-outside-of-docker`. The source code folder of the Feature will be updated to `docker-outside-of-docker` and the updated `devcontainer-feature.json` will look like 👇
+
+```jsonc
+{
+ "id": "docker-outside-of-docker",
+ "version": "2.0.2",
+ "name": "Docker (Docker-outside-of-Docker)",
+ "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker",
+ "legacyIds": [
+ "docker-from-docker"
+ ]
+ ....
+}
+```
+
+**Note** - The semantic version of the Feature defined by the `version` property should be **continued** and should not be restarted at `1.0.0`.
+
### Implementation notes
There are several things to keep in mind for an application that implements Features:
-- The order of execution of Features is determined by the application, based on the `installAfter` property used by Feature authors. It can be overridden by users if necessary with the `overrideFeatureInstallOrder` in `devcontainer.json`.
+- The order of execution of Features is determined by the application, based on the `installsAfter` property used by Feature authors. It can be overridden by users if necessary with the `overrideFeatureInstallOrder` in `devcontainer.json`.
- Features are used to create an image that can be used to create a container or not.
- Parameters like `privileged`, `init` are included if just 1 feature requires them.
- Parameters like `capAdd`, `securityOp` are concatenated.
diff --git a/_implementors/json_reference.md b/_implementors/json_reference.md
index 50be1b57..24320635 100644
--- a/_implementors/json_reference.md
+++ b/_implementors/json_reference.md
@@ -6,9 +6,9 @@ author: Microsoft
index: 4
---
-The `devcontainer.json` file contains any needed metadata and settings required to configurate a **development container** for a given well-defined tool and runtime stack. It can be used by [tools and services that support the dev container spec](../../supporting) to create a **development environment** that contains one or more **development containers**.
+The `devcontainer.json` file contains any needed metadata and settings required to configure a **development container** for a given well-defined tool and runtime stack. It can be used by [tools and services that support the dev container spec](../../supporting) to create a **development environment** that contains one or more **development containers**.
-Metadata properties marked with a 🏷️️ can be stored in the `devcontainer.metadata` **container image label** in addition to `devcontainer.json`. This label can contain an array of json snippets that will be automatically merged with `devcontainer.json` contents (if any) when a container is created.
+Metadata properties marked with a 🏷️️ can be stored in the `devcontainer.metadata` **[container image label](/implementors/reference/#labels)** in addition to `devcontainer.json`. This label can contain an array of json snippets that will be automatically merged with `devcontainer.json` contents (if any) when a container is created.
## General devcontainer.json properties
@@ -18,23 +18,23 @@ Metadata properties marked with a 🏷️️ can be stored in the `devcontainer.
| `forwardPorts` 🏷️ | array | An array of port numbers or `"host:port"` values (e.g. `[3000, "db:5432"]`) that should always be forwarded from inside the primary container to the local machine (including on the web). The property is most useful for forwarding ports that cannot be auto-forwarded because the related process that starts before the `devcontainer.json` supporting service / tool connects or for forwarding a service not in the primary container in Docker Compose scenarios (e.g. `"db:5432"`). Defaults to `[]`. |
| `portsAttributes` 🏷️ | object | Object that maps a port number, `"host:port"` value, range, or regular expression to a set of default options. See [port attributes](#port-attributes) for available options. For example: `"portsAttributes": {"3000": {"label": "Application port"}}` |
| `otherPortsAttributes` 🏷️ | object | Default options for ports, port ranges, and hosts that aren't configured using `portsAttributes`. See [port attributes](#port-attributes) for available options. For example: `"otherPortsAttributes": {"onAutoForward": "silent"}` |
-| `remoteEnv` 🏷️ | object | A set of name-value pairs that sets or overrides environment variables for the `devcontainer.json` supporting service / tool (or sub-processes like terminals) but not the container as a whole. Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the values. |
-| `remoteUser` 🏷️ | string | Overrides the user that `devcontainer.json` supporting services tools / runs as in the container (along with sub-processes like terminals, tasks, or debugging). Does not change the user the container as a whole runs as which can be set using `containerUser`. Defaults to the user the container as a whole is running as (often `root`). |
-| `containerEnv` 🏷️ | object | A set of name-value pairs that sets or overrides environment variables for the container. Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the values. For example: `"containerEnv": { "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }` If you want to reference an existing container variable while setting this one (like updating the `PATH`), use `remoteEnv` instead. |
+| `containerEnv` 🏷️ | object | A set of name-value pairs that sets or overrides environment variables for the container. Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the values. For example: `"containerEnv": { "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }` If you want to reference an existing container variable while setting this one (like updating the `PATH`), use `remoteEnv` instead. `containerEnv` will set the variable on the Docker container itself, so all processes spawned in the container will have access to it. But it will also be static for the life of the container - you must rebuild the container to update the value. We recommend using `containerEnv` (over `remoteEnv`) as much as possible since it allows all processes to see the variable and isn't client-specific. |
+| `remoteEnv` 🏷️ | object | A set of name-value pairs that sets or overrides environment variables for the `devcontainer.json` supporting service / tool (or sub-processes like terminals) but not the container as a whole. Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the values. You may want to use `remoteEnv` (over `containerEnv`) if the value isn't static since you can update its value without having to rebuild the full container. |
+| `remoteUser` 🏷️ | string | Overrides the user that `devcontainer.json` supporting services tools / runs as in the container (along with sub-processes like terminals, tasks, or debugging). Does not change the user the container as a whole runs as which can be set using `containerUser`. Defaults to the user the container as a whole is running as (often `root`). You may learn more in the [remoteUser section below](#remoteUser). |
| `containerUser` 🏷️ | string | Overrides the user for all operations run as inside the container. Defaults to either `root` or the last `USER` instruction in the related Dockerfile used to create the image. If you want any connected tools or related processes to use a different user than the one for the container, see `remoteUser`. |
| `updateRemoteUserUID` 🏷️ | boolean | On Linux, if `containerUser` or `remoteUser` is specified, the user's UID/GID will be updated to match the local user's UID/GID to avoid permission problems with bind mounts. Defaults to `true`. |
| `userEnvProbe` 🏷️ | enum | Indicates the type of shell to use to "probe" for user environment variables to include in `devcontainer.json` supporting services' / tools' processes: `none`, `interactiveShell`, `loginShell`, or `loginInteractiveShell` (default). The specific shell used is based on the default shell for the user (typically bash). For example, bash interactive shells will typically include variables set in `/etc/bash.bashrc` and `~/.bashrc` while login shells usually include variables from `/etc/profile` and `~/.profile`. Setting this property to `loginInteractiveShell` will get variables from all four files. |
| `overrideCommand` 🏷️ | boolean | Tells `devcontainer.json` supporting services / tools whether they should run `/bin/sh -c "while sleep 1000; do :; done"` when starting the container instead of the container's default command (since the container can shut down if the default command fails). Set to `false` if the default command must run for the container to function properly. Defaults to `true` for when using an image Dockerfile and `false` when referencing a Docker Compose file. |
| `shutdownAction` 🏷️ | enum | Indicates whether `devcontainer.json` supporting tools should stop the containers when the related tool window is closed / shut down. Values are `none`, `stopContainer` (default for image or Dockerfile), and `stopCompose` (default for Docker Compose). |
| `init` 🏷️ | boolean | Defaults to `false`. Cross-orchestrator way to indicate whether the [tini init process](https://github.com/krallin/tini) should be used to help deal with zombie processes. |
-| `privileged` 🏷️ | boolean | Defaults to `false`. Cross-orchestrator way to cause the container to run in priviledged mode (`--priviledged`). Required for things like Docker-in-Docker, but has security implications particularly when running directly on Linux. |
+| `privileged` 🏷️ | boolean | Defaults to `false`. Cross-orchestrator way to cause the container to run in privileged mode (`--privileged`). Required for things like Docker-in-Docker, but has security implications particularly when running directly on Linux. |
| `capAdd` 🏷️ | array | Defaults to `[]`. Cross-orchestrator way to add capabilities typically disabled for a container. Most often used to add the `ptrace` capability required to debug languages like C++, Go, and Rust. For example: `"capAdd": ["SYS_PTRACE"]` |
| `securityOpt` 🏷️ | array | Defaults to `[]`. Cross-orchestrator way to set container security options. For example: `"securityOpt": [ "seccomp=unconfined" ]` |
-| `mounts` 🏷️ | string or object | Defaults to unset. Cross-orchestrator way to add additional mounts to a container. Each value is a string that accepts the same values as the [Docker CLI `--mount` flag](https://docs.docker.com/engine/reference/commandline/run/#add-bind-mounts-or-volumes-using-the---mount-flag). Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the value. For example: `"mounts": [{ "source": "dind-var-lib-docker", "target": "/var/lib/docker", "type": "volume" }]` |
+| `mounts` 🏷️ | string or object | Defaults to unset. Cross-orchestrator way to add additional mounts to a container. Each value is a string that accepts the same values as the [Docker CLI `--mount` flag](https://docs.docker.com/engine/reference/commandline/run/#mount). Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the value. For example: `"mounts": [{ "source": "dind-var-lib-docker", "target": "/var/lib/docker", "type": "volume" }]` |
| `features` | object | An object of [Dev Container Feature IDs](../../features) and related options to be added into your primary container. The specific options that are available varies by feature, so see its documentation for additional details. For example: `"features": { "ghcr.io/devcontainers/features/github-cli": {} }` |
-| `overrideFeatureInstallOrder` | array | By default, Features will attempt to automatically set the order they are installed based on a `installsAfter` property within each of them. This property allows you to override the Feature install order when needed. For example: `"overrideFeatureInstallorder": [ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/github-cli" ]` |
-| `customizations` 🏷️ | object | Product specific properties, defined in [supporting tools](../../supporting) |
-{: .table .table-bordered .table-responsive}
+| `overrideFeatureInstallOrder` | array | By default, Features will attempt to automatically set the order they are installed based on a `installsAfter` property within each of them. This property allows you to override the Feature install order when needed. For example: `"overrideFeatureInstallĐžrder": [ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/github-cli" ]` |
+| `customizations` 🏷️| object | Product specific properties, defined in [supporting tools](../../supporting) |
+{: .table .table-bordered}
## Scenario specific properties
@@ -47,24 +47,25 @@ The focus of `devcontainer.json` is to describe how to enrich a container for th
| `image` | string | **Required** when using an image. The name of an image in a container registry ([DockerHub](https://hub.docker.com), [GitHub Container Registry](https://docs.github.com/packages/guides/about-github-container-registry), [Azure Container Registry](https://azure.microsoft.com/services/container-registry/)) that `devcontainer.json` supporting services / tools should use to create the dev container. |
| `build.dockerfile` | string |**Required** when using a Dockerfile. The location of a [Dockerfile](https://docs.docker.com/engine/reference/builder/) that defines the contents of the container. The path is relative to the `devcontainer.json` file. |
| `build.context` | string | Path that the Docker build should be run from relative to `devcontainer.json`. For example, a value of `".."` would allow you to reference content in sibling directories. Defaults to `"."`. |
-| `build.args` | Object | A set of name-value pairs containing [Docker image build arguments](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg) that should be passed when building a Dockerfile. Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the values. Defaults to not set. For example: `"build": { "args": { "MYARG": "MYVALUE", "MYARGFROMENVVAR": "${localEnv:VARIABLE_NAME}" } }` |
-| `build.target` | string | A string that specifies a [Docker image build target](https://docs.docker.com/engine/reference/commandline/build/#specifying-target-build-stage---target) that should be passed when building a Dockerfile. Defaults to not set. For example: `"build": { "target": "development" }` |
-| `build.cacheFrom` | string, array | A string or array of strings that specify one or more images to use as caches when building the image. Cached image identifiers are passed to the `docker build` command with `--cache-from`. Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array properties. |
-| `appPort` | integer, string, array | In most cases, we recommend using the new [forwardPorts property](#general-properties). This property accepts a port or array of ports that should be published locally when the container is running.Unlike `forwardPorts`, your application may need to listen on all interfaces (`0.0.0.0`) not just `localhost` for it to be available externally. Defaults to `[]`. Learn more about publishing vs forwarding ports [here](#publishing-vs-forwarding-ports). Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array properties. |
-| `workspaceMount` | string | Requires `workspaceFolder` be set as well. Overrides the default local mount point for the workspace when the container is created. Supports the same values as the [Docker CLI `--mount` flag](https://docs.docker.com/engine/reference/commandline/run/#add-bind-mounts-or-volumes-using-the---mount-flag). Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the value. For example: `"workspaceMount": "source=${localWorkspaceFolder}/sub-folder,target=/workspace,type=bind,consistency=cached", "workspaceFolder": "/workspace"` |
+| `build.args` | Object | A set of name-value pairs containing [Docker image build arguments](https://docs.docker.com/engine/reference/commandline/build/#build-arg) that should be passed when building a Dockerfile. Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the values. Defaults to not set. For example: `"build": { "args": { "MYARG": "MYVALUE", "MYARGFROMENVVAR": "${localEnv:VARIABLE_NAME}" } }` |
+| `build.options` | array | An array of [Docker image build options](https://docs.docker.com/engine/reference/commandline/build/#options) that should be passed to the build command when building a Dockerfile. Defaults to `[]`. For example: `"build": { "options": [ "--add-host=host.docker.internal:host-gateway" ] }` |
+| `build.target` | string | A string that specifies a [Docker image build target](https://docs.docker.com/engine/reference/commandline/build/#target) that should be passed when building a Dockerfile. Defaults to not set. For example: `"build": { "target": "development" }` |
+| `build.cacheFrom` | string, array | A string or array of strings that specify one or more images to use as caches when building the image. Cached image identifiers are passed to the `docker build` command with `--cache-from`. |
+| `appPort` | integer, string, array | In most cases, we recommend using the new [forwardPorts property](#general-properties). This property accepts a port or array of ports that should be published locally when the container is running. Unlike `forwardPorts`, your application may need to listen on all interfaces (`0.0.0.0`) not just `localhost` for it to be available externally. Defaults to `[]`. Learn more about publishing vs forwarding ports [here](#publishing-vs-forwarding-ports). Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array properties. |
+| `workspaceMount` | string | Requires `workspaceFolder` be set as well. Overrides the default local mount point for the workspace when the container is created. Supports the same values as the [Docker CLI `--mount` flag](https://docs.docker.com/engine/reference/commandline/run/#mount). Environment and [pre-defined variables](#variables-in-devcontainerjson) may be referenced in the value. For example: `"workspaceMount": "source=${localWorkspaceFolder}/sub-folder,target=/workspace,type=bind,consistency=cached", "workspaceFolder": "/workspace"` |
| `workspaceFolder` | string | Requires `workspaceMount` be set. Sets the default path that `devcontainer.json` supporting services / tools should open when connecting to the container. Defaults to the automatic source code mount location. |
| `runArgs` | array | An array of [Docker CLI arguments](https://docs.docker.com/engine/reference/commandline/run/) that should be used when running the container. Defaults to `[]`. For example, this allows ptrace based debuggers like C++ to work in the container: `"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ]` . |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
### Docker Compose specific properties
| Property | Type | Description |
|:------------------|:------------|:------------|
| `dockerComposeFile` | string, array | **Required** when using [Docker Compose](https://docs.docker.com/compose/). Path or an ordered list of paths to Docker Compose files relative to the `devcontainer.json` file. Using an array is useful [when extending your Docker Compose configuration](https://docs.docker.com/compose/extends/#multiple-compose-files). The order of the array matters since the contents of later files can override values set in previous ones. The default `.env` file is picked up from the root of the project, but you can use `env_file` in your Docker Compose file to specify an alternate location. Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array properties. |
-| `service` | string | **Required** when using [Docker Compose](https://docs.docker.com/compose/). The name of the service `devcontainer.json` supporting services / tools should connect to once running. |
+| `service` | string | **Required** when using [Docker Compose](https://docs.docker.com/compose/). The name of the service `devcontainer.json` supporting services / tools should connect to once running. |
| `runServices` | array | An array of services in your Docker Compose configuration that should be started by `devcontainer.json` supporting services / tools. These will also be stopped when you disconnect unless `"shutdownAction"` is `"none"`. Defaults to all services. |
| `workspaceFolder` | string | Sets the default path that `devcontainer.json` supporting services / tools should open when connecting to the container (which is often the path to a volume mount where the source code can be found in the container). Defaults to `"/"`. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
## Tool-specific properties
@@ -76,14 +77,14 @@ When creating or working with a dev container, you may need different commands t
| Property | Type | Description |
|:------------------|:------------|:------------|
-| `initializeCommand` | string, array, object | A command string or list of command arguments to run on the **host machine** before the container is created. .
⚠️ The command is run wherever the source code is located on the host. For cloud services, this is in the cloud.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
+| `initializeCommand` | string, array, object | A command string or list of command arguments to run on the **host machine** during initialization, including during container creation and on subsequent starts. The command may run more than once during a given session.
⚠️ The command is run wherever the source code is located on the host. For cloud services, this is in the cloud.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
| `onCreateCommand` 🏷️ | string, array, object | This command is the first of three (along with `updateContentCommand` and `postCreateCommand`) that finalizes container setup when a dev container is created. It and subsequent commands execute **inside** the container immediately after it has started for the first time.
Cloud services can use this command when caching or prebuilding a container. This means that it will not typically have access to user-scoped assets or secrets.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
| `updateContentCommand` 🏷️ | string, array, object | This command is the second of three that finalizes container setup when a dev container is created. It executes inside the container after `onCreateCommand` whenever new content is available in the source tree during the creation process.
It will execute at least once, but cloud services will also periodically execute the command to refresh cached or prebuilt containers. Like cloud services using `onCreateCommand`, it can only take advantage of repository and org scoped secrets or permissions.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
| `postCreateCommand` 🏷️ | string, array, object | This command is the last of three that finalizes container setup when a dev container is created. It happens after `updateContentCommand` and once the dev container has been assigned to a user for the first time.
Cloud services can use this command to take advantage of user specific secrets and permissions.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
| `postStartCommand` 🏷️ | string, array, object | A command to run each time the container is successfully started.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
| `postAttachCommand` 🏷️ | string, array, object | A command to run each time a tool has successfully attached to the container.
Note that the array syntax will execute the command without a shell. You can [learn more](#formatting-string-vs-array-properties) about formatting string vs array vs object properties. |
| `waitFor` 🏷️ | enum | An enum that specifies the command any tool should wait for before connecting. Defaults to `updateContentCommand`. This allows you to use `onCreateCommand` or `updateContentCommand` for steps that must happen before `devcontainer.json` supporting tools connect while still using `postCreateCommand` for steps that can happen behind the scenes afterwards. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
For each command property, if the value is a single string, it will be run in `/bin/sh`. Use `&&` in a string to execute multiple commands. For example, `"yarn install"` or `"apt-get update && apt-get install -y curl"`. The array syntax `["yarn", "install"]` will invoke the command (in this case `yarn`) directly without using a shell. Each fires after your source code has been mounted, so you can also run shell scripts from your source tree. For example: `bash scripts/install-dev-tools.sh`.
@@ -98,7 +99,8 @@ While `devcontainer.json` does not focus on hardware or VM provisioning, it can
| `hostRequirements.cpus` 🏷️ | integer | Indicates the minimum required number of CPUs / virtual CPUs / cores. For example: `"hostRequirements": {"cpus": 2}` |
| `hostRequirements.memory` 🏷️ | string | A string indicating minimum memory requirements with a `tb`, `gb`, `mb`, or `kb` suffix. For example, `"hostRequirements": {"memory": "4gb"}` |
| `hostRequirements.storage` 🏷️ | string | A string indicating minimum storage requirements with a `tb`, `gb`, `mb`, or `kb` suffix. For example, `"hostRequirements": {"storage": "32gb"}` |
-{: .table .table-bordered .table-responsive}
+| `hostRequirements.gpu` 🏷️ | boolean, string, object | Indicates if any GPU is required. A boolean indicates if a GPU is required or not. The string `"optional"` indicates that a GPU is used when available, but is not required.
The object syntax specifies how much GPU resources are required. The `cores` property indicates the minimum number of cores and the `memory` property indicates minimum storage requirements with a `tb`, `gb`, `mb`, or `kb` suffix. For example, `"gpu": { "cores": 1000, "storage": "32gb" }` |
+ {: .table .table-bordered}
## Port attributes
@@ -108,10 +110,10 @@ The `portsAttributes` and `otherPortsAttributes` properties allow you to map def
|:------------------|:------------|:------------|
| `label` 🏷️ | string | Display name for the port in the ports view. Defaults to not set. |
| `protocol` 🏷️ | enum | Controls protocol handling for forwarded ports. When not set, the port is assumed to be a raw TCP stream which, if forwarded to `localhost`, supports any number of protocols. However, if the port is forwarded to a web URL (e.g. from a cloud service on the web), only HTTP ports in the container are supported. Setting this property to `https` alters handling by ignoring any SSL/TLS certificates present when communicating on the port and using the correct certificate for the forwarded URL instead (e.g `https://*.githubpreview.dev`). If set to `http`, processing is the same as if the protocol is not set. Defaults to not set. |
-| `onAutoForward` 🏷️ | enum | Controls what should happen when a port is auto-forwarded once you've connected to the container. `notify` is the default, and a notification will appear when the port is auto-forwarded. If set to `openBrowser`, the port will be opened in the system's default browser. `openPreview` will open the URL in `devcontainer.json` supporting services' / tools' embedded preview browser. A value of `silent` will forward the port, but take no further action. A value of `ignore` means that this port should not be auto-forwarded at all. |
+| `onAutoForward` 🏷️ | enum | Controls what should happen when a port is auto-forwarded once you've connected to the container. `notify` is the default, and a notification will appear when the port is auto-forwarded. If set to `openBrowser`, the port will be opened in the system's default browser. A value of `openBrowserOnce` will open the browser only once. `openPreview` will open the URL in `devcontainer.json` supporting services' / tools' embedded preview browser. A value of `silent` will forward the port, but take no further action. A value of `ignore` means that this port should not be auto-forwarded at all. |
| `requireLocalPort` 🏷️ | boolean | Dictates when port forwarding is required to map the port in the container to the same port locally or not. If set to `false`, the `devcontainer.json` supporting services / tools will attempt to use the specified port forward to `localhost`, and silently map to a different one if it is unavailable. If set to `true`, you will be notified if it is not possible to use the same port. Defaults to `false`. |
| `elevateIfNeeded` 🏷️ | boolean | Forwarding low ports like 22, 80, or 443 to `localhost` on the same port from `devcontainer.json` supporting services / tools may require elevated permissions on certain operating systems. Setting this property to `true` will automatically try to elevate the `devcontainer.json` supporting tool's permissions in this situation. Defaults to `false`. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
## Formatting string vs. array properties
@@ -161,21 +163,27 @@ Finally, you may use an object format:
Variables can be referenced in certain string values in `devcontainer.json` in the following format: **${variableName}**. The following is a list of available variables you can use.
-| Property | Type | Description |
+| Variable | Properties | Description |
|:------------------|:------------|:------------|
-| `${localEnv:VARIABLE_NAME}` | Any | Value of an environment variable on the **host machine** (in this case, called `VARIABLE_NAME`). Unset variables are left blank. For example, this would set a variable to your local home folder on Linux / macOS or the user folder on Windows: `"remoteEnv": { "LOCAL_USER_PATH": "${localEnv:HOME}${localEnv:USERPROFILE}" }`
A default value for when the environment variable is not set can be given with `${localEnv:VARIABLE_NAME:default_value}`.
⚠️ For a cloud service, the host is in the cloud rather than your local machine. |
+| `${localEnv:VARIABLE_NAME}` | Any | Value of an environment variable on the **host machine** (in the examples below, called `VARIABLE_NAME`). Unset variables are left blank.
⚠️ Clients (like VS Code) may need to be **restarted** to pick up newly set variables.
⚠️ For a cloud service, the host is in the cloud rather than your local machine.
**Examples**
**1.** Set a variable containing your local home folder on Linux / macOS or the user folder on Windows: `"remoteEnv": { "LOCAL_USER_PATH": "${localEnv:HOME}${localEnv:USERPROFILE}" }`.
A default value for when the environment variable is not set can be given with `${localEnv:VARIABLE_NAME:default_value}`.
**2.** In modern versions of macOS, default configurations allow setting local variables with the command `echo 'export VARIABLE_NAME=my-value' >> ~/.zshenv`. |
| `${containerEnv:VARIABLE_NAME}` | `remoteEnv` | Value of an existing environment variable inside the container once it is up and running (in this case, called `VARIABLE_NAME`). For example: `"remoteEnv": { "PATH": "${containerEnv:PATH}:/some/other/path" }`
A default value for when the environment variable is not set can be given with `${containerEnv:VARIABLE_NAME:default_value}`. |
| `${localWorkspaceFolder}` | Any | Path of the local folder that was opened in the `devcontainer.json` supporting service / tool (that contains `.devcontainer/devcontainer.json`). |
| `${containerWorkspaceFolder}` | Any | The path that the workspaces files can be found in the container. |
| `${localWorkspaceFolderBasename}` | Any | Name of the local folder that was opened in the `devcontainer.json` supporting service / tool (that contains `.devcontainer/devcontainer.json`). |
| `${containerWorkspaceFolderBasename}` | Any | Name of the folder where the workspace files can be found in the container. |
-| `${devcontainerId}` | Any | Identifier derived from a set of container labels that uniquely idenity the dev container on a Docker host. It allows Features to refer to an identifier that is unique to the dev container they are installed into and that is stable across rebuilds. The properties supporting it in devcontainer.json are: `name`, `runArgs`, `initializeCommand`, `onCreateCommand`, `updateContentCommand`, `postCreateCommand`, `postStartCommand`, `postAttachCommand`, `workspaceFolder`, `workspaceMount`, `mounts`, `containerEnv`, `remoteEnv`, `containerUser`, `remoteUser`, and `customizations`. |
-{: .table .table-bordered .table-responsive}
+| `${devcontainerId}` | Any | Allow Features to refer to an identifier that is unique to the dev container they are installed into and that is stable across rebuilds. The properties supporting it in devcontainer.json are: `name`, `runArgs`, `initializeCommand`, `onCreateCommand`, `updateContentCommand`, `postCreateCommand`, `postStartCommand`, `postAttachCommand`, `workspaceFolder`, `workspaceMount`, `mounts`, `containerEnv`, `remoteEnv`, `containerUser`, `remoteUser`, and `customizations`. |
+{: .table .table-bordered}
-## Schema
+## Schema
-You can see the VS Code implementation of the dev container schema [here](https://github.com/microsoft/vscode/blob/main/extensions/configuration-editing/schemas/devContainer.schema.src.json).
+You can see the dev container schema [here](https://github.com/devcontainers/spec/blob/main/schemas/devContainer.base.schema.json).
## Publishing vs forwarding ports
Docker has the concept of "publishing" ports when the container is created. Published ports behave very much like ports you make available to your local network. If your application only accepts calls from `localhost`, it will reject connections from published ports just as your local machine would for network calls. Forwarded ports, on the other hand, actually look like `localhost` to the application.
+
+## remoteUser
+
+A dev container configuration will inherit the `remoteUser` property from the base image it uses.
+
+Using the [images](https://github.com/devcontainers/images) and [Templates](https://github.com/devcontainers/templates) part of the spec as an example: `remoteUser` in these images is set to a custom value - you may view an example in the [C++ image](https://github.com/devcontainers/images/blob/main/src/cpp/.devcontainer/devcontainer.json#L26). The [C++ Template](https://github.com/devcontainers/templates/tree/main/src/cpp) will then inherit the custom `remoteUser` value from [its base C++ image](https://github.com/devcontainers/templates/blob/main/src/cpp/.devcontainer/Dockerfile#L1).
diff --git a/_implementors/json_schema.md b/_implementors/json_schema.md
index 7a3ca0c9..6f733bfc 100644
--- a/_implementors/json_schema.md
+++ b/_implementors/json_schema.md
@@ -31,6 +31,13 @@ You may review the current devcontainer.json schemas in the spec repo, which inc
"description": "Features to add to the dev container.",
"additionalProperties": true
},
+ "overrideFeatureInstallOrder": {
+ "type": "array",
+ "description": "Array consisting of the Feature id (without the semantic version) of Features in the order the user wants them to be installed.",
+ "items": {
+ "type": "string"
+ }
+ },
"forwardPorts": {
"type": "array",
"description": "Ports that are forwarded from the container to the local machine. Can be an integer port number, or a string of the format \"host:port_number\".",
@@ -198,7 +205,8 @@ You may review the current devcontainer.json schemas in the spec repo, which inc
"string",
"array"
],
- "description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
+ "description": "A command string or list of command arguments to run on the host machine during initialization, including during container creation and on subsequent starts. The command may run more than once during a given session. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
+
"items": {
"type": "string"
}
@@ -206,51 +214,101 @@ You may review the current devcontainer.json schemas in the spec repo, which inc
"onCreateCommand": {
"type": [
"string",
- "array"
+ "array",
+ "object"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
+ },
+ "additionalProperties": {
+ "type": [
+ "string",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
}
},
"updateContentCommand": {
"type": [
"string",
- "array"
+ "array",
+ "object"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
+ },
+ "additionalProperties": {
+ "type": [
+ "string",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
}
},
"postCreateCommand": {
"type": [
"string",
- "array"
+ "array",
+ "object"
],
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
+ },
+ "additionalProperties": {
+ "type": [
+ "string",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
}
},
"postStartCommand": {
"type": [
"string",
- "array"
+ "array",
+ "object"
],
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
+ },
+ "additionalProperties": {
+ "type": [
+ "string",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
}
},
"postAttachCommand": {
"type": [
"string",
- "array"
+ "array",
+ "object"
],
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
+ },
+ "additionalProperties": {
+ "type": [
+ "string",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
}
},
"waitFor": {
@@ -295,6 +353,39 @@ You may review the current devcontainer.json schemas in the spec repo, which inc
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
+ },
+ "gpu": {
+ "oneOf": [
+ {
+ "type": [
+ "boolean",
+ "string"
+ ],
+ "enum": [
+ true,
+ false,
+ "optional"
+ ],
+ "description": "Indicates whether a GPU is required. The string \"optional\" indicates that a GPU is optional. An object value can be used to configure more detailed requirements."
+ },
+ {
+ "type": "object",
+ "properties": {
+ "cores": {
+ "type": "integer",
+ "minimum": 1,
+ "description": "Number of required cores."
+ },
+ "memory": {
+ "type": "string",
+ "pattern": "^\\d+([tgmk]b)?$",
+ "description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
+ }
+ },
+ "description": "Indicates whether a GPU is required. The string \"optional\" indicates that a GPU is optional. An object value can be used to configure more detailed requirements.",
+ "additionalProperties": false
+ }
+ ]
}
}
}
diff --git a/_implementors/reference.md b/_implementors/reference.md
index 0544432a..6d75dd56 100644
--- a/_implementors/reference.md
+++ b/_implementors/reference.md
@@ -6,18 +6,18 @@ author: Microsoft
index: 2
---
-The reference implementation for the specification is available through a [development container CLI](https://github.com/devcontainers/cli). This CLI can take a devcontainer.json and create and configure a dev container from it.
+The reference implementation for the specification is available through a [development container CLI](https://github.com/devcontainers/cli). This CLI can take a `devcontainer.json` and create and configure a dev container from it.
-## What is the dev container CLI?
-When tools like VS Code and Codespaces detect a devcontainer.json file in a user's project, they use a CLI to configure a dev container. We've now opened up this CLI as a reference implementation so that individual users and other tools can read in devcontainer.json metadata and create dev containers from it.
+## What is the Dev Container CLI?
+When tools like VS Code and Codespaces detect a `devcontainer.json` file in a user's project, they use a CLI to configure a dev container. We've now opened up this CLI as a reference implementation so that individual users and other tools can read in `devcontainer.json` metadata and create dev containers from it.
This CLI can either be used directly or integrated into product experiences, similar to how it's integrated with Dev Containers and Codespaces today. It currently supports both a simple single container option and integrates with [Docker Compose](https://docs.docker.com/compose/) for multi-container scenarios.
-The CLI is available for review in a new [devcontainers/cli](https://github.com/devcontainers/cli) repository, and you can read more about its development in [this issue](https://github.com/devcontainers/spec/issues/9) in the spec repo.
+The CLI is available in the [devcontainers/cli](https://github.com/devcontainers/cli) repository.
## How can I try it?
-We'd love for you to try out the dev container CLI and let us know what you think. You can quickly try it out in just a few simple steps, either by installing its npm package or building the CLI repo from sources.
+We'd love for you to try out the Dev Container CLI and let us know what you think. You can quickly try it out in just a few simple steps, either by installing its npm package or building the CLI repo from sources.
You may learn more about building from sources in the [CLI repo's README](https://github.com/devcontainers/cli#try-it-out). On this page, we'll focus on using the npm package.
@@ -39,6 +39,8 @@ Commands:
devcontainer build [path] Build a dev container image
devcontainer run-user-commands Run user commands
devcontainer read-configuration Read configuration
+ devcontainer features Features commands
+ devcontainer templates Templates commands
devcontainer exec [args..] Execute a command on a running dev container
Options:
@@ -95,29 +97,28 @@ Hello, VS Code Remote - Containers!
{"outcome":"success"}
```
-Congrats, you've just run the dev container CLI and seen it in action!
+Congrats, you've just run the Dev Container CLI and seen it in action!
These steps are also provided in the CLI repo's [README](https://github.com/devcontainers/cli/blob/main/README.md). You may also review frequently asked questions [here](https://github.com/devcontainers/spec/issues/31).
### Prebuilding
We recommend pre-building images with the tools you need rather than creating and building a container image each time you open your project in a dev container. Using pre-built images will result in a faster container startup, simpler configuration, and allows you to pin to a specific version of tools to improve supply-chain security and avoid potential breaks. You can automate pre-building your image by scheduling the build using a DevOps or continuous integration (CI) service like GitHub Actions.
-We recommend using the dev container CLI to pre-build your images. Once you've built your image, you can push it to a container registry (like the [Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-docker-cli?tabs=azure-cli), [GitHub Container Registry](https://docs.github.com/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images), or [Docker Hub](https://docs.docker.com/engine/reference/commandline/push)) and reference it directly.
+We recommend using the [Dev Container CLI](#npm-install) (or other spec supporting utilities like the [GitHub Action](https://github.com/marketplace/actions/devcontainers-ci) or [Azure DevOps task](https://marketplace.visualstudio.com/items?itemName=devcontainers.ci)) to pre-build your images. Once you've built your image, you can push it to a container registry (like the [Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-docker-cli?tabs=azure-cli), [GitHub Container Registry](https://docs.github.com/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images), or [Docker Hub](https://docs.docker.com/engine/reference/commandline/push)) and reference it directly.
-#### Metadata in image labels
-
-You can include dev container configuration and Feature metadata in prebuilt images via [image labels](https://docs.docker.com/config/labels-custom-metadata/), such that, the image and the built-in Features can be used with a devcontainer.json (image-, Dockerfile- or Docker Compose-based) that does not repeat the dev container config or Feature metadata. Other tools should be able to record the same metadata without necessarily using Features themselves.
+```bash
+devcontainer build --workspace-folder . --push true --image-name :
+```
-The metadata label is **automatically added** when you pre-build using the Dev Container CLI (or most Dev Container spec supporting tools) and includes settings from devcontainer.json and any referenced Dev Container Features.
+You can also check out our [in-depth guide on prebuilds](/_posts/2023-08-22-prebuild.md).
-However, if you are using something else to build your images, you can opt to manually add properties to an image label instead. For example, consider this Dockerfile snippet:
+#### Metadata in image labels
-```Dockerfile
-LABEL devcontainer.metadata='[{ "capAdd": [ "SYS_PTRACE" ], "remoteUser": "devcontainer", "postCreateCommand": "yarn install" }]'
+You can include Dev Container configuration and Feature metadata in prebuilt images via [image labels](https://docs.docker.com/config/labels-custom-metadata/). This makes the image self-contained since these settings are automatically picked up when the image is referenced - whether directly, in a `FROM` in a referenced Dockerfile, or in a Docker Compose file. This helps prevent your Dev Container config and image contents from getting out of sync, and allows you to push updates of the same configuration to multiple repositories through a simple image reference.
-```
+This metadata label is **automatically added** when you pre-build using the [Dev Container CLI](#npm-install) (or other spec supporting utilities like the [GitHub Action](https://github.com/marketplace/actions/devcontainers-ci) or [Azure DevOps task](https://marketplace.visualstudio.com/items?itemName=devcontainers.ci)) and includes settings from `devcontainer.json` and any referenced Dev Container Features.
-In either case, the result will be merged with any local devcontainer.json content at the time you create the container (see the [the spec](https://github.com/devcontainers/spec/blob/main/proposals/image-metadata.md) for info on merge logic). But at its simplest, you can just reference the image directly in devcontainer.json for the settings to take effect:
+This allows you to have a separate **more complex** `devcontainer.json` you use to pre-build your image, and then a dramatically **simplified one** in one or more repositories. The contents of the image will be merged with this simplified devcontainer.json content at the time you create the container (see the [the spec](/implementors/spec/#merge-logic) for info on merge logic). But at its simplest, you can just reference the image directly in `devcontainer.json` for the settings to take effect:
```json
{
@@ -125,4 +126,21 @@ In either case, the result will be merged with any local devcontainer.json conte
}
```
-See [Dev Container metadata reference](../json_reference) for information on which properties are supported.
+Note that you can also opt to manually add metadata to an image label instead. These properties will be picked up even if you didn't use the Dev Container CLI to build (and can be updated by the CLI even if you do). For example, consider this Dockerfile snippet:
+
+```Dockerfile
+LABEL devcontainer.metadata='[{ \
+ "capAdd": [ "SYS_PTRACE" ], \
+ "remoteUser": "devcontainer", \
+ "postCreateCommand": "yarn install" \
+}]'
+```
+
+See the [Dev Container metadata reference](../json_reference) for information on which properties are supported.
+
+### Domain Names
+
+If you are behind a firewall that needs to allow specific domains used by the Dev Container CLI, here's the list of hostnames you should allow communication to go through:
+
+* `containers.dev` - The [homepage](https://containers.dev/) for everything about dev containers. It includes all official and community-supported [Features](https://containers.dev/features) and [Templates](https://containers.dev/templates).
+* `ghcr.io`, `*.azurecr.io`, `mcr.microsoft.com` - [OCI registries](https://containers.dev/implementors/features-distribution/#oci-registry) like [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry), [Azure Container Registry](https://azure.microsoft.com/en-us/products/container-registry), and [Microsoft Container Registry](https://mcr.microsoft.com/en-us/catalog?search=dev%20container) serves as the primary distribution mechanism for dev container resources.
\ No newline at end of file
diff --git a/_implementors/spec.md b/_implementors/spec.md
index d27cc70e..ecd0600b 100644
--- a/_implementors/spec.md
+++ b/_implementors/spec.md
@@ -6,27 +6,27 @@ author: Microsoft
index: 1
---
-The purpose of the **development container** specification is to provide a way to enrich containers with the content and metadata necessary to enable development inside them. These container **environments** should be easy to use, create, and recreate.
+The purpose of the **Development Container Specification** is to provide a way to enrich containers with the content and metadata necessary to enable development inside them. These container **environments** should be easy to use, create, and recreate.
-A **development container** is a container in which a user can develop an application. Tools that want to implement this specification should provide a set of features/commands that give more flexibility to users and allow **development containers** to scale to large development groups.
+A **development container** is a container in which a user can develop an application. Tools that want to implement this specification should provide a set of features/commands that give more flexibility to users and allow **development containers** to scale to large development groups.
An **environment** is defined as a logical instance of one or more **development containers**, along with any needed side-car containers. An environment is based on one set of metadata that can be managed as a single unit. Users can create multiple **environments** from the same configuration metadata for different purposes.
# Metadata
-**Development containers** allow one to define a repeatable development environment for a user or team of developers that includes the execution environment the application needs. A development container defines an environment in which you develop your application before you are ready to deploy. While deployment and development containers may resemble one another, you may not want to include tools in a deployment image that you use during development and you may need to use different secrets or other settings.
+The Development Container Spec allows one to define a repeatable development environment for a user or team of developers that includes the execution environment the application needs. A development container defines an environment in which you develop your application before you are ready to deploy. While deployment and development containers may resemble one another, you may not want to include tools in a deployment image that you use during development and you may need to use different secrets or other settings.
Furthermore, working inside a development container can require additional **metadata** to drive tooling or service experiences than you would normally need with a production container. Providing a structured and consistent form for this metadata is a core part of this specification.
-A **development container** is composed of a definition (e.g. contained in a `devcontainer.json` file) that deterministically creates containers under the control of the user.
+A development container is composed of a definition (e.g. contained in a `devcontainer.json` file) that deterministically creates containers under the control of the user.
## `devcontainer.json`
While the structure of this metadata is critical, it is also important to call out how this data can be represented on disk where appropriate. While other representations may be added over time, metadata can be stored in a JSON with Comments file called `devcontainer.json` today. Products using it should expect to find a devcontainer.json file in one or more of the following locations (in order of precedence):
-- .devcontainer/devcontainer.json
-- .devcontainer.json
-- .devcontainer/**/devcontainer.json (where ** is a sub-folder)
+- `.devcontainer/devcontainer.json`
+- `.devcontainer.json`
+- `.devcontainer//devcontainer.json` (where `` is a sub-folder, one level deep)
It is valid that these files may exist in more than one location, so consider providing a mechanism for users to select one when appropriate.
@@ -34,8 +34,7 @@ It is valid that these files may exist in more than one location, so consider pr
Certain dev container metadata properties can be stored in an image label as an array of metadata snippets. This allows them to be stored in prebuilt images, such that, the image and its related configuration are self-contained. These contents should then be merged with any local devcontainer.json file contents at the time the container is created. An array is used so subsequent image builds can simply append changes to the array rather than attempting to merge at that point - which improves compatibility with arbitrary image build systems.
-Metadata should be representative of with the following structure, using one entry per [Dev Container Feature](../features) and devcontainer.json (see table below for the full list):
-
+Metadata should be representative of with the following structure, using one entry per [Dev Container Feature](../features) and `devcontainer.json` (see table below for the full list):
```json
[
@@ -62,45 +61,45 @@ The metadata is added to the image as a `devcontainer.metadata` label with a JSO
### Merge Logic
-To apply the metadata together with a user's devcontainer.json at runtime the following merge logic by property is used. The table also notes which properties are currently supported coming from the devcontainer.json and which from the feature metadata, this will change over time as we add more properties.
+To apply the metadata together with a user's `devcontainer.json` at runtime, the following merge logic by property is used. The table also notes which properties are currently supported coming from the `devcontainer.json` and from the Feature metadata- this will change over time as we add more properties.
-| Property | Type/Format | Merge Logic | devcontainer.json | Feature Metadata |
+| Property | Type/Format | Merge Logic | devcontainer.json | devcontainer-feature.json |
| -------- | ----------- | ----------- | :---------------: | :--------------: |
-| `id` | E.g., `ghcr.io/devcontainers/features/node:1` | Not merged. | | x |
-| `init` | `boolean` | `true` if at least one is `true`, `false` otherwise. | x | x |
-| `privileged` | `boolean` | `true` if at least one is `true`, `false` otherwise. | x | x |
-| `capAdd` | `string[]` | Union of all `capAdd` arrays without duplicates. | x | x |
-| `securityOpt` | `string[]` | Union of all `securityOpt` arrays without duplicates. | x | x |
-| `entrypoint` | `string` | Collected list of all entrypoints. | | x |
-| `mounts` | `(string \| { type, src, dst })[]` | Collected list of all mountpoints. Conflicts: Last source wins. | x | x |
-| `onCreateCommand` | `string \| string[]` | Collected list of all onCreateCommands. | x | |
-| `updateContentCommand` | `string \| string[]` | Collected list of all updateContentCommands. | x | |
-| `postCreateCommand` | `string \| string[]` | Collected list of all postCreateCommands. | x | |
-| `postStartCommand` | `string \| string[]` | Collected list of all postStartCommands. | x | |
-| `postAttachCommand` | `string \| string[]` | Collected list of all postAttachCommands. | x | |
-| `waitFor` | enum | Last value wins. | x | |
-| `customizations` | Object of tool-specific customizations. | Merging is left to the tools. | x | x |
-| `containerUser` | `string` | Last value wins. | x | |
-| `remoteUser` | `string` | Last value wins. | x | |
-| `userEnvProbe` | `string` (enum) | Last value wins. | x | |
-| `remoteEnv` | Object of strings. | Per variable, last value wins. | x | |
-| `containerEnv` | Object of strings. | Per variable, last value wins. | x | |
-| `overrideCommand` | `boolean` | Last value wins. | x | |
-| `portsAttributes` | Map of ports to attributes. | Per port (not per port attribute), last value wins. | x | |
-| `otherPortsAttributes` | Port attributes. | Last value wins (not per port attribute). | x | |
-| `forwardPorts` | `(number \| string)[]` | Union of all ports without duplicates. Last one wins (when mapping changes). | x | |
-| `shutdownAction` | `string` (enum) | Last value wins. | x | |
-| `updateRemoteUserUID` | `boolean` | Last value wins. | x | |
-| `hostRequirements` | `cpus`, `memory`, `storage` | Max value wins. | x | |
-{: .table .table-bordered .table-responsive}
-
-Variables in string values will be substituted at the time the value is applied. When the order matters, the devcontainer.json is considered last.
+| `id` | E.g., `ghcr.io/devcontainers/features/node:1` | Not merged. | | âś“ |
+| `init` | `boolean` | `true` if at least one is `true`, `false` otherwise. | âś“ | âś“ |
+| `privileged` | `boolean` | `true` if at least one is `true`, `false` otherwise. | âś“ | âś“ |
+| `capAdd` | `string[]` | Union of all `capAdd` arrays without duplicates. | âś“ | âś“ |
+| `securityOpt` | `string[]` | Union of all `securityOpt` arrays without duplicates. | âś“ | âś“ |
+| `entrypoint` | `string` | Collected list of all entrypoints. | | âś“ |
+| `mounts` | `(string \| { type, src, dst })[]` | Collected list of all mountpoints. Conflicts: Last source wins. | âś“ | âś“ |
+| `onCreateCommand` | `string \| string[] \| {[key: string]: string \| string[]}` | Collected list of all onCreateCommands. | âś“ | âś“ |
+| `updateContentCommand` | `string \| string[] \| {[key: string]: string \| string[]}` | Collected list of all updateContentCommands. | âś“ | âś“ |
+| `postCreateCommand` | `string \| string[] \| {[key: string]: string \| string[]}` | Collected list of all postCreateCommands. | âś“ | âś“ |
+| `postStartCommand` | `string \| string[] \| {[key: string]: string \| string[]}` | Collected list of all postStartCommands. | âś“ | âś“ |
+| `postAttachCommand` | `string \| string[] \| {[key: string]: string \| string[]}` | Collected list of all postAttachCommands. | âś“ | âś“ |
+| `waitFor` | enum | Last value wins. | âś“ | |
+| `customizations` | Object of tool-specific customizations. | Merging is left to the tools. | âś“ | âś“ |
+| `containerUser` | `string` | Last value wins. | âś“ | |
+| `remoteUser` | `string` | Last value wins. | âś“ | |
+| `userEnvProbe` | `string` (enum) | Last value wins. | âś“ | |
+| `remoteEnv` | Object of strings. | Per variable, last value wins. | âś“ | |
+| `containerEnv` | Object of strings. | Per variable, last value wins. | âś“ | |
+| `overrideCommand` | `boolean` | Last value wins. | âś“ | |
+| `portsAttributes` | Map of ports to attributes. | Per port (not per port attribute), last value wins. | âś“ | |
+| `otherPortsAttributes` | Port attributes. | Last value wins (not per port attribute). | âś“ | |
+| `forwardPorts` | `(number \| string)[]` | Union of all ports without duplicates. Last one wins (when mapping changes). | âś“ | |
+| `shutdownAction` | `string` (enum) | Last value wins. | âś“ | |
+| `updateRemoteUserUID` | `boolean` | Last value wins. | âś“ | |
+| `hostRequirements` | `cpus`, `memory`, `storage`, `gpu` | Max value wins. | âś“ | |
+{: .table .table-bordered}
+
+Variables in string values will be substituted at the time the value is applied. When the order matters, the `devcontainer.json` is considered last.
### Notes
- Passing the label as a `LABEL` instruction in the Dockerfile:
- The size limit on Dockerfiles is around 1.3MB. The line length is limited to 65k characters.
- - Using one line per feature should allow for making full use of these limits.
+ - Using one line per Feature should allow for making full use of these limits.
- Passing the label as a command line argument:
- There is no size limit documented for labels, but the daemon returns an error when the request header is >500kb.
- The 500kb limit is shared, so we cannot use a second label in the same build to avoid it.
@@ -118,7 +117,7 @@ Image based configurations only reference an image that should be reachable and
## Dockerfile based
-These configurations are defined as using a `Dockerfile` to define the starting point of the **development containers**. As with image based configurations, it is assumed that any base images are already reachable by **Docker** when performing a `docker build` command. The only required parameter in this case is the relative reference to the `Dockerfile` in `build.dockerfile`. The details are [here](../json_reference#image-specific).
+These configurations are defined as using a Dockerfile to define the starting point of the development containers. As with image based configurations, it is assumed that any base images are already reachable by Docker when performing a `docker build` command. The only required parameter in this case is the relative reference to the Dockerfile in `build.dockerfile`. The details are [here](../json_reference#image-specific).
There are multiple properties that allow users to control how `docker build` works:
@@ -135,11 +134,11 @@ Docker Compose configurations use `docker-compose` (which may be Docker Compose
- `service`: declares the **main** container that will be used for all other operations. Tools are assumed to also use this parameter to connect to the **development container**, although they can provide facilities to connect to the other containers as required by the user.
- `runServices`: an optional property that indicates the set of services in the `docker-compose` configuration that should be started or stopped with the environment.
-It is important to note that **image** and **dockerfile** properties are not needed since Docker Compose supports them natively in the format.
+It is important to note that the `image` and `dockerfile` properties are not needed since Docker Compose supports them natively in the format.
# Other options
-In addition to the configuration options explained above, there are other settings that apply when creating **development containers** to facilitate their use by developers.
+In addition to the configuration options explained above, there are other settings that apply when creating development containers to facilitate their use by developers.
A complete list of available metadata properties and their purposes can be found in the [`devcontainer.json` reference](https://aka.ms/devcontainer.json). However, we will describe the critical ones below in more detail.
@@ -147,28 +146,28 @@ A complete list of available metadata properties and their purposes can be found
Development container "Features" are self-contained, shareable units of installation code and development container configuration. The name comes from the idea that referencing one of them allows you to quickly and easily add more tooling, runtime, or library "features" into your development container for you or your collaborators to use.
-They are applied to container images as a secondary build step and can affect a number of dev container configuration settings. See the [features documentation](./features.md) for more details.
+They are applied to container images as a secondary build step and can affect a number of dev container configuration settings. See the [Features documentation](../features) for more details.
## Environment variables
-Environment variables can be set at different points in the dev container lifecycle. With this in mind, **development containers** support two classes of environment variables:
+Environment variables can be set at different points in the dev container lifecycle. With this in mind, development containers support two classes of environment variables:
* **Container**: These variables are part of the container when it is created and are available at all points in its lifecycle. This concept is native to containers and can be set in the container image itself, using `containerEnv` for **image** and **Dockerfile** scenarios or using orchestrator specific properties like `env` in **Docker Compose** files.
-* **Remote**: These variables should be set by a **development container** supporting tool as part of configuring its runtime environment. Users can set these using the `remoteEnv` property and implementing tools or services may add their own for specific scenarios (e.g., secrets). These variables can change during the lifetime of the container, and are added after the container's `ENTRYPOINT` has fired.
+* **Remote**: These variables should be set by a development container supporting tool as part of configuring its runtime environment. Users can set these using the `remoteEnv` property and implementing tools or services may add their own for specific scenarios (e.g., secrets). These variables can change during the lifetime of the container, and are added after the container's `ENTRYPOINT` has fired.
The reason for this separation is it allows for the use of information not available at image build time and simplifies updating the environment for project/repository specific needs without modifying an image. With this in in mind, it's important to note that implementing tools should also support the [dynamic variable syntax](../json_reference/#variables-in-devcontainerjson) described in the metadata reference document.
-Another notable and important environment variable related property is **`userEnvProbe`**. Implementing tools should use this property to "probe" for expected environment variables using the specified type of shell. However, it does not specify that this type of shell needs to be used for all sub-processes (given the performance impact). Instead, "probed" environment variables should be merged with Remote environment variables for any processes the implementer injects after the container is created. This allows implementors to emulate developer expected behaviors around values added to their profile and rc files.
+Another notable and important environment variable related property is **`userEnvProbe`**. Implementing tools should use this property to "probe" for expected environment variables using the specified type of shell. However, it does not specify that this type of shell needs to be used for all sub-processes (given the performance impact). Instead, "probed" environment variables should be merged with remote environment variables for any processes the implementer injects after the container is created. allows implementors to emulate developer expected behaviors around values added to their profile and rc files.
## Mounts
-Mounts allow containers to have access to the underlying machine, share data between containers and to persist information between **development containers**.
+Mounts allow containers to have access to the underlying machine, share data between containers and to persist information between development containers.
A default mount should be included so that the source code is accessible from inside the container. Source code is stored outside of the container so that a developer's in-flight edits can be extracted, or a new container created in the event a container no longer starts.
## workspaceFolder and workspaceMount
-The default mount point for the source code can be set with the `workspaceMount` property for **image** and **dockerfile** scenarios or using the built in `mounts` property in **Docker Compose** files. This folder should point to the root of a repository (where the `.git` folder is found) so that source control operations work correctly inside the container.
+The default mount point for the source code can be set with the `workspaceMount` property for image and Dockerfile scenarios or using the built in `mounts` property in Docker Compose files. This folder should point to the root of a repository (where the `.git` folder is found) so that source control operations work correctly inside the container.
The `workspaceFolder` can then be set to the default folder inside the container that should used in the container. Typically this is either the mount point in the container, or a sub-folder under it. Allowing a sub-folder to be used is particularly important for monorepos given you need the `.git` folder to interact with source control but developers are typically are interacting with a specific sub-project within the overall repository.
@@ -178,10 +177,10 @@ See [`workspaceMount` and `workspaceFolder`](../json_reference#image-specific) f
Users control the permissions of applications executed in the containers, allowing the developer to control them. The specification takes into account two types of user definitions:
-* **Container User**: The user that will be used for all operations that run inside a container. This concept is native to containers. It may be set in the container image, using the `continerUser` property for **image** and **dockerfile** scenarios, or using an orchestratric specific property like `user` property in Docker Compose files.
+* **Container User**: The user that will be used for all operations that run inside a container. This concept is native to containers. It may be set in the container image, using the `containerUser` property for **image** and **dockerfile** scenarios, or using an orchestratric specific property like `user` property in Docker Compose files.
* **Remote User**: Used to run the [lifecycle](#lifecycle) scripts inside the container. This is also the user tools and editors that connect to the container should use to run their processes. This concept is not native to containers. Set using the `remoteEnv` property in all cases and defaults to the container user.
-This separation allows the ENTRYPOINT for the image to execute with different permissions than the developer and allows for developers to switch users without recreating their containers.
+This separation allows the `ENTRYPOINT` for the image to execute with different permissions than the developer and allows for developers to switch users without recreating their containers.
# Lifecycle
@@ -194,7 +193,7 @@ A development environment goes through different lifecycle events during its use
## Configuration Validation
-The exact steps required to validate configuration can vary based on exactly where the **development container** metadata is persisted. However, when considering a `devcontainer.json` file, the following validation should occur:
+The exact steps required to validate configuration can vary based on exactly where the development container metadata is persisted. However, when considering a `devcontainer.json` file, the following validation should occur:
1. Validate that a workspace source folder has been provided. It is up to the implementing tool to determine what to do if no source folder is provided.
2. Search for a `devcontainer.json` file in one of the locations [above](#devcontainerjson) in the workspace source folder.
@@ -203,7 +202,7 @@ The exact steps required to validate configuration can vary based on exactly whe
## Environment Creation
-The creation process goes through the steps necesarry to go from the user configuration to a working **environment** that is ready to be used.
+The creation process goes through the steps necessary to go from the user configuration to a working **environment** that is ready to be used.
### Initialization
@@ -213,7 +212,7 @@ During this step, the following is executed:
### Image Creation
-The first part of environment creation is generating the final image(s) that the **development containers** are going to use. This step is orchestrator dependent and can consist of just pulling a Docker image, running Docker build, or docker-compose build. Additionally, this step is useful on its own since it permits the creation of intermediate images that can be uploaded and used by other users, thus cutting down on creation time. It is encouraged that tools implementing this specification give access to a command that just executes this step.
+The first part of environment creation is generating the final image(s) that the development containers are going to use. This step is orchestrator dependent and can consist of just pulling a Docker image, running Docker build, or `docker-compose` build. Additionally, this step is useful on its own since it permits the creation of intermediate images that can be uploaded and used by other users, thus cutting down on creation time. It is encouraged that tools implementing this specification give access to a command that just executes this step.
This step executes the following tasks:
@@ -261,7 +260,7 @@ The intention of this step is to ensure all containers are stopped correctly bas
## Environment Resume
-While it is not a strict requirement to keep a **development container** after it has been stopped, this is the most common scenario.
+While it is not a strict requirement to keep a development container after it has been stopped, this is the most common scenario.
To resume the environment from a stopped state:
1. Restart all related containers.
@@ -274,7 +273,7 @@ Like during the create process, remote [environment variables](#environment-vari
Dev containers support a single command for each of its lifecycle scripts. While serial execution of multiple commands can be achieved with `;`, `&&`, etc., parallel execution deserves first-class support.
-All lifecycle scripts have been extended to support `object` types. The key of the `object` will be a unique name for the command and the value will be the `string` or `array` command. Each command must exit successfully for the stage to be considered successful.
+All lifecycle scripts have been extended to support `object` types. The key of the `object` will be a unique name for the command, and the value will be the `string` or `array` command. Each command must exit successfully for the stage to be considered successful.
Each entry in the `object` will be run in parallel during that lifecycle step.
@@ -292,4 +291,4 @@ Each entry in the `object` will be run in parallel during that lifecycle step.
# Definitions
#### Project Workspace Folder
-The **project workspace folder** is where an implementing tool should begin to search for `devcontainer.json` files. If the target project on disk is using git, the **project workspace folder** is typically the root of the git repository.
\ No newline at end of file
+The **project workspace folder** is where an implementing tool should begin to search for `devcontainer.json` files. If the target project on disk is using git, the **project workspace folder** is typically the root of the git repository.
diff --git a/_implementors/templates-distribution.md b/_implementors/templates-distribution.md
index b80e0a08..3e96eb5a 100644
--- a/_implementors/templates-distribution.md
+++ b/_implementors/templates-distribution.md
@@ -1,9 +1,9 @@
---
layout: implementors
-title: "Dev Container Templates distribution and discovery [proposal]"
+title: "Dev Container Templates distribution and discovery"
shortTitle: "Templates distribution"
author: Microsoft
-index: 10
+index: 8
---
**TL;DR Check out the [quick start repository](https://github.com/devcontainers/template-starter) to get started on distributing your own Dev Container Templates.**
@@ -19,7 +19,7 @@ Goals include:
A Template's source code is stored in a git repository.
-For ease of authorship and maintenance, [1..n] Templates can share a single git repository. This set of Templates is referred to as a "collection," and will share the same [`devcontainer-collection.json`](#devcontainer-collection.json) file and "namespace" (eg. `/`).
+For ease of authorship and maintenance, [1..n] Templates can share a single git repository. This set of Templates is referred to as a "collection," and will share the same [`devcontainer-collection.json`](#devcontainer-collection) file and "namespace" (eg. `/`).
> **Note:** Templates and [Features](/implementors/features) should be placed in different git repositories.
@@ -64,16 +64,13 @@ Tooling that handles publishing Templates will not republish Templates if that e
## Packaging
-
Templates are distributed as tarballs. The tarball contains the entire contents of the Template sub-directory, including the `devcontainer-template.json`, `.devcontainer.json` (or `.devcontainer/devcontainer.json`), and any other files in the directory.
The tarball is named `devcontainer-template-.tgz`, where `` is the Templates's `id` field.
-A reference implementation for packaging and distributing Templates is provided as a GitHub Action (https://github.com/devcontainers/action).
-
+A reference implementation for packaging and distributing Templates is provided as a [GitHub Action](https://github.com/devcontainers/action).
-
-### devcontainer-collection.json
+### devcontainer-collection.json
The `devcontainer-collection.json` is an auto-generated metadata file.
@@ -81,6 +78,7 @@ The `devcontainer-collection.json` is an auto-generated metadata file.
| :--- | :--- | :--- |
| `sourceInformation` | object | Metadata from the implementing packaging tool. |
| `templates` | array | The list of Templates that are contained in this collection.|
+{: .table .table-bordered}
Each Template's `devcontainer-template.json` metadata file is appended into the `templates` top-level array.
@@ -115,7 +113,7 @@ ARTIFACT_PATH=devcontainer-template-go.tgz
for VERSION in 1 1.2 1.2.3 latest
do
oras push ${REGISTRY}/${NAMESPACE}/${TEMPLATE}:${VERSION} \
- --manifest-config /dev/null:application/vnd.devcontainers \
+ --config /dev/null:application/vnd.devcontainers \
./${ARTIFACT_PATH}:application/vnd.devcontainers.layer.v1+tar
done
@@ -131,6 +129,67 @@ REGISTRY=ghcr.io
NAMESPACE=devcontainers/templates
oras push ${REGISTRY}/${NAMESPACE}:latest \
- --manifest-config /dev/null:application/vnd.devcontainers \
+ --config /dev/null:application/vnd.devcontainers \
./devcontainer-collection.json:application/vnd.devcontainers.collection.layer.v1+json
-```
\ No newline at end of file
+```
+
+## Guide to publishing Templates
+
+The Dev Container CLI can be used to publish [Template](https://containers.dev/implementors/templates/) artifacts to an OCI registry (that supports the [artifacts specification](https://oras.land/implementors/)).
+
+To see all the available options, run `devcontainers templates publish --help`.
+
+## Example
+
+Given a directory that is organized according to the [Templates distribution specification](https://containers.dev/implementors/templates-distribution/) - for example:
+
+```
+├── src
+│ ├── color
+│ │ ├── devcontainer-template.json
+│ │ └──| .devcontainer
+│ │ └── devcontainer.json
+│ ├── hello
+│ │ ├── devcontainer-template.json
+│ │ └──| .devcontainer
+│ │ ├── devcontainer.json
+│ │ └── Dockerfile
+| ├── ...
+│ │ ├── devcontainer-template.json
+│ │ └──| .devcontainer
+│ │ └── devcontainer.json
+├── test
+│ ├── color
+│ │ └── test.sh
+│ ├── hello
+│ │ └── test.sh
+│ └──test-utils
+│ └── test-utils.sh
+...
+```
+
+The following command will publish each Template above (`color,hello`) to the registry `ghcr.io` with the following namespace (prefix) `devcontainers/templates`.
+
+```
+[/tmp]$ GITHUB_TOKEN="$CR_PAT" devcontainer templates publish -r ghcr.io -n devcontainers/templates ./src
+```
+
+To later apply a published Template (in the example below, the `color` template) with the CLI, the following `apply` command would be used:
+
+```
+[/tmp]$ devcontainer templates apply \
+ -t 'ghcr.io/devcontainers/templates/color' \
+ -a '{"favorite": "red"}'
+```
+
+### Authentication Methods
+
+> NOTE: OS-specific docker credential helpers (Docker Desktop credential helper) are not currently recognized by the CLI.
+- Adding a $HOME/.docker/config.json with your credentials following [this commonly defined format](https://www.systutorials.com/docs/linux/man/5-docker-config-json/).
+ - Your `docker login` command may write this file for you depending on your operating system.
+- Using our custom env variable DEVCONTAINERS_OCI_AUTH
+ - eg: `DEVCONTAINERS_OCI_AUTH=service1|user1|token1,service2|user2|token2`
+
+For publishing to `ghcr.io`
+- Using the `devcontainers/action` GitHub action to handle the `GITHUB_TOKEN` credential for you.
+- Providing a GITHUB_TOKEN with permission to `write:packages`.
diff --git a/_implementors/templates.md b/_implementors/templates.md
index a8e5fdbc..8a0a519e 100644
--- a/_implementors/templates.md
+++ b/_implementors/templates.md
@@ -1,14 +1,14 @@
---
layout: implementors
-title: "Dev Container Templates reference [proposal]"
+title: "Dev Container Templates reference"
shortTitle: "Templates"
author: Microsoft
-index: 9
+index: 7
---
-Development container "Templates" are source files packaged together that encode configuration for a complete development environment. A Template can be used in a new or existing project, and a [supporting tool](/supporting) will use the configuration from the Template to build a development container.
+**Development Container Templates** are source files packaged together that encode configuration for a complete development environment. A Template can be used in a new or existing project, and a [supporting tool](/supporting) will use the configuration from the Template to build a development container.
-The configuration is placed in a [`.devcontainer.json`](/implementors/json_reference#devcontainerjson) which can also reference other files within the Template. Alternatively, `.devcontainer/devcontainer.json` can also be used if the container needs to reference other files, such as a `Dockerfile` or `docker-compose.yml`. A Template can also provide additional source files (eg: boilerplate code or a [lifecycle script](/implementors/json_reference/#lifecycle-scripts).
+The configuration is placed in a [`.devcontainer.json`](/implementors/json_reference#devcontainerjson) which can also reference other files within the Template. Alternatively, `.devcontainer/devcontainer.json` can also be used if the container needs to reference other files, such as a `Dockerfile` or `docker-compose.yml`. A Template can also provide additional source files (eg: boilerplate code or a [lifecycle script](/implementors/json_reference/#lifecycle-scripts)).
Template metadata is captured by a `devcontainer-template.json` file in the root folder of the Template.
@@ -37,10 +37,12 @@ The properties of the file are as follows:
| `description` | string | Description of the Template. |
| `documentationURL` | string | Url that points to the documentation of the Template. |
| `licenseURL` | string | Url that points to the license of the Template. |
-| `options` | object | A map of options that the supporting tools should use to populate different configuration options for the Template. |
+| [`options`](#options) | object | A map of options that the supporting tools should use to populate different configuration options for the Template. |
| `platforms` | array | Languages and platforms supported by the Template. |
| `publisher` | string | Name of the publisher/maintainer of the Template. |
| `keywords` | array | List of strings relevant to a user that would search for this Template. |
+| [`optionalPaths`](#optionalPaths) | array | An array of files or directories that tooling may consider "optional" when applying a Template. Directories are indicated with a trailing `/*`, (eg: `.github/*`).
+{: .table .table-bordered}
### The `options` property
The `options` property contains a map of option IDs and their related configuration settings. These `options` are used by the supporting tools to prompt the user to choose from different Template configuration options. The tools would replace the option ID with the selected value in all the files (within the sub-directory of the Template). This replacement would happen before dropping the `.devcontainer.json` (or `.devcontainer/devcontainer.json`) and other files (within the sub-directory of the Template) required to containerize your project. See [option resolution](#option-resolution) for more details. For example:
@@ -66,9 +68,34 @@ The `options` property contains a map of option IDs and their related configurat
| `optionId.proposals` | array | A list of suggested string values. Free-form values **are** allowed. Omit when using `optionId.enum`. |
| `optionId.enum` | array | A strict list of allowed string values. Free-form values are **not** allowed. Omit when using `optionId.proposals`. |
| `optionId.default` | string | Default value for the option. |
+{: .table .table-bordered}
> `Note`: The `options` must be unique for every `devcontainer-template.json`
+### The `optionalPaths` property
+
+Before applying a Template, tooling must inspect the `optionalPaths` property of a Template and prompt the user on whether each file or folder should be included in the resulting output workspace folder. A path is relative to the root of the Template source directory.
+
+- For a single file, provide the full relative path (without any leading or trailing path delimiters).
+- For a directory, provide the full relative path with a trailing slash and asterisk (`/*`) appended to the path. The directory and its children will be recursively ignored.
+
+Examples are shown below:
+
+```jsonc
+{
+ "id": "cpp",
+ "version": "3.0.0",
+ "name": "C++",
+ "description": "Develop C++ applications",
+ "optionalPaths": [
+ "GETTING-STARTED.md", // Single file
+ "example-project-1/MyProject.csproj", // Single file in nested directory
+ ".github/*" // Entire recursive contents of directory
+ ]
+}
+```
+
+
### Referencing a Template
The `id` format (`//[:]`) dictates how a [supporting tool](/supporting) will locate and download a given Template from an OCI registry. For example:
@@ -87,7 +114,7 @@ Tooling that handles releasing Templates will not republish Templates if that ex
## Release
-_For information on distributing Templates, see [templates-distribution](/implementors/templates-distribution)._
+_For information on distributing Templates, see the [Templates distribution doc](/implementors/templates-distribution)._
### Option Resolution
@@ -119,7 +146,7 @@ Suppose the `java` Template has the following `options` parameters declared in t
"17",
"11"
],
- "default": "17-bullseye"
+ "default": "17-bullseye"
},
"nodeVersion": {
"type": "string",
@@ -145,14 +172,14 @@ and it has the following `.devcontainer.json` file:
```json
{
- "name": "Java",
- "image": "mcr.microsoft.com/devcontainers/java:0-${templateOption:imageVariant}",
- "features": {
- "ghcr.io/devcontainers/features/node:1": {
- "version": "${templateOption:nodeVersion}",
- "installMaven": "${templateOption:installMaven}"
- }
- },
+ "name": "Java",
+ "image": "mcr.microsoft.com/devcontainers/java:0-${templateOption:imageVariant}",
+ "features": {
+ "ghcr.io/devcontainers/features/node:1": {
+ "version": "${templateOption:nodeVersion}",
+ "installMaven": "${templateOption:installMaven}"
+ }
+ },
// ...
}
```
@@ -161,7 +188,7 @@ A user tries to add the `java` Template to their project using the [supporting t
The supporting tool could then use a string replacer for all the files within the sub-directory of the Template. In this example, `.devcontainer.json` needs to be modified and hence, the inputs can provided to it as follows:
-```
+```json
{
imageVariant:"17-bullseye",
nodeVersion: "latest",
@@ -173,16 +200,16 @@ The modified `.devcontainer.json` will be as follows:
```json
{
- "name": "Go",
- "image": "mcr.microsoft.com/devcontainers/go:0-17-bullseye",
- "features": {
- "ghcr.io/devcontainers/features/node:1": {
- "version": "latest",
- "installMaven": "false"
- }
- },
- ...
+ "name": "Go",
+ "image": "mcr.microsoft.com/devcontainers/go:0-17-bullseye",
+ "features": {
+ "ghcr.io/devcontainers/features/node:1": {
+ "version": "latest",
+ "installMaven": "false"
+ }
+ },
+ ...
}
```
-The modified `.devcontainer.json` would be dropped into any existing folder as a starting point for containerizing your project.
\ No newline at end of file
+The modified `.devcontainer.json` would be dropped into any existing folder as a starting point for containerizing your project.
diff --git a/_includes/footer.html b/_includes/footer.html
index 03bf7495..26bbabac 100644
--- a/_includes/footer.html
+++ b/_includes/footer.html
@@ -28,12 +28,9 @@
{{ page.date | date_to_string }} -
+ {% assign i = 0 %}
+ {% for a in page.author %}
+ {{ page.author[i] }}
+ {% assign i = i | plus:1 %}
+ {% endfor %}
+
+
+ {{ content }}
+
diff --git a/_implementors/create-feature.md b/_posts/2022-11-01-author-a-feature.md
similarity index 63%
rename from _implementors/create-feature.md
rename to _posts/2022-11-01-author-a-feature.md
index a5882250..ab7a0139 100644
--- a/_implementors/create-feature.md
+++ b/_posts/2022-11-01-author-a-feature.md
@@ -1,28 +1,29 @@
---
-layout: implementors
-title: "Create a Feature"
-shortTitle: "Create a Feature"
-author: Microsoft
-index: 7
+layout: post
+title: "Authoring a Dev Container Feature"
+author:
+ - "@joshspicer"
+authorUrl:
+ - https://github.com/joshspicer
---
-Development container ['Features'](../features) are self-contained, shareable units of installation code and development container configuration. We [define a pattern](../features-distribution) for authoring and self-publishing Features.
+Development container ["Features"](/features) are self-contained, shareable units of installation code and development container configuration. We [define a pattern](/implementors/features-distribution) for authoring and self-publishing Features.
-In this document, we'll outline a "quickstart" to help you get up-and-running with creating and sharing your first Feature. You may review an example along with guidance in our [devcontainers/feature-template](https://github.com/devcontainers/feature-template) repo as well.
+In this document, we'll outline a "quickstart" to help you get up-and-running with creating and sharing your first Feature. You may review an example along with guidance in our [devcontainers/feature-starter](https://github.com/devcontainers/feature-starter) repo as well.
-> Note: While this walkthrough will illustrate the use of GitHub and the GitHub Container Registry, you can use your own source control system and publish to any [OCI Artifact supporting](https://oras.land/implementors/#registries-supporting-oci-artifacts) container registry instead.
+> Note: While this walkthrough will illustrate the use of GitHub and the GitHub Container Registry, you can use your own source control system and publish to any [OCI Artifact supporting](https://oras.land/docs/compatible_oci_registries#registries-supporting-oci-artifacts) container registry instead.
## Create a repo
Start off by creating a repository to host your Feature. In this guide, we'll use a public GitHub repository.
-For the simplest getting started experience, you may use our example [feature-template](https://github.com/devcontainers/feature-template) repo. You may select the green `Use this template` button on the repo's page.
+For the simplest getting started experience, you may use our example [feature-starter](https://github.com/devcontainers/feature-starter) repo. You may select the green `Use this template` button on the repo's page.
You may also [create your own repo on GitHub](https://docs.github.com/en/get-started/quickstart/create-a-repo) if you'd prefer.
## Create a folder
-Once you've forked the feature-template repo (or created your own), you'll want to create a folder for your Feature. You may create one within the [`src`](https://github.com/devcontainers/feature-template/tree/main/src) folder.
+Once you've forked the feature-starter repo (or created your own), you'll want to create a folder for your Feature. You may create one within the [`src`](https://github.com/devcontainers/feature-starter/tree/main/src) folder.
If you'd like to create multiple Features, you may add multiple folders within `src`.
@@ -30,11 +31,11 @@ If you'd like to create multiple Features, you may add multiple folders within `
At a minimum, a Feature will include a `devcontainer-feature.json` and an `install.sh` entrypoint script.
-There are many possible properties for `devcontainer-feature.json`, which you may review in the [Features spec](../features#devcontainer-feature-json-properties).
+There are many possible properties for `devcontainer-feature.json`, which you may review in the [Features spec](/features#devcontainer-feature-json-properties).
Below is a hello world example `devcontainer-feature.json` and `install.sh`. You may review the [devcontainers/features](https://github.com/devcontainers/features/blob/main/src) repo for more examples.
-[devcontainer-feature.json](https://github.com/devcontainers/feature-template/blob/main/src/hello/devcontainer-feature.json):
+[devcontainer-feature.json](https://github.com/devcontainers/feature-starter/blob/main/src/hello/devcontainer-feature.json):
```json
{
@@ -58,7 +59,7 @@ Below is a hello world example `devcontainer-feature.json` and `install.sh`. You
}
```
-[install.sh](https://github.com/devcontainers/feature-template/blob/main/src/hello/install.sh):
+[install.sh](https://github.com/devcontainers/feature-starter/blob/main/src/hello/install.sh):
```bash
#!/bin/sh
@@ -82,11 +83,11 @@ chmod +x /usr/local/bin/hello
## Publishing
-The feature-template repo contains a GitHub Action [workflow](https://github.com/devcontainers/feature-template/blob/main/.github/workflows/release.yaml) that will publish each feature to GHCR. By default, each feature will be prefixed with the `` namespace. Using the hello world example from above, it can be referenced in a `devcontainer.json` with: `ghcr.io/devcontainers/feature-template/color:1`.
+The `feature-starter` repo contains a GitHub Action [workflow](https://github.com/devcontainers/feature-starter/blob/main/.github/workflows/release.yaml) that will publish each feature to GHCR. By default, each feature will be prefixed with the `` namespace. Using the hello world example from above, it can be referenced in a `devcontainer.json` with: `ghcr.io/devcontainers/feature-starter/color:1`.
> Note: You can use the `devcontainer features publish` command from the [Dev Container CLI](https://github.com/devcontainers/cli) if you are not using GitHub Actions.
-The provided GitHub Action will also publish a third "metadata" package with just the namespace, eg: `ghcr.io/devcontainers/feature-template`, which is known as the Feature collection namespace.
+The provided GitHub Action will also publish a third "metadata" package with just the namespace, eg: `ghcr.io/devcontainers/feature-starter. This is useful for supporting tools to [crawl](#add-to-index) metadata about available Features in the collection without downloading _all the Features individually_.
By default, GHCR packages are marked as private. To stay within the free tier, Features need to be marked as public.
@@ -100,10 +101,10 @@ https://github.com/users//packages/container/%2F/setti
## Adding Features to the Index
-If you'd like your Features to appear in our [public index](https://containers.dev/features) so that other community members can find them, you can do the following:
+If you'd like your Features to appear in our [public index](/features) so that other community members can find them, you can do the following:
-* Go to [github.com/devcontainers/devcontainers.github.io](github.com/devcontainers/devcontainers.github.io), which is the GitHub repo backing [containers.dev](https://containers.dev/)
+* Go to [github.com/devcontainers/devcontainers.github.io](https://github.com/devcontainers/devcontainers.github.io), which is the GitHub repo backing [containers.dev](https://containers.dev/)
* Open a PR to modify the [collection-index.yml](https://github.com/devcontainers/devcontainers.github.io/blob/gh-pages/_data/collection-index.yml) file
* Features housed in other OCI Artifact container registries can be included as long as they can be downloaded without a login.
-Feature collections are scanned to populate a Feature index on the [containers.dev site](../../features) and allow them to appear in Dev Container creation UX in [supporting tools](https://containers.dev/supporting) like [VS Code Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) and [GitHub Codespaces](https://github.com/features/codespaces).
\ No newline at end of file
+Feature collections are scanned to populate a Feature index on the [containers.dev site](/features) and allow them to appear in Dev Container creation UX in [supporting tools](https://containers.dev/supporting) like [VS Code Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) and [GitHub Codespaces](https://github.com/features/codespaces).
diff --git a/_posts/2022-12-16-dockerfile.md b/_posts/2022-12-16-dockerfile.md
new file mode 100644
index 00000000..c0b44d68
--- /dev/null
+++ b/_posts/2022-12-16-dockerfile.md
@@ -0,0 +1,145 @@
+---
+layout: post
+title: "Using Images, Dockerfiles, and Docker Compose"
+author:
+ - "@chuxel"
+authorUrl:
+ - https://github.com/chuxel
+---
+
+When creating a development container, you have a variety of different ways to customize your environment like ["Features"](/features) or [lifecycle scripts](/implementors/json_reference/#lifecycle-scripts). However, if you are familiar with containers, you may want to use a [Dockerfile](/guide/dockerfile#dockerfile) or [Docker Compose / Compose](/guide/dockerfile#docker-compose) to customize your environment. This article will walk through how to use these formats with the Dev Container spec.
+
+## Using a Dockerfile
+
+To keep things simple, many [Dev Container Templates](/templates) use container image references.
+
+```json
+{
+ "image": "mcr.microsoft.com/devcontainers/base:ubuntu"
+}
+```
+
+However, [Dockerfiles](https://docs.docker.com/engine/reference/builder/) are a great way to extend images, add additional native OS packages, or make minor edits to the OS image. You can reuse any Dockerfile, but let's walk through how to create one from scratch.
+
+First, add a file named `Dockerfile` next to your `devcontainer.json`. For example:
+
+```Dockerfile
+FROM mcr.microsoft.com/devcontainers/base:ubuntu
+# Install the xz-utils package
+RUN apt-get update && apt-get install -y xz-utils
+```
+
+Next, remove the `image` property from `devcontainer.json` (if it exists) and add the `build` and `dockerfile` properties instead:
+
+```json
+{
+ "build": {
+ // Path is relative to the devcontainer.json file.
+ "dockerfile": "Dockerfile"
+ }
+}
+```
+
+That's it! When you start up your Dev Container, the Dockerfile will be automatically built with no additional work. See [Dockerfile scenario reference](/implementors/json_reference/#image-specific) for more information on other related devcontainer.json properties.
+
+### Iterating on an image that includes Dev Container metadata
+
+Better yet, you can can use a Dockerfile as a part of authoring an image you can share with others. You can even **add Dev Container settings and metadata right into the image itself**. This avoids having to duplicate config and settings in multiple devcontainer.json files and keeps them in sync with your images!
+
+See the guide on **[pre-building]({% post_url 2023-08-22-prebuild %})** to learn more!
+
+## Using Docker Compose
+
+[Docker Compose](https://docs.docker.com/compose/) is a great way to define a multi-container development environment. Rather than adding things like databases or redis to your Dockerfile, you can reference existing images for these services and focus your Dev Container's content on tools and utilities you need for development.
+
+### Using an image with Docker Compose
+
+As mentioned in the Dockerfile section, to keep things simple, many [Dev Container Templates](/templates) use container image references.
+
+```json
+{
+ "image": "mcr.microsoft.com/devcontainers/base:ubuntu"
+}
+```
+
+Let's create a `docker-compose.yml` file next to your `devcontainer.json` that references the same image and includes a PostgreSQL database:
+
+```yaml
+version: '3.8'
+services:
+ devcontainer:
+ image: mcr.microsoft.com/devcontainers/base:ubuntu
+ volumes:
+ - ../..:/workspaces:cached
+ network_mode: service:db
+ command: sleep infinity
+
+ db:
+ image: postgres:latest
+ restart: unless-stopped
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_USER: postgres
+ POSTGRES_DB: postgres
+
+volumes:
+ postgres-data:
+```
+
+In this example:
+- `../..:/workspaces:cached` mounts the workspace folder from the local source tree into the Dev Container.
+- `network_mode: service:db` puts the Dev Container on the same network as the database, so that it can access it on `localhost`.
+- The `db` section uses the [Postgres](https://hub.docker.com/_/postgres) image with a few settings.
+
+Next, let's configure devcontainer.json to use it.
+
+```json
+{
+ "dockerComposeFile": "docker-compose.yml",
+ "service": "devcontainer",
+ "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}"
+}
+```
+
+In this example:
+- `service` indicates which service in the `docker-compose.yml` file is the Dev Container.
+- `dockerComposeFile` indicates where to find the `docker-compose.yml` file.
+- `workspaceFolder` indicates where to mount the workspace folder. This corresponds to a sub-folder under the mount point from `../..:/workspaces:cached` in the `docker-compose.yml` file.
+
+That's it!
+
+### Using a Dockerfile with Docker Compose
+
+You can also combine these scenarios and use Dockerfile with Docker Compose. This time we'll update `docker-compose.yml` to reference the Dockerfile by replacing `image` with a similar `build` section:
+
+```yaml
+version: '3.8'
+services:
+ devcontainer:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ volumes:
+ - ../..:/workspaces:cached
+ network_mode: service:db
+ command: sleep infinity
+
+ db:
+ image: postgres:latest
+ restart: unless-stopped
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_USER: postgres
+ POSTGRES_DB: postgres
+
+volumes:
+ postgres-data:
+```
+
+Finally, as in the Dockerfile example, you can use this same setup to create a Dev Container image that you can share with others. You can also add Dev Container settings and metadata right into the image itself.
+
+See the guide on **[pre-building]({% post_url 2023-08-22-prebuild %})** to learn more!
diff --git a/_posts/2023-02-15-gitlab-ci.md b/_posts/2023-02-15-gitlab-ci.md
new file mode 100644
index 00000000..63d3b5d0
--- /dev/null
+++ b/_posts/2023-02-15-gitlab-ci.md
@@ -0,0 +1,152 @@
+---
+layout: post
+title: "Working with GitLab CI"
+author:
+ - "@raginjason"
+authorUrl:
+ - https://github.com/raginjason
+---
+
+For simple use cases you can use your development container (dev container) for CI without much issue. Once you begin using more advanced dev container functionality such as [Features](/features), you will need dev container tooling in your CI pipeline. While GitHub CI has the [devcontainers-ci GitHub Action](https://github.com/marketplace/actions/devcontainers-ci), there is no such analog in GitLab CI. To achieve the goal of using your dev container in GitLab CI, the container must be pre-built.
+
+This document will guide you on how to build a dev container with GitLab CI, push that dev container to the GitLab Container Registry, and finally reference that dev container in your main project for both local development and GitLab CI.
+
+For the purpose of this document, we will assume the main project is named `my-project` and lives under the `my-user` path. The example here uses a few [Features](/features), which is what forces the container to be pre-built.
+
+## The Development Container GitLab project
+
+Create a project in GitLab where the stand-alone dev container project will live. As the main project is assumed to be named `my-project`, let's assume the dev container project name will be `my-project-dev-container`
+
+### Development Container .devcontainer/devcontainer.json
+
+The example here is a CDK project for Python makes use of both the [AWS CLI](https://github.com/devcontainers/features/tree/main/src/aws-cli) and the community-maintained [AWS CDK](http://github.com/devcontainers-contrib/features/tree/main/src/aws-cdk) Features.
+
+`.devcontainer/devcontainer.json`:
+
+```json
+{
+ "build": {
+ "context": "..",
+ "dockerfile": "Dockerfile"
+ },
+ "features": {
+ "ghcr.io/devcontainers/features/aws-cli:1": {},
+ "ghcr.io/devcontainers-contrib/features/aws-cdk:2": {}
+ },
+ "customizations": {
+ "vscode": {
+ "settings": {
+ "python.formatting.provider": "black"
+ }
+ }
+ }
+}
+```
+
+### Development Container Dockerfile
+
+As this is a Python project working with CDK, the `Dockerfile` will begin by using the latest Python dev container image and then install some basic packages via `pip`.
+
+`Dockerfile`:
+
+```Dockerfile
+FROM mcr.microsoft.com/devcontainers/python:latest
+
+RUN pip3 --disable-pip-version-check --no-cache-dir install aws_cdk_lib constructs jsii pylint \
+ && rm -rf /tmp/pip-tmp
+```
+
+### Development Container .gitlab-ci.yml
+
+Since there is no GitLab CI equivalent to [devcontainers-ci GitHub Action](https://github.com/marketplace/actions/devcontainers-ci), we will need to install the devcontainers CLI manually. The following will:
+
+1. Install the packages that the devcontainers CLI requires
+2. Install the devcontainers CLI itself
+3. Login to GitLab Container Repository
+4. Build the dev container and push it to the GitLab Container Repository
+
+`.gitlab-ci.yml`:
+
+```yaml
+image: docker:latest
+
+variables:
+ DOCKER_TLS_CERTDIR: "/certs"
+
+services:
+ - docker:dind
+
+before_script:
+ - apk add --update nodejs npm python3 make g++
+ - npm install -g @devcontainers/cli
+
+build:
+ stage: build
+ script:
+ - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
+ - devcontainer build --workspace-folder . --push true --image-name ${CI_REGISTRY_IMAGE}:latest
+```
+
+## The Main GitLab project
+
+### Main .devcontainer/devcontainer.json
+
+`.devcontainer/devcontainer.json`:
+
+```json
+{
+ "image": "registry.gitlab.com/my-user/my-project-dev-container"
+}
+```
+
+### Main .gitlab.ci.yml
+
+Assuming the dev container project name is based off the main project name, the `${CI_REGISTRY_NAME}` variable can be used. This configuration performs some basic sanity checks and linting once merge requests are submitted.
+
+`.gitlab-ci.json`:
+
+```yaml
+image: ${CI_REGISTRY_IMAGE}-dev-container:latest
+
+before_script:
+ - python --version
+ - cdk --version
+
+stages:
+ - Build
+ - Lint
+
+py_compile:
+ stage: Build
+ script:
+ - find . -type f -name "*.py" -print | xargs -n1 python3 -m py_compile
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+
+cdk synth:
+ stage: Build
+ script:
+ - JSII_DEPRECATED=fail cdk --app "python3 app.py" synth
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+
+Pylint:
+ stage: Lint
+ script:
+ - pylint *
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+
+Black code format:
+ stage: Lint
+ script:
+ - black --check --diff .
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+```
+
+## Conclusion
+
+It's worth noting that the best practice would be to pin the versions of the various packages installed by `pip`, `apk`, `npm` and the like. Version pinning was omitted from this guide so that it can be executed as-is without issue.
+
+The above provides a starting point for a dev container that's used for both local development and in GitLab CI. It can easily be customized for other languages and tool chains. Take it and make it your own, happy coding!
\ No newline at end of file
diff --git a/_posts/2023-06-14-feature-authoring-best-practices.md b/_posts/2023-06-14-feature-authoring-best-practices.md
new file mode 100644
index 00000000..adca4d49
--- /dev/null
+++ b/_posts/2023-06-14-feature-authoring-best-practices.md
@@ -0,0 +1,162 @@
+---
+layout: post
+title: "Best Practices: Authoring a Dev Container Feature"
+author:
+ - "@joshspicer"
+authorUrl:
+ - https://github.com/joshspicer
+---
+
+Last November I wrote about the basics around [authoring a Dev Container Feature](/guide/author-a-feature). Since then, [hundreds](https://containers.dev/features) of Features have been written by the community. The flexibility of Features has enabled a wide variety of use cases, from installing a single tool to setting up specific aspects of a project's development environment that can be shared across repositories. To that effect, many different patterns for Feature authorship have emerged, and the core team has learned a lot about what works well and what doesn't.
+
+## Utilize the `test` command
+
+Bundled with the [devcontainer cli](https://github.com/devcontainers/cli) is the `devcontainer features test` command. This command is designed to help Feature authors test their Feature in a variety of scenarios. It is highly recommended that Feature authors use this command to test their Feature before publishing. Some documentation on the `test` command can be found [here](https://github.com/devcontainers/cli/blob/main/docs/features/test.md), and an example can be found in the [Feature quick start repo](https://github.com/devcontainers/feature-starter). This repo is updated periodically as new functionality is added to the reference implementation.
+
+## Feature idempotency
+
+The most useful Features are idempotent. This means that if a Feature is installed multiple times with different options (something that will come into play with [Feature Dependencies](https://github.com/devcontainers/spec/blob/main/proposals/feature-dependencies.md)), the Feature should be able to handle this gracefully. This is especially important for option-rich Features that you anticipate others may depend on in the future.
+
+> đź”§ There is an open spec proposal for installing the same Feature twice in a given `devcontainer.json` [(devcontainers/spec#44)](https://github.com/devcontainers/spec/issues/44). While the syntax to do so in a given `devcontainer.json` is not yet defined, Feature dependencies will effectively allow for this.
+
+For Features that install a versioned tool (eg: version x of `go` and version y of `ruby` ), a robust Feature should be able to install multiple versions of the tool. If your tool has a version manager (java's `SDKMAN`, ruby's `rvm`) it is usually as simple as installing the version manager and then running a command to install the desired version of that tool.
+
+For instances where there isn't an existing version manager available, a well-designed Feature should consider installing distict versions of itself to a well known location. A pattern that many Features utilize successfully is writing each version of each tool to a central folder and symlinking the "active" version to a folder on the PATH.
+
+Features can redefine the PATH variable with `containerEnv`, like so:
+
+```bash
+# devcontainer-feature.json
+"containerEnv": {
+ "PATH": "/usr/local/myTool/bin:${PATH}"
+}
+```
+
+> đź”§ A spec proposal is open for simplifying the process of adding a path to the $PATH variable: [(devcontainers/spec#251)](https://github.com/devcontainers/spec/issues/251).
+
+To make testing for idempotency easy, [this change to the reference implementation](https://github.com/devcontainers/cli/pull/553) introduces a new mode to the `devcontainer features test` command that will attempt to install a Feature multiple times. This is useful for testing that a Feature is idempotent, and also for testing that a Feature is able to logically "juggle" multiple versions of a tool.
+
+## Writing your install script
+
+
+> đź”§ Many of the suggestions in this section may benefit from the [Feature library/code reuse proposal](https://github.com/devcontainers/spec/blob/main/proposals/features-library.md).
+
+This section includes some tips for the contents of the `install.sh` entrypoint script.
+
+### Detect Platform/OS
+
+> đź”§ A spec proposal is open for detecting the platform/OS and providing better warnings [(devcontainers/spec#58)](https://github.com/devcontainers/spec/issues/58).
+
+Features are often designed to work on a subset of possible base images. For example, the majority of Features in the [`devcontainers/features`](https://github.com/devcontainers/features) repo are designed to work broadly with debian-derived images. The limitation is often simply due to the wide array of base images available, and the fact that many Features will use an OS-specific package manager. To make it easy for users to understand which base images a Feature is designed to work with, it is recommended that Features include a check for the OS and provide a helpful error message if the OS is not supported.
+
+One possible way to implement this check is shown below.
+
+```bash
+# Source /etc/os-release to get OS info
+# Looks something like:
+# PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
+# NAME="Debian GNU/Linux"
+# VERSION_ID="11"
+# VERSION="11 (bullseye)"
+# VERSION_CODENAME=bullseye
+# ID=debian
+# HOME_URL="https://www.debian.org/"
+# SUPPORT_URL="https://www.debian.org/support"
+# BUG_REPORT_URL="https://bugs.debian.org/"
+. /etc/os-release
+# Store host architecture
+architecture="$(dpkg --print-architecture)"
+
+DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye focal bionic xenial"
+if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
+ print_error "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution"
+ print_error "Supported distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}"
+ exit 1
+fi
+```
+
+If you are targeting distros that may not have your desired scripting language installed (eg: `bash` is often not installed on `alpine` images), you can either use plain `/bin/sh` - which is available virtually everywhere - or you can verify (and install) the scripting language in a small bootstrap script as shown below.
+
+```sh
+#!/bin/sh
+
+# ...
+# ...
+
+if [ "$(id -u)" -ne 0 ]; then
+ echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
+ exit 1
+fi
+
+# If we're using Alpine, install bash before executing
+. /etc/os-release
+if [ "${ID}" = "alpine" ]; then
+ apk add --no-cache bash
+fi
+
+exec /bin/bash "$(dirname $0)/main.sh" "$@"
+exit $?
+```
+
+Validating functionality against several base images can be done by using the `devcontainer features test` command with the `--base-image` flag, or with a [scenario](https://github.com/devcontainers/cli/blob/main/docs/features/test.md#scenarios). For example, one could add a [workflow like this to their repo](https://github.com/devcontainers/features/blob/d934503a050ba84e6b42a006aacd891c4088eb62/.github/workflows/test-all.yaml#L9-L52).
+
+```yaml
+name: "Test Features matrixed with a set of base images"
+on:
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ continue-on-error: true
+ strategy:
+ matrix:
+ features: [
+ "anaconda",
+ "aws-cli",
+ "azure-cli",
+ # ...
+ ]
+ baseImage:
+ [
+ "ubuntu:bionic",
+ "ubuntu:focal",
+ "ubuntu:jammy",
+ "debian:11",
+ "debian:12",
+ "mcr.microsoft.com/devcontainers/base:ubuntu",
+ "mcr.microsoft.com/devcontainers/base:debian",
+ ]
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: "Install latest devcontainer CLI"
+ run: npm install -g @devcontainers/cli
+ {% raw %}
+ - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'"
+ run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }}
+ {% endraw %}
+```
+
+### Detect the non-root user
+
+Feature installation scripts are run as `root`. In contrast, many dev containers have a `remoteUser` set (either implicitly through [image metadata](https://containers.dev/implementors/spec/#image-metadata) or directly in the `devcontainer.json`). In a Feature's installation script, one should be mindful of the final user and account for instances where the user is not `root`.
+
+Feature authors should take advantage of the [`_REMOTE_USER` and similar variables](https://containers.dev/implementors/features/#user-env-var) injected during the build.
+
+```bash
+# Install tool in effective remoteUser's bin folder
+mkdir -p "$_REMOTE_USER_HOME/bin"
+curl $TOOL_DOWNLOAD_LINK -o "$_REMOTE_USER_HOME/bin/$TOOL"
+chown $_REMOTE_USER:$_REMOTE_USER "$_REMOTE_USER_HOME/bin/$TOOL"
+chmod 755 "$_REMOTE_USER_HOME/bin/$TOOL"
+```
+
+### Implement redundant paths/strategies
+
+Most Features in [the index today](https://containers.dev/features) have some external/upstream dependency. Very often these upstream dependencies can change (ie: versioning pattern, rotated GPG key, etc...) that may cause a Feature to fail to install. To mitigate this, one strategy is to implement multiple paths to install a given tool (if available). For example, a Feature that installs `go` might try to install it from the upstream package manager, and if not fall back to a GitHub release.
+
+Writing several [scenario tests](https://github.com/devcontainers/cli/blob/main/docs/features/test.md#scenarios) that force the Feature to go down distinct installation paths will help you catch cases where a given path no longer works.
\ No newline at end of file
diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md
new file mode 100644
index 00000000..684e854c
--- /dev/null
+++ b/_posts/2023-08-22-prebuild.md
@@ -0,0 +1,138 @@
+---
+layout: post
+title: "Speed Up Your Workflow with Prebuilds"
+author:
+ - "@bamurtaugh"
+ - "@craiglpeters"
+authorUrl:
+ - "https://github.com/bamurtaugh"
+ - "https://github.com/craiglpeters"
+
+---
+
+Getting dev containers up and running for your projects is exciting - you've unlocked environments that include all the dependencies your projects need to run, and you can spend so much more time on coding rather than configuration.
+
+Once your dev container has everything it needs, you might start thinking more about ways to optimize it. For instance, it might take a while to build. Maybe it takes 5 minutes. Maybe it takes an hour!
+
+You can get back to working fast and productively after that initial container build, but what if you need to work on another machine and build the container again? Or what if some of your teammates want to use the container on their machines and will need to build it too? It'd be great to make the build time faster for everyone, every time.
+
+After configuring your dev container, a great next step is to **prebuild your image**.
+
+In this guide, we'll explore what it means to prebuild an image and the benefits of doing so, such as speeding up your workflow, simplifying your environment, and pinning to specific versions of tools.
+
+We have a variety of tools designed to help you with prebuilds. In this guide, we'll explore two different repos as examples of how our team uses different combinations of these tools:
+* The prebuilt image for the [Kubernetes repo](https://github.com/craiglpeters/kubernetes-devcontainer) developed by one of our spec maintainers [Craig](https://github.com/craiglpeters)
+* The prebuilt images we host in the [devcontainers/images](https://github.com/devcontainers/images/tree/main/src) repo as part of the dev container spec
+
+
+## What is prebuilding?
+
+We should first define: What is prebuilding?
+
+If you're already using dev containers, you're likely already familiar with the idea of building a container, where you package everything your app needs to run into a single unit.
+
+You need to build your container once it has all the dependencies it needs, and rebuild anytime you add new dependencies. Since you may not need to rebuild often, it might be alright if it takes a while for that initial build. But if you or your teammates need to use that container on another machine, you'll need to wait for it to build again in those new environments.
+
+> **Note:** The [dev container CLI doc](/implementors/reference#prebuilding) is another great resource on prebuilding.
+
+### Prebuilt Codespaces
+
+You may have heard (or will hear about) [GitHub Codespaces prebuilds](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds). Codespaces prebuilds are similar to prebuilt container images, with some additional focus on the other code in your repo.
+
+GitHub Codespaces prebuilds help to speed up the creation of new codespaces for large or complex repositories. A prebuild assembles the main components of a codespace for a particular combination of repository, branch, and `devcontainer.json` file.
+
+By default, whenever you push changes to your repository, GitHub Codespaces uses GitHub Actions to automatically update your prebuilds.
+
+You can learn more about codespaces prebuilds and how to manage them in the [codespaces docs](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds).
+
+## How do I prebuild my image?
+
+We try to make prebuilding an image and using a prebuilt image as easy as possible. Let's walk through the couple of steps to get started.
+
+**Prebuilding an image:**
+* Install the [Dev Container CLI](/implementors/reference):
+
+ ```bash
+ npm install -g @devcontainers/cli
+ ```
+
+* Build your image and push it to a container registry (like the [Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-docker-cli?tabs=azure-cli), [GitHub Container Registry](https://docs.github.com/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images), or [Docker Hub](https://docs.docker.com/engine/reference/commandline/push)):
+
+ ```bash
+ devcontainer build --workspace-folder . --push true --image-name :
+ ```
+
+* You can automate pre-building your image by scheduling the build using a DevOps or continuous integration (CI) service like GitHub Actions. We've created a [GitHub Action](https://github.com/marketplace/actions/dev-container-build-and-run-action) and [Azure DevOps task](https://marketplace.visualstudio.com/items?itemName=devcontainers.ci) to help with this.
+
+**Using a prebuilt image:**
+* Determine the published URL of the prebuilt image you want to use
+* Reference it in your `devcontainer.json`, Dockerfile, or Docker Compose file
+ * In our previous guide on ["Using Images, Dockerfiles, and Docker Compose,"](/guide/dockerfile) we also showed how you can use prebuilt images, Dockerfiles, or Docker Compose files for your configurations
+
+### Prebuild Examples
+
+As mentioned above, let's walk through a couple examples of these steps, one using Craig's [Kubernetes repo](https://github.com/craiglpeters/kubernetes-devcontainer), and the other using our [devcontainers/images](https://github.com/devcontainers/images/tree/main/src) repo.
+
+**Kubernetes**
+* It's a fork of the main [Kubernetes repo](https://github.com/kubernetes/kubernetes) and contributes a prebuilt dev container for use in the main Kubernetes repo or any other forks
+* The dev container it's prebuilding is defined in the [.github/.devcontainer folder](https://github.com/craiglpeters/kubernetes-devcontainer/tree/master/.github/.devcontainer)
+* Any time a change is made to the dev container, the repo currently uses the dev container [GitHub Action](https://github.com/craiglpeters/kubernetes-devcontainer/actions/workflows/devcontainer-build-and-push.yml) to build the image and push it to GHCR
+ * You can check out its latest prebuilt image in the [`Packages` tab](https://github.com/users/craiglpeters/packages/container/package/kubernetes-devcontainer) of its GitHub Repo. In this tab, you can see its GHCR URL is `ghcr.io/craiglpeters/kubernetes-devcontainer:latest`
+* The main Kubernetes repo and any fork of it can now define a `.devcontainer` folder and [reference this prebuilt image](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.devcontainer/devcontainer.json#L7) through: `"image": "ghcr.io/craiglpeters/kubernetes-devcontainer:latest"`
+
+**Dev container spec images**
+* This repo prebuilds a variety of dev containers, each of which is defined in their individual folders in the [src folder](https://github.com/devcontainers/images/tree/main/src)
+ * As an example, the Python image is defined in the [src/python/.devcontainer](https://github.com/devcontainers/images/tree/main/src/python/.devcontainer) folder
+* Any time a change is made to the dev container, the repo uses a [GitHub Action](https://github.com/devcontainers/images/actions/workflows/push.yml) to build the image and push it to MCR
+ * Using the Python image as an example again, its MCR URL is `mcr.microsoft.com/devcontainers/python`
+* Any projects can now reference this prebuilt image through: `"image": "mcr.microsoft.com/devcontainers/python"`
+
+## Where do the dependencies come from?
+
+If your `devcontainer.json` is as simple as just an `image` property referencing a prebuilt image, you may wonder: How can I tell what dependencies will be installed for my project? And how can I modify them?
+
+Let's walk through the Kubernetes prebuild as an example of how you can determine which dependencies are installed and where:
+* **Start at your end user dev container**
+ * We start at the [`.devcontainer/devcontainer.json`](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.devcontainer/devcontainer.json) designed for end use in the Kubernetes repo and other forks of it
+ * It sets a few properties, such as `hostRequirements`, `onCreateCommand`, and `otherPortsAttributes`
+ * We see it references a prebuilt image, which will include dependencies that don't need to be explicitly mentioned in this end user dev container. Let's next go explore the dev container defining this prebuilt image
+* **Explore the dev container defining your prebuilt image**
+ * We next open the config that defines the prebuilt image. This is contained in the [`.github/.devcontainer` folder](https://github.com/craiglpeters/kubernetes-devcontainer/tree/master/.github/.devcontainer)
+ * We see there's a [`devcontainer.json`](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.github/.devcontainer/devcontainer.json). It's much more detailed than the end user dev container we explored above and includes a variety of [Features](/implementors/features)
+* **Explore content in the prebuilt dev container's config**
+ * Each Feature defines additional functionality
+ * We can explore what each of them installs in their associated repo. Most appear to be defined in the [devcontainers/features repo](https://github.com/devcontainers/features/tree/main/src) as part of the dev container spec
+* **Modify and rebuild as desired**
+ * If I'd like to add more content to my dev container, I can either modify my end user dev container (i.e. the one designed for the main Kubernetes repo), or modify the config defining the prebuilt image (i.e. the content in Craig's dev container)
+ * For universal changes that anyone using the prebuilt image should get, update the prebuilt image
+ * For more project or user specific changes (i.e. a language I need in my project but other forks won't necessarily need, or user settings I prefer for my editor environment), update the end user dev container
+ * Features are a great way to add dependencies in a clear, easily packaged way
+
+## Benefits
+
+There are a variety of benefits (some of which we've already explored) to creating and using prebuilt images:
+* Faster container startup
+ * Pull an already built dev container config rather than having to build it freshly on any new machine
+* Simpler configuration
+ * Your `devcontainer.json` can be as simple as just an `image` property
+* Pin to a specific version of tools
+ * This can improve supply-chain security and avoid breaks
+
+## Tips and Tricks
+
+* We explored the prebuilt images we host as part of the spec in [devcontainers/images](https://github.com/devcontainers/images/tree/main/src). These can form a great base for other dev containers you'd like to create for more complex scenarios
+* The spec has a concept of Development container "Templates" which are source files packaged together that encode configuration for a complete development environment
+ * A Template may be as simple as a `devcontainer.json` referencing a prebuilt image, and a `devcontainer-template.json`
+ * You can learn more about Templates in our [Templates documentation](../implementors/templates)
+ * You can adopt and iterate on [existing Templates](../templates.html) from the spec and community, or you can [create and share your own](../implementors/templates-distribution)
+* You can include Dev Container configuration and Feature metadata in prebuilt images via [image labels](https://docs.docker.com/config/labels-custom-metadata/). This makes the image self-contained since these settings are automatically picked up when the image is referenced - whether directly, in a `FROM` in a referenced Dockerfile, or in a Docker Compose file. You can learn more in our [reference docs](/implementors/reference#labels)
+* You can use multi-stage Dockerfiles to create a prod container from your dev container
+ * You'd typically start with your prod image, then add to it
+ * Features provide a quick way to add development and CI specific layers that you wouldn't use in production
+ * For more information and an example, check out our [discussion on multi-stage builds](https://github.com/orgs/devcontainers/discussions/4#discussioncomment-4152158)
+
+## Feedback and Closing
+
+We hope this guide will help you optimize your dev container workflows! We can't wait to hear your tips, tricks, and feedback. How are you prebuilding your images? Would anything in the spec or tooling make the process easier for you?
+
+If you haven't already, we recommend joining our dev container [community Slack channel](https://aka.ms/dev-container-community) where you can connect with the dev container spec maintainers and community at large. If you have any feature requests or experience any issues as you use the above tools, please feel free to also open an issue in the corresponding repo in the [dev containers org](https://github.com/devcontainers) on GitHub.
diff --git a/_posts/2024-01-23-dependabot.md b/_posts/2024-01-23-dependabot.md
new file mode 100644
index 00000000..dd73a371
--- /dev/null
+++ b/_posts/2024-01-23-dependabot.md
@@ -0,0 +1,81 @@
+---
+layout: post
+title: "General Availability of Dependabot Integration"
+author:
+ - "@joshspicer"
+authorUrl:
+ - https://github.com/joshspicer
+---
+
+We are excited to announce that starting today, in collaboration with the Dependabot Team, the `devcontainers` package ecosystem is now generally available!
+ Dependabot will now be able to update your public Dev Container [Features](https://containers.dev/features), keeping them up-to-date with the latest published versions.
+
+ To opt-in, add a `.github/dependabot.yml` to a repository containing one or more `devcontainer.json` configuration files:
+
+ ```yaml
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "devcontainers" # See documentation for possible values
+ directory: "/"
+ schedule:
+ interval: weekly
+ ```
+
+Once configured, Dependabot will begin to create pull requests to update your Dev Container Features:
+
+
+
+
+
+
+An example diff generated by Dependabot is shown below:
+
+```diff
+---
+ .devcontainer-lock.json | 8 ++++----
+ .devcontainer.json | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/.devcontainer-lock.json b/.devcontainer-lock.json
+index 324582b..a3868d9 100644
+--- a/.devcontainer-lock.json
++++ b/.devcontainer-lock.json
+@@ -1,9 +1,9 @@
+ {
+ "features": {
+- "ghcr.io/devcontainers/features/docker-in-docker:1": {
+- "version": "1.0.9",
+- "resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:b4c04ba88371a8ec01486356cce10eb9fe8274627d8d170aaec87ed0d333080d",
+- "integrity": "sha256:b4c04ba88371a8ec01486356cce10eb9fe8274627d8d170aaec87ed0d333080d"
++ "ghcr.io/devcontainers/features/docker-in-docker:2": {
++ "version": "2.7.1",
++ "resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:f6a73ee06601d703db7d95d03e415cab229e78df92bb5002e8559bcfc047fec6",
++ "integrity": "sha256:f6a73ee06601d703db7d95d03e415cab229e78df92bb5002e8559bcfc047fec6"
+ }
+ }
+ }
+\ No newline at end of file
+diff --git a/.devcontainer.json b/.devcontainer.json
+index e9d9af5..9eb9165 100644
+--- a/.devcontainer.json
++++ b/.devcontainer.json
+@@ -1,6 +1,6 @@
+ {
+ "image": "mcr.microsoft.com/devcontainers/base:jammy",
+ "features": {
+- "ghcr.io/devcontainers/features/docker-in-docker:1": {}
++ "ghcr.io/devcontainers/features/docker-in-docker:2": {}
+ }
+ }
+```
+
+ This updater ensures publicly-accessible Features are pinned to the latest version in the associated `devcontainer.json` file. If a dev container has an associated lockfile, that file will also be updated. For more information on lockfiles, see this [specification](https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-lockfile.md).
+
+Features in any [valid dev container location](https://containers.dev/implementors/spec/#devcontainerjson) will be updated in a single pull request.
+
+Dependabot version updates are free to use for all repositories on GitHub.com. For more information [see the Dependabot version update documentation](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/about-dependabot-version-updates#supported-repositories-and-ecosystem).
diff --git a/collections.html b/collections.html
index 205688e5..2dc28bf0 100644
--- a/collections.html
+++ b/collections.html
@@ -6,24 +6,60 @@
Collections
- This list below contains pointers to official and community-contributed Dev Container assets, including Features and Templates.
- Collections on this list are continuously crawled for liveness, and can be presented in UX of Dev Container-supporting tools
+ This list below contains pointers to official and community-contributed dev container assets, including Features and
+ Templates.
+ Collections on this list are continuously crawled for liveness, and can be presented in UX of spec supporting tools
(i.e. it will be presented in the GitHub Codespaces and VS Code Dev Containers UX).
- To add your own collection to this list, please create a PR editing this yaml file.
+ To add your own collection to this list, please create a PR editing this
+ yaml file.
+
+
\ No newline at end of file
diff --git a/contributing.md b/contributing.md
index 90d7ccba..8c2e9296 100644
--- a/contributing.md
+++ b/contributing.md
@@ -1,8 +1,8 @@
# How to Contribute to the Dev Container Specification
-We're excited for your contributions to the dev container specification! This document outlines how you can get involved.
+We're excited for your contributions to the Dev Container Specification! This document outlines how you can get involved. We also welcome you to join our [community Slack channel](https://aka.ms/dev-container-community).
-## Contribution approaches
+## Spec contribution approaches
If you'd like to contribute a change or addition to the spec, you may follow the guidance below:
- Propose the change via an [issue](https://github.com/devcontainers/spec/issues) in this repository. Try to get early feedback before spending too much effort formalizing it.
@@ -16,7 +16,7 @@ Here is a sample:
- PRs to the [schema](https://github.com/microsoft/vscode/blob/main/extensions/configuration-editing/schemas/devContainer.schema.src.json), i.e code or shell scripts demonstrating approaches for implementation.
-Once there is discussion on your proposal, please also open and link a PR to update the [devcontainer.json reference doc](https://github.com/microsoft/vscode-docs/blob/main/docs/remote/devcontainerjson-reference.md). When your proposal is merged, the docs will be kept up-to-date with the latest spec.
+Once there is discussion on your proposal, please also open and link a PR to update the [devcontainer.json reference doc](https://aka.ms/devcontainer.json). When your proposal is merged, the docs will be kept up-to-date with the latest spec.
### Contributing tool-specific support
@@ -37,14 +37,32 @@ Tool-specific properties are contained in namespaces in the `"customizations"` p
You may propose adding a new namespace for a specific tool, and any properties specific to that tool.
-### GitHub Discussions
-If you'd like to discuss the spec, such as asking questions, providing feedback, or engaging on how your team may use or contribute to dev containers, please check out the [GitHub Discussions](https://github.com/devcontainers/spec/discussions) in this repo. This is a great opportunity to connect with the community and maintainers of this project, without the requirement of contributing a change to the actual spec (which we see more in issues and PRs).
+## Formatting Guidelines
+
+When contributing an official doc or referencing dev containers in your projects, please consider the following guidelines:
+
+- Refer to the spec as the "Development Container Specification"
+ - All capital letters
+ - Singular "Container" rather than plural "Containers"
+- The term "dev container" shouldn't be capitalized on its own
+ - It should only be capitalized when referring to an official tool title, like the VS Code Dev Containers extension
+- Signify `devcontainer.json` is a file type through backticks
+- Features and Templates should always be capitalized
+- Refer to the CLI as the "Dev Container CLI" (note the caps)
+- Use bolding for emphasis sprinkled throughout sections, rather than try to use it to always bold certain terms
## Review process
-We use the following [labels](https://github.com/devcontainers/spec/labels):
+We use the following [labels](https://github.com/devcontainers/spec/labels) in the spec repo:
- `proposal`: Issues under discussion, still collecting feedback.
- `finalization`: Proposals we intend to make part of the spec.
[Milestones](https://github.com/devcontainers/spec/milestones) use a "month year" pattern (i.e. January 2022). If a finalized proposal is added to a milestone, it is intended to be merged during that milestone.
+
+## Community Engagement
+There are several additional options to engage with the dev container community, such as asking questions, providing feedback, or engaging on how your team may use or contribute to dev containers:
+- [GitHub Discussions](https://github.com/devcontainers/spec/discussions): This is a great opportunity to connect with the community and maintainers of this project, without the requirement of contributing a change to the actual spec (which we see more in issues and PRs)
+- [Community Slack channel](https://aka.ms/dev-container-community): This is a great opportunity to connect with the community and maintainers
+- You can always check out the issues and PRs (and contribute new ones) across the repos in the [Dev Containers GitHub org](https://github.com/devcontainers) too!
+- Community collections: You can contribute your own [Templates](https://containers.dev/implementors/templates-distribution/#distribution) and [Features](https://containers.dev/implementors/features-distribution/#distribution) to our [community index](https://containers.dev/collections)!
\ No newline at end of file
diff --git a/css/main.scss b/css/main.scss
index 53433b0a..b205fef8 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -24,7 +24,7 @@ body {
}
.bg-primary {
- background-color: #2753e3 !important;
+ background-color: #{{ site.theme_color }} !important;
}
.header-container {
@@ -442,7 +442,7 @@ pre[class=highlight] {
}
.nav .nav-link {
- color: #2753e3 !important;
+ color: #{{ site.theme_color }} !important;
}
.nav .nav-link:hover {
@@ -450,7 +450,7 @@ pre[class=highlight] {
}
a {
- color: #2753e3;
+ color: #{{ site.theme_color }};
}
a:hover {
diff --git a/features.html b/features.html
index 9ade82e0..edf3c062 100644
--- a/features.html
+++ b/features.html
@@ -7,30 +7,88 @@
- Referencing a feature below can be done in the "features" section of a devcontainer.json.
+ Referencing a Feature below can be done in the "features"
+ section of a devcontainer.json.
+
+ Please note that if you need to report a Feature, you should do so through the registry hosting the Feature.
+ To add your own collection to this list, please create a PR editing this
+ yaml file.
-
-
Feature Name
-
Maintainer
-
Reference
-
Latest Version
-
-
-{% for c in site.data.devcontainer-index.collections %}
+
+
+
+
+
+
+
+
Feature Name
+
Maintainer
+
Reference
+
Latest Version
+
+
+ {% for c in site.data.devcontainer-index.collections %}
{% for f in c.features %}
+ {% if f.deprecated != true %}
+
+
\ No newline at end of file
diff --git a/guides.html b/guides.html
new file mode 100644
index 00000000..6234d1d0
--- /dev/null
+++ b/guides.html
@@ -0,0 +1,13 @@
+---
+layout: singlePage
+title: Dev Container Guides
+---
+
+{% for post in site.posts %}
+
A Development Container (or Dev Container for short) allows you to use a container as a full-featured development environment. It can be used to run an application, to separate tools, libraries, or runtimes needed for working with a codebase, and to aid in continuous integration and testing. Dev containers can be run locally or remotely, in a private or public cloud.
+
A development container (or dev container for short) allows you to use a container as a full-featured
+ development environment. It can be used to run an application, to separate tools, libraries, or runtimes
+ needed for working with a codebase, and to aid in continuous integration and testing. Dev containers can
+ be run locally or remotely, in a private or public cloud, in a variety of supporting tools and editors.
-
The Development Containers Specification seeks to find ways to enrich existing formats with common development specific settings, tools, and configuration while still providing a simplified, un-orchestrated single container option – so that they can be used as coding environments or for continuous integration and testing. Beyond the specification's core metadata, the spec also enables developers to quickly share and reuse container setup steps through Dev Container Features and Templates.
+
The Development Container Specification seeks to find ways to enrich existing formats with common
+ development specific settings, tools, and configuration while still providing a simplified,
+ un-orchestrated single container option – so that they can be used as coding environments or for
+ continuous integration and testing. Beyond the specification's core metadata, the spec also enables
+ developers to quickly share and reuse container setup steps through Features and Templates.
-
-
Use or create dev container definitions for a multitude of tech stacks and tools.
+
+
Use or create dev container definitions for a multitude of tech stacks and
+ tools.
+ A variety of tools and services support this standard.
+
+
-
-
+
\ No newline at end of file
diff --git a/overview.md b/overview.md
index ccfb5e1f..6858efa8 100644
--- a/overview.md
+++ b/overview.md
@@ -7,17 +7,17 @@ sectionid: overview
## What are development containers?
As containerizing production workloads becomes commonplace, more developers are using containers for scenarios beyond deployment, including continuous integration, test automation, and even full-featured coding environments.
-Each scenario’s needs can vary between simple single container environments to complex, orchestrated multi-container setups. Rather than attempting to create another orchestrator format, the Development Containers Specification (or Dev Containers Spec for short) seeks to find ways to enrich existing formats with metadata for common development specific settings, tools, and configuration.
+Each scenario’s needs can vary between simple single container environments to complex, orchestrated multi-container setups. Rather than attempting to create another orchestrator format, the Development Container Specification (or Dev Container Spec for short) seeks to find ways to enrich existing formats with metadata for common development specific settings, tools, and configuration.
### A structured metadata format
Like the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) before it, the first format in the specification, [`devcontainer.json`](implementors/json_reference), was born out of necessity. It is a structured JSON with Comments (jsonc) metadata format that tools can use to store any needed configuration required to develop inside of local or cloud-based containerized coding.
-Since the spec was initally published, Dev Container metadata can now be stored in [image labels](../implementors/spec/#image-metadata) and in reusable chunks of metadata and install scripts known as [Dev Container Features](../features). We envision that this same structured data can be embedded in other formats -- all while retaining a common object model for consistent processing.
+Since the spec was initally published, dev container metadata can now be stored in [image labels](../implementors/spec/#image-metadata) and in reusable chunks of metadata and install scripts known as [Dev Container Features](../features). We envision that this same structured data can be embedded in other formats -- all while retaining a common object model for consistent processing.
### Development vs production
-A Development Container defines an environment in which you develop your application before you are ready to deploy. While deployment and development containers may resemble one another, you may not want to include tools in a deployment image that you use during development.
+A development container defines an environment in which you develop your application before you are ready to deploy. While deployment and development containers may resemble one another, you may not want to include tools in a deployment image that you use during development.
diff --git a/supporting.md b/supporting.md
index f0163ddc..30a7d129 100644
--- a/supporting.md
+++ b/supporting.md
@@ -4,7 +4,7 @@ layout: singlePage
sectionid: supporting
---
-This page outlines tools and services that currently support the development container specification, including the `devcontainer.json` format. A `devcontainer.json` file in your project tells tools and services that support the dev container spec how to access (or create) a dev container with a well-defined tool and runtime stack.
+This page outlines tools and services that currently support the Development Container Specification, including the `devcontainer.json` format. A `devcontainer.json` file in your project tells tools and services that support the dev container spec how to access (or create) a dev container with a well-defined tool and runtime stack.
While most [dev container properties](implementors/json_reference) apply to any `devcontainer.json` supporting tool or service, a few are specific to certain tools, which are outlined below.
@@ -29,33 +29,53 @@ Visual Studio Code specific properties go under `vscode` inside `customizations`
|:------------------|:------------|:------------|
| `extensions` | array | An array of extension IDs that specify the extensions that should be installed inside the container when it is created. Defaults to `[]`. |
| `settings` | object | Adds default `settings.json` values into a container/machine specific settings file. Defaults to `{}`. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
-Please note that [Dev Containers](#dev-containers) and [GitHub Codespaces](#github-codespaces) support the VS Code properties.
+Please note that the [Dev Containers](#dev-containers) extension and [GitHub Codespaces](#github-codespaces) support these VS Code properties.
### Visual Studio
-Visual Studio added Dev Container support in Visual Studio 2022 17.4 for C++ projects using CMake Presets. It is part of the Linux and embedded development with C++ workload, so make sure it is selected in your VS installation. Visual Studio manages the lifecycle of Dev Containers it uses as you work, but it treats them as remote targets in a similar way to other Linux or WSL targets.
+Visual Studio added dev container support in Visual Studio 2022 17.4 for C++ projects using CMake Presets. It is part of the Linux and embedded development with C++ workload, so make sure it is selected in your VS installation. Visual Studio manages the lifecycle of dev containers it uses as you work, but it treats them as remote targets in a similar way to other Linux or WSL targets.
You may learn more in the [announcement blog post](https://devblogs.microsoft.com/cppblog/dev-containers-for-c-in-visual-studio/).
+### IntelliJ IDEA
+
+IntelliJ IDEA has early support dev containers that can be run remotely via an SSH connection or locally using Docker.
+
+You may learn more in the [announcement blog post](https://blog.jetbrains.com/idea/2023/06/intellij-idea-2023-2-eap-6/#SupportforDevContainers).
+
## Tools
-## Dev container CLI
+### Dev Container CLI
+
+The Dev Container Command Line Interface (CLI) is a reference implementation for the Dev Container Spec. It is in development in the [devcontainers/cli](https://github.com/devcontainers/cli) repo. It is intended both for use directly and by tools or services that want to support the spec.
+
+The CLI can take a `devcontainer.json` and create and configure a dev container from it. It allows for prebuilding dev container configurations using a CI or DevOps product like GitHub Actions. It can detect and include dev container features and apply them at container runtime, and run [lifecycle scripts](implementors/json_reference/#lifecycle-scripts) like `postCreateCommand`, providing more power than a plain `docker build` and `docker run`.
+
+#### VS Code extension CLI
-A dev container command line interface (CLI) that implements this specification. It is in development in the [devcontainers/cli](https://github.com/devcontainers/cli) repo.
+The [VS Code Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) includes a variation of the Dev Container CLI that adds the ability use the command line to open a dev container in VS Code. It is also automatically updated when the extension updates.
-The CLI can take a `devcontainer.json` and create and configure a dev container from it. It allows for prebuilding dev container definitions using a CI or DevOps product like GitHub Actions. It can detect and include dev container features and apply them at container runtime, and run [lifecycle commands](implementors/json_reference/#lifecycle-scripts) like `postCreateCommand`, providing more power than a plain `docker build` and `docker run`.
+Press cmd/ctrl+shift+p or F1 and select the **Dev Containers: Install devcontainer CLI** command to install it.
-### VS Code extension CLI
+### Cachix devenv
-VS Code has a [CLI](https://code.visualstudio.com/docs/remote/devcontainer-cli) which may be installed within the Dev Containers extension or through the command line.
+Cachix's **[devenv](https://devenv.sh/)** now supports automatically generating a `.devcontainer.json` file. This gives you a more convenient and consistent way to use [Nix](https://nixos.org/) with any Dev Container Spec supporting tool or service!
-### Visual Studio Code Dev Containers
+See [devenv documentation](https://devenv.sh/integrations/codespaces-devcontainer/) for detais.
-The [**Visual Studio Code Dev Containers** extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) lets you use a [Docker container](https://docker.com) as a full-featured development environment. It allows you to open any folder inside (or mounted into) a container and take advantage of Visual Studio Code's full feature set. There is more information in the Dev Containers [documentation](https://code.visualstudio.com/docs/remote/containers).
+### Jetify Devbox
-> **Tip:** If you make a change to your dev container after having built and connected to it, be sure to run **Dev Containers: Rebuild Container** from the Command Palette (`kbstyle(F1)`) to pick up any changes you make.
+[Jetify](https://jetify.com) (formerly jetpack.io) is a [Nix](https://nixos.org/)-based service for deploying applications. [DevBox](https://www.jetify.com/devbox/) provides a way to use Nix to generate a development environment. [Jetify's VS Code extension](https://marketplace.visualstudio.com/items?itemName=jetpack-io.devbox) allows you to quickly take advantage of DevBox in any Dev Container Spec supporting tool or service.
+
+Press cmd/ctrl+shift+p or F1 and select the **Generate Dev Container files** command to get started!
+
+### VS Code Dev Containers extension
+
+The [Visual Studio Code Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) lets you use a [Docker container](https://docker.com) as a full-featured development environment. It allows you to open any folder inside (or mounted into) a container and take advantage of Visual Studio Code's full feature set. There is more information in the Dev Containers [documentation](https://code.visualstudio.com/docs/remote/containers).
+
+> **Tip:** If you make a change to your dev container after having built and connected to it, be sure to run **Dev Containers: Rebuild Container** from the Command Palette (cmd/ctrl+shift+p or F1) to pick up any changes you make.
#### Product specific properties
@@ -71,15 +91,15 @@ Some properties may also have certain limitations in the Dev Containers extensio
| `workspaceFolder` | string | Not yet supported when using Clone Repository in Container Volume. |
| `${localWorkspaceFolder}` | Any | Not yet supported when using Clone Repository in Container Volume. |
| `${localWorkspaceFolderBasename}` | Any | Not yet supported when using Clone Repository in Container Volume. |
-{: .table .table-bordered .table-responsive}
+{: .table .table-bordered}
+
+## Services
### GitHub Codespaces
A [codespace](https://docs.github.com/en/codespaces/overview) is a development environment that's hosted in the cloud. Codespaces run on a variety of VM-based compute options hosted by GitHub.com, which you can configure from 2 core machines up to 32 core machines. You can connect to your codespaces from the browser or locally using Visual Studio Code.
-> **Tip:** If you make a change to your dev container after having built and connected to your codespace, be sure to run **Codespaces: Rebuild Container** from the Command Palette (`kbstyle(F1)`) to pick up any changes you make.
-
-> **Tip** Codespaces implements an auto `workspaceFolder` mount in **Docker Compose** scenarios.
+> **Tip:** If you make a change to your dev container after having built and connected to your codespace, be sure to run **Codespaces: Rebuild Container** from the Command Palette (cmd/ctrl+shift+p or F1) to pick up any changes you make.
#### Product specific properties
GitHub Codespaces works with a growing number of tools and, where applicable, their `devcontainer.json` properties. For example, connecting the Codespaces web editor or VS Code enables the use of [VS Code properties](#visual-studio-code).
@@ -88,33 +108,102 @@ If your Codespaces project needs additional permissions for other repositories,
```json
"customizations": {
- // Configure properties specific to Codespaces.
- "codespaces": {
- "repositories": {
- "my_org/my_repo": {
- "permissions": {
- "issues": "write"
- }
+ // Configure properties specific to Codespaces.
+ "codespaces": {
+ "repositories": {
+ "my_org/my_repo": {
+ "permissions": {
+ "issues": "write"
}
}
}
+ }
+}
+```
+
+You can customize which files are initially opened when the codespace is created:
+```json
+"customizations": {
+ // Configure properties specific to Codespaces.
+ "codespaces": {
+ "openFiles": [
+ "README"
+ "src/index.js"
+ ]
+ }
}
```
+The paths are relative to the root of the repository. They will be opened in order, with the first file activated.
+
+> **Note** that currently Codespaces reads these properties from `devcontainer.json`, not image metadata.
+
#### Product specific limitations
-Some properties may apply differently to Codespaces.
+Some properties may apply differently to codespaces.
-| Property or variable | Type | Description |
-|:------------------|:------------|:------------|
+| Property or variable | Type | Description |
+|----------|---------|----------------------|
| `mounts` | array | Codespaces ignores "bind" mounts with the exception of the Docker socket. Volume mounts are still allowed.|
| `forwardPorts` | array | Codespaces does not yet support the `"host:port"` variation of this property. |
| `portsAttributes` | object | Codespaces does not yet support the `"host:port"` variation of this property.|
| `shutdownAction` | enum | Does not apply to Codespaces. |
| `${localEnv:VARIABLE_NAME}` | Any | For Codespaces, the host is in the cloud rather than your local machine.|
-| `waitFor` | enum | Codespaces does not yet support `waitFor`. |
-{: .table .table-bordered .table-responsive}
+| `customizations.codespaces` | object | Codespaces reads this property from devcontainer.json, not image metadata. |
+| `hostRequirements` | object | Codespaces reads this property from devcontainer.json, not image metadata. |
+{: .table .table-bordered}
+
+### CodeSandbox
+
+[CodeSandbox](https://codesandbox.io/) provides cloud development environments running on a microVM architecture. VM specs start at 2 vCPUs + 2 GB RAM per environment (free tier) and can go up to 16 vCPUs + 32 GB RAM.
+
+When you import a GitHub repository into CodeSandbox, it will automatically provision a dedicated environment for every branch. Thanks to memory snapshotting, CodeSandbox then resumes and branches an environment in under two seconds.
+
+CodeSandbox offers support for multiple editors, so you can code using the CodeSandbox web editor, VS Code, or the CodeSandbox iOS app.
+
+**Tip:** After importing a repository into CodeSandbox, you can use the built-in UI to configure the environment using dev containers.
+
+#### Product specific properties
+CodeSandbox has built-in support for any programming language and supports Debian and Ubuntu-based images.
+
+All properties specific to CodeSandbox are placed within a `.codesandbox` folder at root level. Typically, this will contain a `tasks.json` file, which defines the commands to be run at startup or with a click.
+
+More details about these can be found in the CodeSandbox [documentation](https://codesandbox.io/docs/learn/repositories/task).
+
+#### Product specific limitations
+
+CodeSandbox runs dev containers using rootless Podman instead of Docker. CodeSandbox also uses [devcontainers/cli](https://github.com/devcontainers/cli) to manage dev containers. So any limitations of rootless Podman and Dev Container CLI should apply to CodeSandbox.
+
+The following properties apply differently to CodeSandbox.
+
+| Property or variable | Type | Description |
+|----------|---------|----------------------|
+| `forwardPorts` | array | CodeSandbox does not need this property. All ports opened in dev containers will be mapped to a public URL automatically. |
+| `portsAttributes` | object | CodeSandbox does not yet support this property. Ports are attached to tasks configured in `.codesandbox/tasks.json` and are attributed to the tasks.|
+| `otherPortsAttributes` | object | CodeSandbox does not yet support this property. |
+| `remoteUser` | string | CodeSandbox currently ignores this property and overrides this as `root`. CodeSandbox uses rootless Podman to run containers. Running with a non-root remote user is the same as running as a root remote user in rootless Podman, from a security perspective. CodeSandbox plans on supporting this in the future. |
+| `shutdownAction` | string | Does not apply to CodeSandbox. |
+| `capAdd` | array | CodeSandbox does not support adding docker capabilities. As the containers are run as a non-root user, capabilities that need root access will not work. |
+| `features` | object | CodeSandbox automatically adds docker-cli to the container and connects to the host socket. Features like `docker-in-docker` and `docker-outside-of-docker` will work a bit differently. As the docker-cli and socket from host are accessible in the container, most use cases should work as expected. |
+| `${localEnv:VARIABLE_NAME}` | Any | For CodeSandbox, the host is in the cloud rather than in your local machine.|
+| `hostRequirements` | object | CodeSandbox does not yet support this property. |
+{: .table .table-bordered}
+
+### DevPod
+
+[DevPod](https://github.com/loft-sh/devpod) is a client-only tool to create reproducible developer environments based on a `devcontainer.json` on any backend. Each developer environment runs in a container and is specified through a `devcontainer.json`. Through DevPod providers these environments can be created on any backend, such as the local computer, a Kubernetes cluster, any reachable remote machine or in a VM in the cloud.
+
+### Ona (formerly Gitpod)
+
+[Ona](https://ona.com/) (formerly Gitpod) is the mission control for software projects and software engineering agents. It provides secure, ephemeral development environments that run in our cloud or your VPC, enabling humans and agents to collaborate seamlessly.
+
+Ona fully adheres to the Dev Container Specification, so you can define portable and reproducible environments with `devcontainer.json`. Whether you’re onboarding a new developer, running background agents, or delegating long-running migrations, Ona Environments ensure every task runs in a clean, policy-enforced environment.
+
+For details on constraints, customization, and automation options, see the [Ona Dev Container docs](https://ona.com/docs/ona/configuration/devcontainer/overview).
+
### Schema
You can explore the [VS Code implementation](implementors/json_schema) of the dev container schema.
+
+
diff --git a/templates.html b/templates.html
index 42f620be..14573146 100644
--- a/templates.html
+++ b/templates.html
@@ -12,21 +12,78 @@
Available Dev Container Templa
Template quick start repository to add your own!
Templates listed here will be presented in the UX of supporting tools.
+
+ Please note that if you need to report a Template, you should do so through the registry hosting the Template.
+ To add your own collection to this list, please create a PR editing this
+ yaml file.
-
-
Template Name
-
Maintainer
-
-{% for c in site.data.devcontainer-index.collections %}
+
+
+
+
+
+
+
Template Name
+
Maintainer
+
Reference
+
Latest Version
+
+
+ {% for c in site.data.devcontainer-index.collections %}
{% for f in c.templates %}