forked from devcontainers/spec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.bs
476 lines (361 loc) Β· 23.2 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
<pre class=metadata>
Title: Development Containers
Abstract: 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.
Status: LD
Warning: Not Ready
Shortname: devcontainers
Repository: devcontainers-community/devcontainers.org
Favicon: https://avatars.githubusercontent.com/u/102692984?s=200&v=4
URL: https://devcontainers.org/spec/
Editor: Samruddhi Khandale, Microsoft, https://github.com/samruddhikhandale
Editor: Brigit Murtaugh, Microsoft, https://github.com/bamurtaugh
Editor: Josh Spicer, Microsoft, https://github.com/joshspicer
Former Editor: Edmundo Gonzalez, Microsoft, https://github.com/edgonmsft
!Participate: <a href="https://github.com/devcontainers/spec">Participate on GitHub!</a>
Markup Shorthands: markdown yes
Complain About: accidental-2119 no, missing-example-ids no
Boilerplate: omit conformance
</pre>
<div boilerplate=copyright>
<!-- https://creativecommons.org/choose/results-one?license_code=by&jurisdiction=&version=4.0&lang=en -->
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img no-autosize alt="Creative Commons License" src="https://i.creativecommons.org/l/by/4.0/80x15.png"></a> This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
</div>
<script type="module">
document.body.insertAdjacentHTML("afterbegin", `
<nav id="mynav">
<ul>
<li><a href="https://devcontainers.org/">Home</a></li>
<li><a href="https://devcontainers.org/marketplace/">Marketplace</a></li>
<li><a href="https://devcontainers.org/devctl/">devctl</a></li>
<li><a href="./">Specification</a></li>
</ul>
</nav>
<style>
#mynav {
display: flex;
align-items: center;
justify-content: end;
}
#mynav ul {
margin: 0;
padding: 0;
display: flex;
gap: 0.66em;
align-items: center;
justify-content: center;
list-style: none;
}
#mynav ul li {
display: block;
margin: 0;
padding: 0;
}
</style>
`)
</script>
<!--
ββββ ββ ββ ββββββββ ββββββββ βββββββ
ββ βββ ββ ββ ββ ββ ββ ββ
ββ ββββ ββ ββ ββ ββ ββ ββ
ββ ββ ββ ββ ββ ββββββββ ββ ββ
ββ ββ ββββ ββ ββ ββ ββ ββ
ββ ββ βββ ββ ββ ββ ββ ββ
ββββ ββ ββ ββ ββ ββ βββββββ
-->
# Introduction # {#intro}
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 <dfn export>development container</dfn> 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 <dfn export>environment</dfn> 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.
[=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.
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.
## Lifecycle
A development environment goes through different lifecycle events during its use in the outer and inner loop of development.
1. Configuration Validation
2. Environment Creation
3. Environment Stop
4. Environment Resume
### Configuration validation
The exact steps required to <dfn>validate a configuration</dfn> 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=] in the workspace source folder.
3. If no [=devcontainer.json=] is found, it is up to the implementing tool or service to determine what to do. This specification does not dictate this behavior.
4. Validate that the metadata contains all parameters required for the selected configuration type.
<!--
ββββββ βββββββ ββ ββ ββββββββ ββββ ββββββ
ββ ββ ββ ββ βββ ββ ββ ββ ββ ββ
ββ ββ ββ ββββ ββ ββ ββ ββ
ββ ββ ββ ββ ββ ββ ββββββ ββ ββ ββββ
ββ ββ ββ ββ ββββ ββ ββ ββ ββ
ββ ββ ββ ββ ββ βββ ββ ββ ββ ββ
ββββββ βββββββ ββ ββ ββ ββββ ββββββ
-->
# Configuration # {#config}
There are three primary sources that dev container configuration can come from:
1. <code>devcontainer.json</code>
2. Docker image metadata
3. Included dev container features
## devcontainer.json
To <dfn>search for a devcontainer.json</dfn>, an agent should look in any of these locations to locate a [=devcontainer.json=]
- `.devcontainer/devcontainer.json`
- `.devcontainer.json`
- <code>.devcontainer/<i>$FOLDER</i>/devcontainer.json</code> (where `$FOLDER` 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.
The <dfn export>`devcontainer.json`</dfn> file is a [JSON-with-comments](https://github.com/microsoft/node-jsonc-parser) file that conforms to the {{DevcontainerJSON}} IDL definition below:
<xmp class=idl>
dictionary DevcontainerJSON {
DOMString name;
sequence<DOMString> forwardPorts;
any portsAttributes;
any otherPortsAttributes;
any containerEnv;
any remoteEnv;
DOMString remoteUser;
DOMString containerUser;
boolean updateRemoteUserUID;
any userEnvProbe;
DOMString workspaceFolder;
};
</xmp>
- {{DevcontainerJSON/name}}: A name for the dev container displayed in the UI
- {{forwardPorts}}: An array of port numbers or `"host:port"` values that should always be forwarded from inside the primary container to the local machine (including on the web). Defaults to `[]`.
<pre class=example highlight=json>
{
// The "db" hostname in docker-compose.yml
"forwardPorts": [3000, "db:8080"]
}
</pre>
<p class=note>This 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.</p>
- {{portsAttributes}}: Object that maps a port number, <code>"host:port"</code> value, range, or regular expression to a set of default options. See port attributes for available options.
<pre class=example highlight=json>
{
"forwardPorts": [3000],
"portsAttributes": {
"3000": {
"label": "Application port"
}
}
}
</pre>
- {{otherPortsAttributes}}: Default options for ports, port ranges, and hosts that aren't configured using portsAttributes. See port attributes for available options.
<pre class=example highlight=json>
{
"forwardPorts": [3000],
"otherPortsAttributes": {
"onAutoForward": "silent"
}
}
</pre>
- {{containerEnv}}: A set of name-value pairs that sets or overrides environment variables for the container. Environment and pre-defined variables may be referenced in the values.
<pre class=example highlight=json>
{
"containerEnv": {
"MY_VARIABLE": "${localEnv:MY_VARIABLE}"
}
}
</pre>
<div class=note>
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.
</div>
- {{workspaceFolder}}: 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.
A core principle of this specification is to seek to enrich existing container orchestrator formats with development container metadata where appropriate rather than replacing them. As a result, the metadata schema includes a set of optional properties for interoperating with different orchestrators. Today, the specification includes scenario-specific properties for working without a container orchestrator (by directly referencing an image or Dockerfile) and for using Docker Compose as a simple multi-container orchestrator. At the same time, this specification leaves space for further development and implementation of other orchestrator mechanisms and file formats.
### Image based
Image based configurations only reference an image that should be reachable and downloadable through docker pull commands. Logins and tokens required for these operations are execution environment specific. The only required parameter is image.
<xmp class=idl>
partial dictionary DevcontainerJSON {
DOMString image;
};
</xmp>
- {{image}}: The name of an image in a container registry (DockerHub, GitHub Container Registry, Azure Container Registry) that devcontainer.json supporting services/tools should use to create the dev container. Required when using an image.
Both [[#image-based]] and [[#dockerfile-based]] configurations share these properties:
<xmp class=idl>
partial dictionary DevcontainerJSON {
// image;
// build;
(long or DOMString or sequence<(long or DOMString)>) appPort;
DevcontainerWorkspaceMount workspaceMount;
DevcontainerRunArgs runArgs;
};
</xmp>
- {{image}}: The name of an image in a container registry (DockerHub, GitHub Container Registry, Azure Container Registry) that devcontainer.json supporting services/tools should use to create the dev container. Required when using an image.
- {{build}}: Configuration for building a Dockerfile.
- {{dockerfile}}: The location of a Dockerfile that defines the contents of the container. Required when using a Dockerfile.
- {{context}}: Path that the Docker build should be run from relative to devcontainer.json. Defaults to ".".
- {{args}}: A set of name-value pairs containing Docker image build arguments that should be passed when building a Dockerfile. Defaults to not set.
- {{target}}: A string that specifies a Docker image build target that should be passed when building a Dockerfile. Defaults to not set.
- {{cacheFrom}}: 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}}: In most cases, we recommend using the new forwardPorts property. This property accepts a port or array of ports that should be published locally when the container is running. Defaults to [].
- {{workspaceMount}}: Overrides the default local mount point for the workspace when the container is created. Supports the same values as the Docker CLI --mount flag.
- {{runArgs}}: An array of Docker CLI arguments that should be used when running the container. Defaults to []. Allows customization for running the container.
### Dockerfile based
<xmp class=idl>
partial dictionary DevcontainerJSON {
BuildOptions build;
};
</xmp>
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.
There are multiple properties that allow users to control how docker build works:
<xmp class=idl>
dictionary BuildOptions {
required DOMString dockerfile;
DOMString context;
object args;
DOMString target;
(DOMString or sequence<DOMString>) cacheFrom;
};
</xmp>
### Docker Compose based
<xmp class=idl>
partial dictionary DevcontainerJSON {
(DOMString or sequence<DOMString>) dockerComposeFile;
DOMString service;
sequence<DOMString> runServices;
// Also has workspaceFolder just like "image" and "dockerFile"
// DOMString workspaceFolder;
};
</xmp>
Docker Compose configurations use docker-compose (which may be Docker Compose V1 or aliased Docker Compose V2) to create and manage a set of containers required for an application. As with the other configurations, any images required for this operation are assumed to be reachable. The required parameters are:
- {{dockerComposeFile}}: the reference to the Docker Compose file(s) to be used.
- {{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.
## Docker image metadata
A subset of dev container config options may be stored in the [=devcontainer.metadata=] label on the Docker image that is being used as the base image. The <dfn export>`devcontainer.metadata`</dfn> is a JSON-encoded string of the following subset of the properties configurable via [=devcontainer.json=].
<xmp class=idl>
typedef (
DevcontainerMetadataItem
or sequence<DevcontainerMetadataItem>
) DevcontainerMetadata;
dictionary DevcontainerMetadataItem {};
</xmp>
The merge logic to combine these properties with [=devcontainer-feature.json=] the
[=devcontainer.json=] is described in [[#config-merge]].
<pre class=example highlight=dockerfile>
FROM ubuntu:latest
LABEL "devcontainer.metadata"='[{ "customizations": { "vscode": { ... } } }]'
</pre>
<!--
- Passing the label as a `LABEL` instruction in the Dockerfile:
- The size limit on `Dockerfile` 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.
- 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.
- If/when this becomes an issue we could embed the metadata as a file in the image (e.g., with a label indicating it).
-->
## Merge dev container configurations ## {#config-merge}
To <dfn>merge dev container configurations</dfn>, perform the following described logic for each key to produce a single resulting object. Any properties not listed or excess properties from the source object should not be merged into the final configuration.
- {{init}}: `true` if at least one is `true`, otherwise `false`.
- {{privileged}}: `true` if at least one is `true`, otherwise `false`.
- {{capAdd}}: Union of all `capAdd` arrays without duplicates.
- {{securityOpt}}: Union of all securityOpt arrays without duplicates.
<p class=note>Check [=devcontainer.json=], [=devcontainer-feature.json=], and [=devcontainer.metadata=] if you're wondering which properties are allowed from which sources. For instance [=devcontainer.json=] may specify {{forwardPorts}}, but [=devcontainer-feature.json=] may not.</p>
<div class=example>
```json
// devcontainer.json
{
"dockerFile": "./Dockerfile",
"customizations": {
"vscode": {
"settings": {
"editor.minimap.enabled": true
}
}
}
}
```
```Dockerfile
FROM ubuntu:latest
LABEL "devcontainer.metadata"='{ "privileged": true }'
```
Merging those two dev container configuration sources will result in:
```json
{
"customizations": {
"vscode": {
"settings": {
"editor.minimap.enabled": true
}
}
},
"privileged": true
}
```
</div>
<!--
ββββββββ ββββββββ βββ ββββββββ ββ ββ ββββββββ ββββββββ ββββββ
ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ
ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ
ββββββ ββββββ ββ ββ ββ ββ ββ ββββββββ ββββββ ββββββ
ββ ββ βββββββββ ββ ββ ββ ββ ββ ββ ββ
ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ ββ
ββ ββββββββ ββ ββ ββ βββββββ ββ ββ ββββββββ ββββββ
-->
# Dev container features # {#features}
<dfn>Development container Features</dfn> 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.
<p class=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).</p>
A Feature is a self contained entity in a folder with at least a [=devcontainer-feature.json=] and `install.sh` entrypoint script. Additional files are permitted and are packaged along side the required files.
<pre class=example>
feature/
βββ devcontainer-feature.json
βββ install.sh
βββ my-file.txt
βββ hello-world.md
</pre>
## devcontainer-feature.json
The <dfn>`devcontainer-feature.json`</dfn> file defines metadata about a given Feature. All properties are optional except for `id`, `version`, and `name`.
<xmp class=idl>
dictionary DevcontainerFeatureJSON {
required DOMString id;
required DOMString version;
required DOMString name;
DOMString description;
DOMString documentationURL;
DOMString licenseURL;
sequence<DOMString> keywords;
object options;
object containerEnv;
boolean privileged;
boolean init;
sequence<DOMString> capAdd;
sequence<DOMString> securityOpt;
DOMString entrypoint;
object customizations;
sequence<DOMString> installsAfter;
sequence<DOMString> legacyIds;
boolean deprecated;
object mounts;
};
</xmp>
- {{id}}: 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}}: The semantic version of the Feature (e.g., 1.0.0).
- {{name}}: A "human-friendly" display name for the Feature.
- {{description}}: Description of the Feature.
- {{documentationURL}}: URL that points to the documentation of the Feature.
- {{licenseURL}}: URL that points to the license of the Feature.
- {{keywords}}: List of strings relevant to a user that would search for this definition/Feature.
- {{options}}: A map of options that will be passed as environment variables to the execution of the script.
- {{containerEnv}}: A set of name-value pairs that sets or overrides environment variables.
- {{privileged}}: Sets privileged mode for the container (required by things like [docker-in-docker](https://github.com/devcontainers/features/tree/main/src/docker-in-docker)) when the feature is used.
- {{init}}: Adds the tiny init process to the container (`--init`) when the Feature is used.
- {{capAdd}}: Adds container capabilities when the Feature is used.
- {{securityOpt}}: Sets container security options like updating the seccomp profile when the Feature is used.
- {{entrypoint}}: Set if the feature requires an "entrypoint" script that should fire at container startup.
- {{customizations}}: Product-specific properties, each namespace under customizations is treated as a separate set of properties. For each of these sets, the object is parsed, values are replaced while arrays are set as a union.
- {{installsAfter}}: Array of IDs of Features (omitting a version tag) that should execute before this one. Allows control for Feature authors on soft dependencies between different Features.
- {{legacyIds}}: Array of old IDs used to publish this Feature.
<p class=note>The property is useful for renaming a currently published Feature within a single namespace.</p>
- {{deprecated}}: 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}}: 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. The Pre-defined devcontainerId variable may be referenced in the value.
<pre class=example highlight=json>
{
"mounts": [
{
"source": "dind-var-lib-docker",
"target": "/var/lib/docker",
"type": "volume"
}
]
}
</pre>