Skip to content

Update links and headers #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions _implementors/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,24 @@ author: Microsoft
index: 2
---

# Reference Implementation
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?
## <a href="#what-is-CLI" name="what-is-CLI" class="anchor"> What is the dev container CLI? </a>
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 Remote - 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.

## How can I try it?
## <a href="#try-it" name="try-it" class="anchor"> How can I try it? </a>

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.

To install the npm package, you will need Python, Node.js (version 14 or greater), and C/C++ installed to build one of the dependencies. The VS Code [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) wiki has details about the recommended toolsets.

### npm install
### <a href="#npm-install" name="npm-install" class="anchor"> npm install </a>

```bash
npm install -g @devcontainers/cli
Expand All @@ -47,7 +46,7 @@ Options:
--version Show version number [boolean]
```

### Try out the CLI
### <a href="#try-out" name="try-out" class="anchor"> Try out the CLI </a>

Once you have the CLI, you can try it out with a sample project, like this [Rust sample](https://github.com/microsoft/vscode-remote-try-rust).

Expand Down Expand Up @@ -98,4 +97,4 @@ Hello, VS Code Remote - Containers!

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).
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).
95 changes: 56 additions & 39 deletions _implementors/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ author: Microsoft
index: 1
---

# Dev container specification

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.
Expand All @@ -18,38 +16,37 @@ Historically, dev containers have been used to enable a development workflow use

The focus of the dev container specification is to describe how to enrich a container for the purposes of development, rather than acting as a multi-container orchestrator format. Container orchestrator formats can be referenced, when needed, to manage multiple containers and the **development container** lifecycle. Today, `devcontainer.json` 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.

# Metadata
# <a href="#metadata" name="metadata" class="anchor"> Metadata </a>

**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.

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`
## <a href="#devcontainerjson" name="devcontainerjson" class="anchor"> `devcontainer.json` </a>

The current metadata schema for **development containers** is contained in a `devcontainer.json` file.

The `devcontainer.json` specification contains different configuration options related to the underlying orchestrator format. At the same time, this specification leaves space for further development and implementation of other orchestrator mechanisms and file formats.

While this metadata may be provided in different ways, when searching for a devcontainer.json file, products 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)

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.


# Configuration options
## <a href="#configuration-options" name="configuration-options" class="anchor"> Configuration options </a>

**Development containers** currently support multiple ways to specify the containers that create an environment. The following section describes the differences between them.

## Image based
## <a href="#image-based" name="image-based" class="anchor"> Image based </a>

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`. The details are [here](devcontainerjson-reference.md#image-or-dockerfile-specific-properties).
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`. The details are [here](json_reference.md#image-specific).

## Dockerfile based
## <a href="#dockerfile-based" name="dockerfile-based" class="anchor"> Dockerfile based </a>

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](devcontainerjson-reference.md#image-or-dockerfile-specific-properties).
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.md#image-specific).

There are multiple properties that allow users to control how `docker build` works:

Expand All @@ -58,7 +55,7 @@ There are multiple properties that allow users to control how `docker build` wor
- `build.target`,
- `build.cacheFrom`

## Docker Compose based
## <a href="#docker-compose-based" name="docker-compose-based" class="anchor"> Docker Compose based </a>

Docker Compose configurations use `docker-compose` 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:

Expand All @@ -69,45 +66,56 @@ It is important to remark that due to how `docker-compose` works a lot of the pr

-`runServices`: the set of services in the `docker-compose` configuration that should be started or stopped with the environment.

# Other options
# <a href="#other-options" name="other-options" class="anchor"> Other options </a>

In addition to the configuration options explained above, there are other settings that apply when creating **development containers** to facilitate their use by developers. These properties mostly apply to **image** and **Dockerfile** based configurations.

We describe the main ones below.

## Environment Variables
## <a href="#environment-variables" name="environment-variables" class="anchor"> Environment variables </a>

Environment variables can be set in containers at creation time, to override existing ones, or just to be used when a supporting tool connects to the environment.

There are two kinds of environment variables:
* Container: These variables are part of the container when it is created and are available at all points in its lifecycle.
* Remote: This variables are to be set by a **development container** supporting tool as part of its environment when it runs. These variables can change during the lifetime of the container.

## Mounts
## <a href="#mounts" name="mounts" class="anchor"> Mounts </a>

Mounts allow containers to have access to the underlying machine, share data between containers and to persist information between **development containers**.

It is important to note that these mounts are from the underlying compute environment and thus cloud environments might not have access to the same data as a local machine.

## Users
A default mount is included so that the source code is accessible from inside the container. Inside the container this mount defaults to `/workspace`.

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:
## <a href="#workspace-folder" name="workspace-folder" class="anchor"> workspaceFolder and worspaceMount </a>

The default mount point for the source code can be set with the `workspaceMount` property. 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. By default, this value mirrors `workspaceFolder`.

* Container User: The user that will be used for all operations that run inside a container. It is used to run lifecycle commands among others.
* Remote User: In case the developer wants to use different users for different purposes, the remote user is the user that connecting tools should use to execute operations inside the container.
> **Note**: It's important to note that this is not considered in the case of [Docker Compose](#docker-compose-based).

The `workspaceFolder` can then be set to a subfolder if it is desired that IDEs should open this folder by default. This value should be taken into account in all scenarios.

# Lifecycle
See [`workspaceMount` and `workspaceFolder`](json_reference.md#image-or-dockerfile-specific-properties) for reference.

## <a href="#users" name="users" class="anchor"> Users </a>

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 allows the ENTRYPOINT for the image to execute with different permissions than the developer.
* 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.

# <a href="#lifecycle" name="lifecycle" class="anchor"> Lifecycle </a>

A development environment goes through different lifecycle events during its use in the outer and inner loop of development.

- Configuration Validation.
- Environment Creation.
- Environment Stop.
- Environment Resume.
- Environment Connection.
- Configuration Validation
- Environment Creation
- Environment Stop
- Environment Resume
- Environment Connection

## Configuration Validation
## <a href="#configuration-validation" name="configuration-validation" class="anchor"> Configuration Validation </a>

This section consists of actions required to validate the `devcontainer.json` configuration and does not contain values that conflict with each other.

Expand All @@ -117,27 +125,27 @@ The tasks executed when validating the configuration are:
- Validate access to the `workspace-folder`.
- Validate that the metadata (for example `devcontainer.json`) contains all parameters required for the selected configuration type.

## Environment Creation
## <a href="#environment-creation" name="environment-creation" class="anchor"> Environment Creation </a>

The creation process goes through the steps necesarry to go from the user configuration to a working **environment** that is ready to be used.

### Initialization
### <a href="#initialization" name="initialization" class="anchor"> Initialization </a>

During this step, the following is executed:
- Validate access to the container orchestrator specified by the configuration.
- Execution of `initializeCommand`.

### Image creation
### <a href="#image-creation" name="image-creation" class="anchor"> Image Creation </a>

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:

- [Configuration Validation](#configuration-validation)
- [Configuration validation](#configuration-validation)
- Pull/build/execute of the defined container orchestration format to create images.
- Validate the result of these operations.

### Container Creation
### <a href="#container-creation" name="container-creation" class="anchor"> Container Creation </a>

After image creation, containers are created based on that image and setup.

Expand All @@ -146,15 +154,24 @@ This step executes the following:
- Create the container with the specified properties.
- Validate the container(s) were created successfully.

### Post Container Creation
### <a href="#post-container-creation" name="post-container-creation" class="anchor"> Post Container Creation </a>

- At the end of the container creation step, a set of commands are executed inside the **main** container: `on-create-command`, `update-content-command` and `post-create-command`. This set of commands is executed in sequence on a container the first time it's created and depending on the creation parameters received. You can learn more in the [documentation on lifecycle scripts](devcontainerjson-reference.md#lifecycle-scripts). By default, `post-create-command` is executed in the background after reporting the successful creation of the development environment.
- If the `wait-for` property is defined, then execution should stop at the specified property.
- At the end of the container creation step, a set of commands are executed inside the **main** container: `onCreateCommand`, `updateContentCommand` and `postCreateCommand`. This set of commands is executed in sequence on a container the first time it's created and depending on the creation parameters received. You can learn more in the [documentation on lifecycle scripts](json_reference.md#lifecycle-scripts). By default, `postCreateCommand` is executed in the background after reporting the successful creation of the development environment.
- If the `waitFor` property is defined, then execution should stop at the specified property. This property defaults to `updateContentCommand`.
- The `userEnvProbe` setting dictates whether environment variables present in a particular shell type (login, interactive, login and interactive, or an empty shell) should be passed into all post create or implementation specific commands that are executed. This allows implementors to emulate developer expected behaviors around values added to their profile and rc files. In addition, any `remoteEnv` values should also be applied to any of these commands.

## Environment Stop
## <a href="#environment-stop" name="environment-stop" class="anchor"> Environment Stop </a>

Stops all containers in the environment. The intention of this step is to ensure all containers are stopped correctly to ensure no data is lost.

## Environment Restart
## <a href="#environment-restart" name="environment-restart" class="anchor"> Environment Restart </a>

After an environment has been stopped, the containers are restarted according to the orchestrator defined. Additionally, `postStartCommand` is executed in the **main** container.

# <a href="#implementation-specific-steps" name="implementation-specific-steps" class="anchor"> Implementation specific steps </a>

## <a href="#post-creation" name="post-creation" class="anchor"> Post creation </a>

After the all the steps executed in a succesful creation or restart, any implementation specific commands can safely execute. These specific implementations should take into account the `userEnvProbe` and `remoteEnv` properties.

After an environment has been stopped, the containers are restarted according to the orchestrator defined. Additionally, `post-start-command` is executed in the **main** container.
For example, in the CLI reference implementation, this is the point in which anything executed with `devcontainer exec` would run.
2 changes: 2 additions & 0 deletions supporting.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ A [codespace](https://docs.github.com/en/codespaces/overview) is a development e

> **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.

#### <a href="#codespaces-specific-properties" name="codespaces-specific-properties" class="anchor"> Product specific properties </a>
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).

Expand Down