You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
@@ -11,7 +16,14 @@ Once your dev container has everything it needs, you might start thinking more a
11
16
12
17
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.
13
18
14
-
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'll explore an example of a prebuilt image that [Craig](https://github.com/craiglpeters) developed for the [Kubernetes repo](https://github.com/craiglpeters/kubernetes-devcontainer).
19
+
After configuring your dev container, a great next step is to **prebuild your image**.
20
+
21
+
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.
22
+
23
+
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:
24
+
* 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)
25
+
* 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
26
+
15
27
16
28
## <ahref="#what-is-a-prebuild"name="what-is-a-prebuild"class="anchor"> What is prebuilding? </a>
17
29
@@ -25,7 +37,7 @@ You need to build your container once it has all the dependencies it needs, and
You may have heard (or will hear about) [GitHub Codespaces prebuilds](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds).
40
+
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.
29
41
30
42
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.
31
43
@@ -37,8 +49,6 @@ You can learn more about codespaces prebuilds and how to manage them in the [cod
37
49
38
50
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.
39
51
40
-
We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example throughout these steps.
41
-
42
52
**Prebuilding an image:**
43
53
* Install the [Dev Container CLI](/_implementors/reference.md):
44
54
@@ -59,49 +69,63 @@ We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-d
59
69
* Reference it in your `devcontainer.json`, Dockerfile, or Docker Compose file
60
70
* In our previous guide on ["Using Images, Dockerfiles, and Docker Compose,"](/_posts/2022-12-16-dockerfile.md) we also showed how you can use prebuilt images, Dockerfiles, or Docker Compose files for your configurations
61
71
62
-
Let's use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example for these steps:
63
-
* It's a fork of the main [Kubernetes repo](https://github.com/kubernetes/kubernetes) and contributes a prebuilt dev container for use in the Kubernetes repo
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.
75
+
76
+
**Kubernetes**
77
+
* It's a fork of the main [Kubernetes repo](https://github.com/kubernetes/kubernetes) and contributes a prebuilt dev container forusein the main Kubernetes repo or any other forks
64
78
* The dev container it's prebuilding is defined in the [.github/.devcontainer folder](https://github.com/craiglpeters/kubernetes-devcontainer/tree/master/.github/.devcontainer)
65
-
*Anytime a change is made to the dev container, the repo 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
66
-
* 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`
79
+
* 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
80
+
* 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`
67
81
* 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"`
68
82
83
+
**Dev container spec images**
84
+
* This repo prebuilds a variety of dev containers, each of which is defined in their individual folks in the [src folder](https://github.com/devcontainers/images/tree/main/src)
85
+
* As an example, the Python image is defined in the [src/python/.devcontainer](https://github.com/devcontainers/images/tree/main/src/python/.devcontainer) folder
86
+
* 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
87
+
* Using the Python image as an example again, its MCR URL is `mcr.microsoft.com/devcontainers/python`
88
+
* Any projects can now reference this prebuilt image through: `"image": "mcr.microsoft.com/devcontainers/python"`
89
+
69
90
## <a href="#where" name="where" class="anchor"> Where do the dependencies come from? </a>
70
91
71
92
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?
72
93
73
94
Let's walk through the Kubernetes prebuild as an example of how you can determine which dependencies are installed and where:
74
95
***Start at your end user dev container**
75
-
* We start at the [Kubernetes repo's `devcontainer.json`](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.devcontainer/devcontainer.json)
96
+
* We start at the [`.devcontainer/devcontainer.json`](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.devcontainer/devcontainer.json) designed forend usein the Kubernetes repo and other forks of it
76
97
* It sets a few properties, such as `hostRequirements`, `onCreateCommand`, and `otherPortsAttributes`
77
98
* 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
78
99
***Explore the dev container defining your prebuilt image**
79
-
* We next visit Craig's repo and 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)
80
-
* 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 and includes a variety of [Features](/_implementors/features.md)
100
+
* 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)
101
+
* 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.md)
81
102
***Explore content in the prebuilt dev container's config**
82
-
* Each Feature in this `devcontainer.json`defines additional functionality
103
+
* Each Feature defines additional functionality
83
104
* 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
84
105
* **Modify and rebuild as desired**
85
-
* 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 in the main Kubernetes repo), or modify the config defining the prebuilt image (i.e. the content in Craig's dev container)
86
-
* For more universal changes that anyone using the prebuilt image should get, update the config defining the prebuilt image
87
-
* For more project or user specific changes (i.e. a language I need in my project but other folks using this container won't necessarily need in theirs, or settings I prefer for my editor environment), update the end user dev container
106
+
* 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 forthe main Kubernetes repo), or modify the config defining the prebuilt image (i.e. the contentin Craig's dev container)
107
+
* For universal changes that anyone using the prebuilt image should get, update the prebuilt image
108
+
* 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
88
109
* Features are a great way to add dependencies in a clear, easily packaged way
There are a variety of benefits (some of which we've already seen) to prebuilding and using prebuilt images:
113
+
There are a variety of benefits (some of which we've already explored) to creating and using prebuilt images:
93
114
* Faster container startup
94
115
* Pull an already built dev container config rather than having to build it freshly on any new machine
95
116
* Simpler configuration
96
-
*We've seen your `devcontainer.json` can be as simple as just an `image` property
117
+
* Your `devcontainer.json` can be as simple as just an `image` property
97
118
* Pin to a specific version of tools
98
119
* This can improve supply-chain security and avoid breaks
99
120
100
121
## <a href="#tips" name="tips" class="anchor"> Tips and Tricks </a>
101
122
102
-
* 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.md#metadata-in-image-labels).
103
-
104
-
<!-- TODO: Get more from Craig during his journey -->
123
+
* 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
124
+
* The spec has a concept of Development container "Templates" which are source files packaged together that encode configuration for a complete development environment
125
+
* A Template may be as simple as a `devcontainer.json` referencing a prebuilt image, and a `devcontainer-template.json`
126
+
* You can learn more about Templates in our [Templates documentation](../_implementors/templates.md)
127
+
* 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.md)
128
+
* 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.md#metadata-in-image-labels)
105
129
106
130
## <a href="#feedback" name="feedback" class="anchor"> Feedback and Closing </a>
0 commit comments