Skip to content
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

Feature build performance #21

Open
chrmarti opened this issue Mar 24, 2022 · 4 comments
Open

Feature build performance #21

chrmarti opened this issue Mar 24, 2022 · 4 comments
Labels
proposal Still under discussion, collecting feedback

Comments

@chrmarti
Copy link
Contributor

chrmarti commented Mar 24, 2022

This proposal is an enhancement idea to the current dev container features proposal.


Currently features are built in a single layer of the image, so when a feature is added, removed or its options are modified, all features need to be rebuilt.

Building each feature in a separate layer would partially improve the use of the layer cache, but when the user changes a feature, that would still trigger a rebuild of all the feature layers coming after that.

A more promising approach is to use a multi-stage build and build each feature in a separate stage. One additional advantage is that these stages can be built in parallel. The challenge with it is that a feature needs to build its 'layer' in a separate folder, so in the last build stage we can copy all these feature layers (folders) from the different feature stages. Not all features might be simple to implement in this way, but we can keep supporting the existing way of building features while we work on updating popular features to the new model.

A feature would come with a set of scripts that are run in the following order:

  • validate-prereqs: Runs as root in a separate build stage using a "build image".
    • This can install build time dependencies.
  • acquire: Runs as regular user after validate-prereqs in the build image.
    • This needs to copy the result to a 'layer' folder that is self-contained in that it can be copied to a different image and run there.
  • configure: Runs as root in the final image build after the 'layer' from acquire is copied over. Based on a "run image".
    • This can run additional configuration or even installation steps. This will run on each rebuild, so doing less here is better.

A new-style feature could omit the configure and validate-prereqs scripts if it doesn't need them. Old-style features could come only with a configure script.

The build image and the run image must be binary compatible in that binaries built for the build image must be able to run in the run image. (E.g., Debian/Ubuntu vs. Alpine. x64 vs. ARM.)

On dependencies: Plain runtime dependencies between features don't affect this approach. When there are build-time dependencies between features, we can declare these on the feature (separate to runtime dependencies) and let the depending feature's stage run with the layer from its dependencies copied in. (This will reduce parallelization of building stages. Unclear if build-time dependencies are common.)

@chrmarti chrmarti added the proposal Still under discussion, collecting feedback label Mar 24, 2022
@jsma
Copy link

jsma commented Apr 1, 2022

Apologies if this is the wrong place to ask, but would the proposal above address the fact that running devcontainer build followed by devcontainer open opens VS Code but then in the output one of the first things it does is start building stuff again?

[1690 ms] Start: Run: docker events --format {{json .}} --filter event=start
[1692 ms] Start: Run: docker-compose --project-name myproject -f /Users/username/Projects/myproject/docker-compose.yml build

It makes for a very slow startup experience since I cannot interact with the editor until the build completes. What is also non-intuitive for me is that even though it rebuilds after opening the dev container, I am sometimes still prompted that e.g. docker-compose.yml has changed and may need to be rebuilt. How many times does it need to build before VS Code is content that everything is in working shape and can let me get to work?

@chrmarti
Copy link
Contributor Author

chrmarti commented Apr 4, 2022

@jsma This is a separate issue. I have copied your description to microsoft/vscode-remote-release#6558. Thanks.

@Chuxel
Copy link
Member

Chuxel commented Apr 5, 2022

@jsma Do you have a feature entry in your devcontainer.json?

If so @chrmarti this may also be a cleanup task for dev container features related to #8 and #18. Right now you need to list features even with a pre-created image because otherwise the config and entrypoints won't fire, but unfortunately right now, the build still executes. We've got code to trap the build and not do it a second time for our features - but you still end up going through a docker build process.

@jsma
Copy link

jsma commented Apr 6, 2022

@Chuxel, the short answer is: yes, I did have a features entry in devcontainer.json. I added details in the other issue to avoid polluting this thread further with my tales of woe ;) Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal Still under discussion, collecting feedback
Projects
None yet
Development

No branches or pull requests

3 participants