|
| 1 | +# Dev Container Templates reference |
| 2 | + |
| 3 | +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](https://containers.dev/supporting) will use the configuration from the Template to build a development container. |
| 4 | + |
| 5 | +The configuration is placed in a [`.devcontainer.json`](/docs/specs/devcontainer-reference.md#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](https://containers.dev/implementors/json_reference/#lifecycle-scripts). |
| 6 | + |
| 7 | +Template metadata is captured by a `devcontainer-template.json` file in the root folder of the Template. |
| 8 | + |
| 9 | +## Folder structure |
| 10 | + |
| 11 | +A single Template is a folder with at least a `devcontainer-template.json` and [`devcontainer.json`](/docs/specs/devcontainer-reference.md#devcontainerjson). Additional files are permitted and are packaged along side the required files. |
| 12 | + |
| 13 | +``` |
| 14 | ++-- template |
| 15 | +| +-- devcontainer-template.json |
| 16 | +| +-- .devcontainer.json |
| 17 | +| +-- (other files) |
| 18 | +``` |
| 19 | + |
| 20 | +## devcontainer-template.json properties |
| 21 | + |
| 22 | +The `devcontainer-template.json` file defines information about the Template to be used by any [supporting tools](../docs/specs/supporting-tools.md#supporting-tools-and-services). |
| 23 | + |
| 24 | +The properties of the file are as follows: |
| 25 | + |
| 26 | +| Property | Type | Description | |
| 27 | +| :--- | :--- | :--- | |
| 28 | +| `id` | string | ID of the Template. The `id` should be unique in the context of the repository/published package where the Template exists and must match the name of the directory where the `devcontainer-template.json` resides. | |
| 29 | +| `name` | string | Name of the Template. | |
| 30 | +| `description` | string | Description of the Template. | |
| 31 | +| `documentationURL` | string | Url that points to the documentation of the Template. | |
| 32 | +| `licenseURL` | string | Url that points to the license of the Template. | |
| 33 | +| `type` | string | Type of the dev container (image, dockerfile, dockerCompose) created by the Template. | |
| 34 | +| `options` | object | A map of options that the supporting tools should use to populate different configuration options for the Template. | |
| 35 | +| `platforms` | object | Languages and platforms supported by the Template. | |
| 36 | +| `publisher` | object | Name of the publisher/maintainer of the Template. | |
| 37 | +| `keywords` | array | List of strings relevant to a user that would search for this Template. | |
| 38 | + |
| 39 | +### The `options` property |
| 40 | + |
| 41 | +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 the specified `replaceIn` files. 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: |
| 42 | + |
| 43 | +```json |
| 44 | +{ |
| 45 | + "options": { |
| 46 | + "optionId": { |
| 47 | + "type": "string", |
| 48 | + "description": "Description of the option", |
| 49 | + "proposals": ["value1", "value2"], |
| 50 | + "default": "value1", |
| 51 | + "replaceIn": [".devcontainer.json"], |
| 52 | + } |
| 53 | + } |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +| Property | Type | Description | |
| 58 | +| :--- | :--- | :--- | |
| 59 | +| `optionId` | string | ID of the option used by the supporting tools to replace the selected value in the specified `replaceIn` files. | |
| 60 | +| `optionId.type` | string | Type of the option. Valid types are currently: `boolean`, `string` | |
| 61 | +| `optionId.description` | string | Description for the option. | |
| 62 | +| `optionId.proposals` | array | A list of suggested string values. Free-form values **are** allowed. Omit when using `optionId.enum`. | |
| 63 | +| `optionId.enum` | array | A strict list of allowed string values. Free-form values are **not** allowed. Omit when using `optionId.proposals`. | |
| 64 | +| `optionId.default` | string | Default value for the option. | |
| 65 | +| `optionId.replaceIn` | array | List of file paths which the supporting tool should use to perform the string replacement of `optionId` with the selected value. The provided path is always relative to the sub-directory of the Template. | |
| 66 | + |
| 67 | +> `Note`: The `options` must be unique for every `devcontainer-template.json` |
| 68 | +
|
| 69 | +### Referencing a Template |
| 70 | + |
| 71 | +The `id` format (`<oci-registry>/<namespace>/<template>[:<semantic-version>]`) dictates how a [supporting tool](https://containers.dev/supporting) will locate and download a given Template from an OCI registry. For example: |
| 72 | + |
| 73 | +- `ghcr.io/user/repo/go` |
| 74 | +- `ghcr.io/user/repo/go:1` |
| 75 | +- `ghcr.io/user/repo/go:latest` |
| 76 | + |
| 77 | +The registry must implement the [OCI Artifact Distribution Specification](https://github.com/opencontainers/distribution-spec). Some implementors can be [found here](https://oras.land/implementors/). |
| 78 | + |
| 79 | +## Versioning |
| 80 | + |
| 81 | +Each Template is individually [versioned according to the semver specification](https://semver.org/). The `version` property in the respective `devcontainer-template.json` file is updated to increment the Template's version. |
| 82 | + |
| 83 | +Tooling that handles releasing Templates will not republish Templates if that exact version has already been published; however, tooling must republish major and minor versions in accordance with the semver specification. |
| 84 | + |
| 85 | +## Release |
| 86 | + |
| 87 | +_For information on distributing Templates, see [devcontainer-templates-distribution.md](./devcontainer-templates-distribution.md)._ |
| 88 | + |
| 89 | +### Option Resolution |
| 90 | + |
| 91 | +A Template's `options` property is used by a supporting tool to prompt for different configuration options. A supporting tool will parse the `options` object provided by the user. If a value is selected for a Template, it will be replaced in the provided `replaceIn` files. |
| 92 | + |
| 93 | +### Option resolution example |
| 94 | + |
| 95 | +Consider a `java` Template with the following folder structure: |
| 96 | + |
| 97 | ++-- java |
| 98 | +| +-- devcontainer-template.json |
| 99 | +| +-- .devcontainer.json |
| 100 | + |
| 101 | +Suppose the `java` Template has the following `options` parameters declared in the `devcontainer-template.json` file: |
| 102 | + |
| 103 | +```json |
| 104 | +// ... |
| 105 | +"options": { |
| 106 | + "imageVariant": { |
| 107 | + "type": "string", |
| 108 | + "description": "Specify version of java.", |
| 109 | + "proposals": [ |
| 110 | + "17-bullseye", |
| 111 | + "17-buster", |
| 112 | + "11-bullseye", |
| 113 | + "11-buster", |
| 114 | + "17", |
| 115 | + "11" |
| 116 | + ], |
| 117 | + "default": "17-bullseye", |
| 118 | + "replaceIn": [".devcontainer.json"] |
| 119 | + }, |
| 120 | + "nodeVersion": { |
| 121 | + "type": "string", |
| 122 | + "proposals": [ |
| 123 | + "latest", |
| 124 | + "16", |
| 125 | + "14", |
| 126 | + "10", |
| 127 | + "none" |
| 128 | + ], |
| 129 | + "default": "latest", |
| 130 | + "description": "Specify version of node, or 'none' to skip node installation.", |
| 131 | + "replaceIn": [".devcontainer.json"] |
| 132 | + }, |
| 133 | + "installMaven": { |
| 134 | + "type": "boolean", |
| 135 | + "description": "Install Maven, a management tool for Java.", |
| 136 | + "default": "false", |
| 137 | + "replaceIn": [".devcontainer.json"] |
| 138 | + }, |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +and it has the following `.devcontainer.json` file: |
| 143 | + |
| 144 | +```json |
| 145 | +{ |
| 146 | + "name": "Java", |
| 147 | + "image": "mcr.microsoft.com/devcontainers/java:0-${templateOption:imageVariant}", |
| 148 | + "features": { |
| 149 | + "ghcr.io/devcontainers/features/node:1": { |
| 150 | + "version": "${templateOption:nodeVersion}", |
| 151 | + "installMaven": "${templateOption:installMaven}" |
| 152 | + } |
| 153 | + }, |
| 154 | +// ... |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +A user tries to add the `java` Template to their project using the [supporting tools](../docs/specs/supporting-tools.md#supporting-tools-and-services) and selects `17-bullseye` when prompted for `"Specify version of Go"` and the `default` values when prompted for `"Specify version of node, or 'none' to skip node installation"` and `"Install Maven, a management tool for Java"`. |
| 159 | + |
| 160 | +The supporting tool could then use a string replacer (eg. [handlebars](https://handlebarsjs.com/)) for the files mentioned by `replaceIn` property. In this example, `.devcontainer.json` needs to be modified and hence, the inputs can provided to it as follows: |
| 161 | + |
| 162 | +``` |
| 163 | +{ |
| 164 | + imageVariant:"17-bullseye", |
| 165 | + nodeVersion: "latest", |
| 166 | + installMaven: "false" |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +The modified `.devcontainer.json` will be as follows: |
| 171 | + |
| 172 | +```json |
| 173 | +{ |
| 174 | + "name": "Go", |
| 175 | + "image": "mcr.microsoft.com/devcontainers/go:0-17-bullseye", |
| 176 | + "features": { |
| 177 | + "ghcr.io/devcontainers/features/node:1": { |
| 178 | + "version": "latest", |
| 179 | + "installMaven": "false" |
| 180 | + } |
| 181 | + }, |
| 182 | + ... |
| 183 | +} |
| 184 | +``` |
| 185 | + |
| 186 | +The modified `.devcontainer.json` would be dropped into any existing folder as a starting point for containerizing your project. |
0 commit comments