Skip to content

Commit 2b3aa26

Browse files
author
bamurtaugh
committed
Content and wording
1 parent 648aed6 commit 2b3aa26

File tree

1 file changed

+46
-22
lines changed

1 file changed

+46
-22
lines changed

_posts/2023-08-22-prebuild.md

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
---
22
layout: post
33
title: "Speed Up Your Workflow with Prebuilds"
4-
author: "@bamurtaugh"
5-
authorUrl: https://github.com/bamurtaugh
4+
authors:
5+
- "@bamurtaugh"
6+
- "@craiglpeters"
7+
authorUrls:
8+
- "https://github.com/bamurtaugh"
9+
- "https://github.com/craiglpeters"
10+
611
---
712

813
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
1116

1217
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.
1318

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+
1527

1628
## <a href="#what-is-a-prebuild" name="what-is-a-prebuild" class="anchor"> What is prebuilding? </a>
1729

@@ -25,7 +37,7 @@ You need to build your container once it has all the dependencies it needs, and
2537
2638
### <a href="#prebuilt-codespaces" name="prebuilt-codespaces" class="anchor"> Prebuilt Codespaces </a>
2739

28-
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.
2941

3042
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.
3143

@@ -37,8 +49,6 @@ You can learn more about codespaces prebuilds and how to manage them in the [cod
3749

3850
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.
3951

40-
We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example throughout these steps.
41-
4252
**Prebuilding an image:**
4353
* Install the [Dev Container CLI](/_implementors/reference.md):
4454

@@ -59,49 +69,63 @@ We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-d
5969
* Reference it in your `devcontainer.json`, Dockerfile, or Docker Compose file
6070
* 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
6171
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
72+
### <a href="#prebuild-examples" name="prebuild-examples" class="anchor"> Prebuild Examples </a>
73+
74+
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 for use in the main Kubernetes repo or any other forks
6478
* 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`
6781
* 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"`
6882
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+
6990
## <a href="#where" name="where" class="anchor"> Where do the dependencies come from? </a>
7091
7192
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?
7293
7394
Let's walk through the Kubernetes prebuild as an example of how you can determine which dependencies are installed and where:
7495
* **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 for end use in the Kubernetes repo and other forks of it
7697
* It sets a few properties, such as `hostRequirements`, `onCreateCommand`, and `otherPortsAttributes`
7798
* 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
7899
* **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)
81102
* **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
83104
* 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
84105
* **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 for the main Kubernetes repo), or modify the config defining the prebuilt image (i.e. the content in 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
88109
* Features are a great way to add dependencies in a clear, easily packaged way
89110

90111
## <a href="#benefits" name="benefits" class="anchor"> Benefits </a>
91112

92-
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:
93114
* Faster container startup
94115
* Pull an already built dev container config rather than having to build it freshly on any new machine
95116
* 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
97118
* Pin to a specific version of tools
98119
* This can improve supply-chain security and avoid breaks
99120
100121
## <a href="#tips" name="tips" class="anchor"> Tips and Tricks </a>
101122
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)
105129

106130
## <a href="#feedback" name="feedback" class="anchor"> Feedback and Closing </a>
107131

0 commit comments

Comments
 (0)