From 6a5bf4615f706a0f96a10c6497c317e7f2f19aa5 Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Fri, 11 Aug 2023 20:16:20 +0000 Subject: [PATCH 01/10] Scaffold post, enable multiple authors --- _layouts/post.html | 11 ++++++++++- _posts/2023-08-22-prebuild.md | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 _posts/2023-08-22-prebuild.md diff --git a/_layouts/post.html b/_layouts/post.html index 3bf16631..a8fc1ae2 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -2,7 +2,16 @@ layout: singlePage ---
-

{{ page.date | date_to_string }} - {{ page.author }}

+

{{ page.date | date_to_string }} - + {% if page.authors.size == 1 %} + {{ page.author }} + {% else %} + Authors: + {% for author in page.authors %} + {{ author.name }}{% unless forloop.last %}, {% endunless %} + {% endfor %} + {% endif %} +

{{ content }}
\ No newline at end of file diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md new file mode 100644 index 00000000..12e14250 --- /dev/null +++ b/_posts/2023-08-22-prebuild.md @@ -0,0 +1,12 @@ +--- +layout: post +title: "Speed Up Your Workflow with Prebuilds" +authors: + - "@bamurtaugh" + - "@craiglpeters" +authorUrls: + - "https://github.com/bamurtaugh" + - "https://github.com/craiglpeters" +--- + +## What is a prebuild? \ No newline at end of file From 083d5d334ec0107c891f854ae259d6fe3bb95d7d Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Fri, 11 Aug 2023 21:46:32 +0000 Subject: [PATCH 02/10] Add initial content --- _posts/2023-08-22-prebuild.md | 73 ++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index 12e14250..ae89bcf2 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -9,4 +9,75 @@ authorUrls: - "https://github.com/craiglpeters" --- -## What is a prebuild? \ No newline at end of file +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. + +Once your dev container has everything it needs, you might start thinking more about ways to optimize it. For instance, it might take a while to build. Maybe it takes 5 minutes. Maybe it takes an hour! + +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. + +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 use a real example of a prebuilt image that [Craig](https://github.com/craiglpeters) developed for the [Kubernetes repo](https://github.com/craiglpeters/kubernetes-devcontainer). + +## What is prebuilding? + +We should first define: What is prebuilding? + +If you're already using dev containers, you're likely already familiar with the idea of building a container, where you package everything your app needs to run into a single unit. + +You'll need to build your container once it has all the dependencies it needs, and then you can continue using it. Since you may not need to rebuild often, it might be alright if it takes a while for that initial build. But if you or your teammates need to use that container on another machine, you'll need to wait for it to build it again in those new environments. + +> **Note:** The [dev container CLI doc](/_implementors/reference.md#prebuilding) is another great resource on prebuilding. + +### Prebuilt Codespaces + +You may have heard (or will hear about) GitHub Codespaces prebuilds. + +// TODO: More info + +## How do I prebuild my image? + +We try to make prebuilding an image and using a prebuilt image as easy as possible. + +**Prebuilding an image:** +* Install the [Dev Container CLI](/_implementors/reference.md): + + ```bash + npm install -g @devcontainers/cli + ``` + +* Build your image and push it to a container registry (like the [Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-docker-cli?tabs=azure-cli), [GitHub Container Registry](https://docs.github.com/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images), or [Docker Hub](https://docs.docker.com/engine/reference/commandline/push)): + + ```bash + devcontainer build --workspace-folder . --push true --image-name : + ``` + +* You can automate pre-building your image by scheduling the build using a DevOps or continuous integration (CI) service like GitHub Actions. We've created a [GitHub Action](https://github.com/marketplace/actions/devcontainers-ci) and [Azure DevOps task](https://marketplace.visualstudio.com/items?itemName=devcontainers.ci) to help with this. + +**Using a prebuilt image:** +* Determine the published URL of the prebuilt image you want to use +* Reference it in your devcontainer.json, Dockerfile, or Docker Compose file + +**Note:** 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. + +## Example + +Let's use Craig's Kubernetes dev container as an example. + +**Prebuilding the image:** +// TODO + +**Using the prebuilt image:** +// TODO + +### Metadata in image labels + +// TODO - bring over info from other doc + +## Tips and Tricks + +// TODO: Get these from Craig during his journey + +## Feedback and Closing + +We hope these tips will help you optimize your dev container workflows! We can't wait to hear your tips, tricks, and feedback. How are you prebuilding your images? Would anything make the process easier for you? + +If you haven't already, we recommend joining our dev container [community Slack channel](https://aka.ms/dev-container-community) where you can connect with the dev container spec maintainers and community at large. If you have any feature requests or experience any issues as you use any of the above tools, please feel free to also open an issue in the corresponding repo in the [dev containers org](https://github.com/devcontainers) on GitHub. \ No newline at end of file From b05f9bc69fdcda51d9ee6b854d246e2df8c107ac Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Mon, 14 Aug 2023 16:07:46 -0700 Subject: [PATCH 03/10] Guide content updates --- _posts/2023-08-22-prebuild.md | 79 ++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index ae89bcf2..4d57ef4f 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -15,7 +15,7 @@ Once your dev container has everything it needs, you might start thinking more a 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. -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 use a real example of a prebuilt image that [Craig](https://github.com/craiglpeters) developed for the [Kubernetes repo](https://github.com/craiglpeters/kubernetes-devcontainer). +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). ## What is prebuilding? @@ -23,19 +23,25 @@ We should first define: What is prebuilding? If you're already using dev containers, you're likely already familiar with the idea of building a container, where you package everything your app needs to run into a single unit. -You'll need to build your container once it has all the dependencies it needs, and then you can continue using it. Since you may not need to rebuild often, it might be alright if it takes a while for that initial build. But if you or your teammates need to use that container on another machine, you'll need to wait for it to build it again in those new environments. +You need to build your container once it has all the dependencies it needs, and rebuild anytime you add new dependencies. Since you may not need to rebuild often, it might be alright if it takes a while for that initial build. But if you or your teammates need to use that container on another machine, you'll need to wait for it to build it again in those new environments. > **Note:** The [dev container CLI doc](/_implementors/reference.md#prebuilding) is another great resource on prebuilding. ### Prebuilt Codespaces -You may have heard (or will hear about) GitHub Codespaces prebuilds. +You may have heard (or will hear about) [GitHub Codespaces prebuilds](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds). -// TODO: More info +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. + +By default, whenever you push changes to your repository, GitHub Codespaces uses GitHub Actions to automatically update your prebuilds. + +You can learn more about codespaces prebuilds and how to manage them in the [codespaces docs]((https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds)). ## How do I prebuild my image? -We try to make prebuilding an image and using a prebuilt image as easy as possible. +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. + +We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example throughout these steps. **Prebuilding an image:** * Install the [Dev Container CLI](/_implementors/reference.md): @@ -54,30 +60,53 @@ We try to make prebuilding an image and using a prebuilt image as easy as possib **Using a prebuilt image:** * Determine the published URL of the prebuilt image you want to use -* Reference it in your devcontainer.json, Dockerfile, or Docker Compose file - -**Note:** 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. - -## Example - -Let's use Craig's Kubernetes dev container as an example. - -**Prebuilding the image:** -// TODO - -**Using the prebuilt image:** -// TODO - -### Metadata in image labels - -// TODO - bring over info from other doc +* Reference it in your `devcontainer.json`, Dockerfile, or Docker Compose file + * 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 + +Let's use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example for these steps: +* 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 +* The dev container it's prebuilding is defined in the [.github/.devcontainer folder](https://github.com/craiglpeters/kubernetes-devcontainer/tree/master/.github/.devcontainer) +* 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 +* 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` +* 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"` + +## Where do the dependencies come from? + +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? + +Let's walk through the Kubernetes prebuild as an example of how you can determine which dependencies are installed and where: +* **Start at your end user dev container** + * We start at the [Kubernetes repo's `devcontainer.json`](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.devcontainer/devcontainer.json) + * It sets a few properties, such as `hostRequirements`, `onCreateCommand`, and `otherPortsAttributes` + * 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 +* **Explore the dev container defining your prebuilt image** + * 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) + * 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) +* **Explore content in the prebuilt dev container's config** + * Each Feature in this `devcontainer.json` defines additional functionality + * 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 +* **Modify and rebuild as desired** + * 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) + * Features are a great way to add dependencies in a clear, easily packaged way + +## Benefits + +There are a variety of benefits (some of which we've already seen) to prebuilding and using prebuilt images: +* Faster container startup + * Pull an already built dev container config rather than having to build it freshly on any new machine +* Simpler configuration + * We've seen your `devcontainer.json` can be as simple as just an `image` property +* Pin to a specific version of tools + * This can improve supply-chain security and avoid breaks ## Tips and Tricks -// TODO: Get these from Craig during his journey +* 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). + + ## Feedback and Closing -We hope these tips will help you optimize your dev container workflows! We can't wait to hear your tips, tricks, and feedback. How are you prebuilding your images? Would anything make the process easier for you? +We hope this guide will help you optimize your dev container workflows! We can't wait to hear your tips, tricks, and feedback. How are you prebuilding your images? Would anything in the spec or tooling make the process easier for you? -If you haven't already, we recommend joining our dev container [community Slack channel](https://aka.ms/dev-container-community) where you can connect with the dev container spec maintainers and community at large. If you have any feature requests or experience any issues as you use any of the above tools, please feel free to also open an issue in the corresponding repo in the [dev containers org](https://github.com/devcontainers) on GitHub. \ No newline at end of file +If you haven't already, we recommend joining our dev container [community Slack channel](https://aka.ms/dev-container-community) where you can connect with the dev container spec maintainers and community at large. If you have any feature requests or experience any issues as you use the above tools, please feel free to also open an issue in the corresponding repo in the [dev containers org](https://github.com/devcontainers) on GitHub. \ No newline at end of file From 648aed63beae416bf5248e1437e1e72b766ea699 Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Mon, 28 Aug 2023 11:59:41 -0700 Subject: [PATCH 04/10] Feedback --- _posts/2023-08-22-prebuild.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index 4d57ef4f..68e981b0 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -1,12 +1,8 @@ --- layout: post title: "Speed Up Your Workflow with Prebuilds" -authors: - - "@bamurtaugh" - - "@craiglpeters" -authorUrls: - - "https://github.com/bamurtaugh" - - "https://github.com/craiglpeters" +author: "@bamurtaugh" +authorUrl: https://github.com/bamurtaugh --- 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. @@ -23,7 +19,7 @@ We should first define: What is prebuilding? If you're already using dev containers, you're likely already familiar with the idea of building a container, where you package everything your app needs to run into a single unit. -You need to build your container once it has all the dependencies it needs, and rebuild anytime you add new dependencies. Since you may not need to rebuild often, it might be alright if it takes a while for that initial build. But if you or your teammates need to use that container on another machine, you'll need to wait for it to build it again in those new environments. +You need to build your container once it has all the dependencies it needs, and rebuild anytime you add new dependencies. Since you may not need to rebuild often, it might be alright if it takes a while for that initial build. But if you or your teammates need to use that container on another machine, you'll need to wait for it to build again in those new environments. > **Note:** The [dev container CLI doc](/_implementors/reference.md#prebuilding) is another great resource on prebuilding. @@ -87,6 +83,8 @@ Let's walk through the Kubernetes prebuild as an example of how you can determin * 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 * **Modify and rebuild as desired** * 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) + * For more universal changes that anyone using the prebuilt image should get, update the config defining the prebuilt image + * 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 * Features are a great way to add dependencies in a clear, easily packaged way ## Benefits From 2b3aa269b79f745ee6ba30e0a2d087c6216ee9a5 Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Mon, 28 Aug 2023 13:21:54 -0700 Subject: [PATCH 05/10] Content and wording --- _posts/2023-08-22-prebuild.md | 68 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index 68e981b0..e69a3a4d 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -1,8 +1,13 @@ --- layout: post title: "Speed Up Your Workflow with Prebuilds" -author: "@bamurtaugh" -authorUrl: https://github.com/bamurtaugh +authors: + - "@bamurtaugh" + - "@craiglpeters" +authorUrls: + - "https://github.com/bamurtaugh" + - "https://github.com/craiglpeters" + --- 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 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. -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). +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 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: +* 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) +* 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 + ## What is prebuilding? @@ -25,7 +37,7 @@ You need to build your container once it has all the dependencies it needs, and ### Prebuilt Codespaces -You may have heard (or will hear about) [GitHub Codespaces prebuilds](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds). +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. 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. @@ -37,8 +49,6 @@ You can learn more about codespaces prebuilds and how to manage them in the [cod 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. -We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example throughout these steps. - **Prebuilding an image:** * Install the [Dev Container CLI](/_implementors/reference.md): @@ -59,49 +69,63 @@ We'll use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-d * Reference it in your `devcontainer.json`, Dockerfile, or Docker Compose file * 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 -Let's use the [Kubernetes prebuild](https://github.com/craiglpeters/kubernetes-devcontainer) mentioned above as an example for these steps: -* 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 +### Prebuild Examples + +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. + +**Kubernetes** +* 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 * The dev container it's prebuilding is defined in the [.github/.devcontainer folder](https://github.com/craiglpeters/kubernetes-devcontainer/tree/master/.github/.devcontainer) -* 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 -* 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` +* 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 + * 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` * 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"` +**Dev container spec images** +* 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) + * As an example, the Python image is defined in the [src/python/.devcontainer](https://github.com/devcontainers/images/tree/main/src/python/.devcontainer) folder +* 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 + * Using the Python image as an example again, its MCR URL is `mcr.microsoft.com/devcontainers/python` +* Any projects can now reference this prebuilt image through: `"image": "mcr.microsoft.com/devcontainers/python"` + ## Where do the dependencies come from? 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? Let's walk through the Kubernetes prebuild as an example of how you can determine which dependencies are installed and where: * **Start at your end user dev container** - * We start at the [Kubernetes repo's `devcontainer.json`](https://github.com/craiglpeters/kubernetes-devcontainer/blob/master/.devcontainer/devcontainer.json) + * 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 * It sets a few properties, such as `hostRequirements`, `onCreateCommand`, and `otherPortsAttributes` * 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 * **Explore the dev container defining your prebuilt image** - * 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) - * 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) + * 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) + * 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) * **Explore content in the prebuilt dev container's config** - * Each Feature in this `devcontainer.json` defines additional functionality + * Each Feature defines additional functionality * 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 * **Modify and rebuild as desired** - * 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) - * For more universal changes that anyone using the prebuilt image should get, update the config defining the prebuilt image - * 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 + * 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) + * For universal changes that anyone using the prebuilt image should get, update the prebuilt image + * 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 * Features are a great way to add dependencies in a clear, easily packaged way ## Benefits -There are a variety of benefits (some of which we've already seen) to prebuilding and using prebuilt images: +There are a variety of benefits (some of which we've already explored) to creating and using prebuilt images: * Faster container startup * Pull an already built dev container config rather than having to build it freshly on any new machine * Simpler configuration - * We've seen your `devcontainer.json` can be as simple as just an `image` property + * Your `devcontainer.json` can be as simple as just an `image` property * Pin to a specific version of tools * This can improve supply-chain security and avoid breaks ## Tips and Tricks -* 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). - - +* 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 +* The spec has a concept of Development container "Templates" which are source files packaged together that encode configuration for a complete development environment + * A Template may be as simple as a `devcontainer.json` referencing a prebuilt image, and a `devcontainer-template.json` + * You can learn more about Templates in our [Templates documentation](../_implementors/templates.md) + * 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) +* 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) ## Feedback and Closing From 4dd115e46e615b55915c51c808c7d5e3d3f796c3 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Mon, 28 Aug 2023 21:26:32 +0000 Subject: [PATCH 06/10] fix displaying author(s) --- _layouts/post.html | 15 ++++++--------- _posts/2022-11-01-author-a-feature.md | 6 ++++-- _posts/2022-12-16-dockerfile.md | 6 ++++-- _posts/2023-02-15-gitlab-ci.md | 6 ++++-- ...2023-06-14-feature-authoring-best-practices.md | 6 ++++-- _posts/2023-08-22-prebuild.md | 4 ++-- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/_layouts/post.html b/_layouts/post.html index a8fc1ae2..06a0a3dd 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -2,16 +2,13 @@ layout: singlePage ---
-

{{ page.date | date_to_string }} - - {% if page.authors.size == 1 %} - {{ page.author }} - {% else %} - Authors: - {% for author in page.authors %} - {{ author.name }}{% unless forloop.last %}, {% endunless %} +

{{ page.date | date_to_string }} - + {% assign i = 0 %} + {% for a in page.author %} + {{ page.author[i] }} + {% assign i = i | plus:1 %} {% endfor %} - {% endif %}

{{ content }} -
\ No newline at end of file + diff --git a/_posts/2022-11-01-author-a-feature.md b/_posts/2022-11-01-author-a-feature.md index 8f72734a..ab7a0139 100644 --- a/_posts/2022-11-01-author-a-feature.md +++ b/_posts/2022-11-01-author-a-feature.md @@ -1,8 +1,10 @@ --- layout: post title: "Authoring a Dev Container Feature" -author: "@joshspicer" -authorUrl: https://github.com/joshspicer +author: + - "@joshspicer" +authorUrl: + - https://github.com/joshspicer --- Development container ["Features"](/features) are self-contained, shareable units of installation code and development container configuration. We [define a pattern](/implementors/features-distribution) for authoring and self-publishing Features. diff --git a/_posts/2022-12-16-dockerfile.md b/_posts/2022-12-16-dockerfile.md index 14f8c6b0..0881c010 100644 --- a/_posts/2022-12-16-dockerfile.md +++ b/_posts/2022-12-16-dockerfile.md @@ -1,8 +1,10 @@ --- layout: post title: "Using Images, Dockerfiles, and Docker Compose" -author: "@chuxel" -authorUrl: https://github.com/chuxel +author: + - "@chuxel" +authorUrl: + - https://github.com/chuxel --- When creating a development container, you have a variety of different ways to customize your environment like ["Features"](/features) or [lifecycle scripts](/implementors/json_reference/#lifecycle-scripts). However, if you are familiar with containers, you may want to use a [Dockerfile](/guide/dockerfile#dockerfile) or [Docker Compose / Compose](/guide/dockerfile#docker-compose) to customize your environment. This article will walk through how to use these formats with the Dev Container spec. diff --git a/_posts/2023-02-15-gitlab-ci.md b/_posts/2023-02-15-gitlab-ci.md index 85104558..63d3b5d0 100644 --- a/_posts/2023-02-15-gitlab-ci.md +++ b/_posts/2023-02-15-gitlab-ci.md @@ -1,8 +1,10 @@ --- layout: post title: "Working with GitLab CI" -author: "@raginjason" -authorUrl: https://github.com/raginjason +author: + - "@raginjason" +authorUrl: + - https://github.com/raginjason --- For simple use cases you can use your development container (dev container) for CI without much issue. Once you begin using more advanced dev container functionality such as [Features](/features), you will need dev container tooling in your CI pipeline. While GitHub CI has the [devcontainers-ci GitHub Action](https://github.com/marketplace/actions/devcontainers-ci), there is no such analog in GitLab CI. To achieve the goal of using your dev container in GitLab CI, the container must be pre-built. diff --git a/_posts/2023-06-14-feature-authoring-best-practices.md b/_posts/2023-06-14-feature-authoring-best-practices.md index 2bf5a1cd..adca4d49 100644 --- a/_posts/2023-06-14-feature-authoring-best-practices.md +++ b/_posts/2023-06-14-feature-authoring-best-practices.md @@ -1,8 +1,10 @@ --- layout: post title: "Best Practices: Authoring a Dev Container Feature" -author: "@joshspicer" -authorUrl: https://github.com/joshspicer +author: + - "@joshspicer" +authorUrl: + - https://github.com/joshspicer --- Last November I wrote about the basics around [authoring a Dev Container Feature](/guide/author-a-feature). Since then, [hundreds](https://containers.dev/features) of Features have been written by the community. The flexibility of Features has enabled a wide variety of use cases, from installing a single tool to setting up specific aspects of a project's development environment that can be shared across repositories. To that effect, many different patterns for Feature authorship have emerged, and the core team has learned a lot about what works well and what doesn't. diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index e69a3a4d..22fb9847 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -1,10 +1,10 @@ --- layout: post title: "Speed Up Your Workflow with Prebuilds" -authors: +author: - "@bamurtaugh" - "@craiglpeters" -authorUrls: +authorUrl: - "https://github.com/bamurtaugh" - "https://github.com/craiglpeters" From 3b0b9af14fc4380a56931e01bafe72a7efad071d Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Mon, 28 Aug 2023 14:53:31 -0700 Subject: [PATCH 07/10] Typo --- _posts/2023-08-22-prebuild.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index 22fb9847..f203b942 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -81,7 +81,7 @@ As mentioned above, let's walk through a couple examples of these steps, one usi * 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"` **Dev container spec images** -* 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) +* This repo prebuilds a variety of dev containers, each of which is defined in their individual folders in the [src folder](https://github.com/devcontainers/images/tree/main/src) * As an example, the Python image is defined in the [src/python/.devcontainer](https://github.com/devcontainers/images/tree/main/src/python/.devcontainer) folder * 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 * Using the Python image as an example again, its MCR URL is `mcr.microsoft.com/devcontainers/python` From 630fa7fc7aa9d2440fd5c0f9670a3e8ab7a51574 Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Wed, 30 Aug 2023 11:03:43 -0700 Subject: [PATCH 08/10] Link between guides --- _posts/2022-12-16-dockerfile.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/2022-12-16-dockerfile.md b/_posts/2022-12-16-dockerfile.md index 0881c010..daa8a800 100644 --- a/_posts/2022-12-16-dockerfile.md +++ b/_posts/2022-12-16-dockerfile.md @@ -46,7 +46,7 @@ That's it! When you start up your Dev Container, the Dockerfile will be automati Better yet, you can can use a Dockerfile as a part of authoring an image you can share with others. You can even **add Dev Container settings and metadata right into the image itself**. This avoids having to duplicate config and settings in multiple devcontainer.json files and keeps them in sync with your images! -See the reference on **[pre-building](/implementors/reference/#prebuilding)** to learn more! +See the guiide on **[pre-building](/_posts/2023-08-22-prebuild.md)** to learn more! ## Using Docker Compose @@ -142,4 +142,4 @@ volumes: Finally, as in the Dockerfile example, you can use this same setup to create a Dev Container image that you can share with others. You can also add Dev Container settings and metadata right into the image itself. -See the reference on **[pre-building](/implementors/reference/#prebuilding)** to learn more! \ No newline at end of file +See the guide on **[pre-building](/_posts/2023-08-22-prebuild.md)** to learn more! \ No newline at end of file From b6c8f87a51f12d24148cf67aeace58cda83ad7fe Mon Sep 17 00:00:00 2001 From: bamurtaugh Date: Wed, 30 Aug 2023 11:10:15 -0700 Subject: [PATCH 09/10] Feedback --- _posts/2023-08-22-prebuild.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_posts/2023-08-22-prebuild.md b/_posts/2023-08-22-prebuild.md index f203b942..ad7b5159 100644 --- a/_posts/2023-08-22-prebuild.md +++ b/_posts/2023-08-22-prebuild.md @@ -126,6 +126,10 @@ There are a variety of benefits (some of which we've already explored) to creati * You can learn more about Templates in our [Templates documentation](../_implementors/templates.md) * 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) * 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) +* You can use multi-stage Dockerfiles to create a prod container from your dev container + * You'd typically stat with your prod image, then add to it + * Features provide a quick way to add development and CI specific layers that you wouldn't use in production + * For more information and an example, check out our [discussion on multi-stage builds](https://github.com/orgs/devcontainers/discussions/4#discussioncomment-4152158) ## Feedback and Closing From 866fe0c62accc6cbdf55e13513e80c4512108135 Mon Sep 17 00:00:00 2001 From: Brigit Murtaugh Date: Thu, 31 Aug 2023 16:35:50 -0700 Subject: [PATCH 10/10] Typo --- _posts/2022-12-16-dockerfile.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/2022-12-16-dockerfile.md b/_posts/2022-12-16-dockerfile.md index daa8a800..f6e8cc1d 100644 --- a/_posts/2022-12-16-dockerfile.md +++ b/_posts/2022-12-16-dockerfile.md @@ -46,7 +46,7 @@ That's it! When you start up your Dev Container, the Dockerfile will be automati Better yet, you can can use a Dockerfile as a part of authoring an image you can share with others. You can even **add Dev Container settings and metadata right into the image itself**. This avoids having to duplicate config and settings in multiple devcontainer.json files and keeps them in sync with your images! -See the guiide on **[pre-building](/_posts/2023-08-22-prebuild.md)** to learn more! +See the guide on **[pre-building](/_posts/2023-08-22-prebuild.md)** to learn more! ## Using Docker Compose @@ -142,4 +142,4 @@ volumes: Finally, as in the Dockerfile example, you can use this same setup to create a Dev Container image that you can share with others. You can also add Dev Container settings and metadata right into the image itself. -See the guide on **[pre-building](/_posts/2023-08-22-prebuild.md)** to learn more! \ No newline at end of file +See the guide on **[pre-building](/_posts/2023-08-22-prebuild.md)** to learn more!