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

Decide whether to base the devcontainer on mcr.microsoft.com/devcontainers/python #208

Open
coretl opened this issue Oct 30, 2024 · 22 comments

Comments

@coretl
Copy link
Contributor

coretl commented Oct 30, 2024

See https://github.com/devcontainers/images/tree/main/src/python

Pros:

  • Already has zsh so should be a lot quicker to start a new devcontainer (with common-utils feature) - needs testing
  • Contains additional tools like pipx

Cons:

  • More change
  • Another tie into Microsoft ecosystem

@callumforrester @garryod thoughts?

@garryod
Copy link
Member

garryod commented Oct 30, 2024

Don't think the tie in would be too strong, but generally prefer composition (features) instead of a monolithic base container. Then again, features can be rather slow

@callumforrester
Copy link
Contributor

I agree with @garryod on tie in. The slowness of features has definitely reduces adoption in DAQ so it is something we're looking to do something about.

An alternative might be to build our own base image out of precisely the features we want and use that?

@coretl
Copy link
Contributor Author

coretl commented Oct 30, 2024

I think the microsoft one is precisely that, base python image with common-utils in it...

@coretl
Copy link
Contributor Author

coretl commented Nov 5, 2024

Benchmarking the existing container with just dev dependencies (python-copier-template-example):

  • From "rebuild container without cache" to venv installed: 1m59s
  • From "rebuild container" to venv installed: 1m19s

If we remove `common-utils":

  • From "rebuild container without cache" to venv installed: 1m06s
  • From "rebuild container" to venv installed: 36s
  • But no zsh

If we switch to mcr.microsoft.com/devcontainers/python:

@coretl
Copy link
Contributor Author

coretl commented Nov 5, 2024

Also, most of the warm cache time is taken with 25s of pip install. This drops to 5s if we use uv pip install instead...

@gilesknap
Copy link
Contributor

gilesknap commented Nov 5, 2024

I think common utils is giving more than just zsh. Maybe.

  • Do you get your ssh keys and github access inside the container without them?
  • Also X11 forwarding may or may not work without common utils
  • what about other git global config ?

We used to have manual workarounds for the above but I prefer the native MS approach if possible.

@gilesknap
Copy link
Contributor

gilesknap commented Nov 5, 2024

I think common utils is giving more than just zsh. Maybe.

  • Do you get your ssh keys and github access inside the container without them?
  • Also X11 forwarding may or may not work without common utils
  • what about other git global config ?

We used to have manual workarounds for the above but I prefer the native MS approach if possible.

Above is not true as I tried it here https://github.com/gilesknap/docker-outside-docker/tree/no-common-utils.

If you do not use MS base image and remove common-utils feature you need only add an install of git and all of the above still work. So zsh is all you miss out on as far as I can tell. But I do like zsh these days.

@coretl
Copy link
Contributor Author

coretl commented Nov 6, 2024

One thing that helps massively is going back to how it was originally, removing the feature, and installing it manually in the Dockerfile:

RUN git clone https://github.com/devcontainers/features --depth=1 && USERNAME=none bash features/src/common-utils/install.sh

This means that it gets cached rather than being run each time.

  • From "rebuild container without cache" to venv installed: 1m36s
  • From "rebuild container" to venv installed: 35s

If we switch to uv too then then we can shave another 20s off this
The git clone is a hack, we should really be extracting from the OCI artifact at ghcr.io/devcontainers/features/common-utils:2, but I have no idea how to do that!
@garryod any ideas?

@garryod
Copy link
Member

garryod commented Nov 6, 2024

If we switch to uv too then then we can shave another 20s off this
The git clone is a hack, we should really be extracting from the OCI artifact at ghcr.io/devcontainers/features/common-utils:2, but I have no idea how to do that!
@garryod any ideas?

Not sure of the exact format of their OCI artifacts, but I expect oras pull is likely what you're after

@callumforrester
Copy link
Contributor

One thing that helps massively is going back to how it was originally, removing the feature, and installing it manually in the Dockerfile:

@coretl would it be even faster if we did that and prebuilt it remotely and pulled from Github?

@coretl
Copy link
Contributor Author

coretl commented Nov 8, 2024

I would rather avoid maintaining a container build for every version of python we want to support that triggers a rebuild each time there are security updates... If we only pay the 1min cost on first run of the dev container that doesn't seem too bad to me...

If we want to go down the container build root then we should use the devcontainers cli to make these in the copier template CI, but we need to work out when to trigger them...

@coretl
Copy link
Contributor Author

coretl commented Nov 8, 2024

Ok, here is the version with oras:

# Add common utils features
COPY --from=ghcr.io/oras-project/oras:v1.2.0 /bin/oras /bin/oras
RUN mkdir /tmp/common-utils \
    && cd /tmp/common-utils \
    && /bin/oras pull ghcr.io/devcontainers/features/common-utils:2 \
    && tar xvf devcontainer-feature-common-utils.tgz \
    && USERNAME=none ./install.sh

I'm now pretty certain this is not the right path to take. What we are after is a good out of the box experience that can be customized by the user (prompt, dotfiles, etc.). VSCode has 2 ways to do this, features and dotfile support.

Some possible routes:

  1. Remove all features from the project, and provide instructions to add user features (and plugins) with at least one sensible default setup (based on zsh) that people can copy and paste with a prompt, completion and persistent history
  2. As 1 but put some useful apt install commands in the dockerfile (like zsh) so that they are cached
  3. As 1 but make the default setup based on bash instead

I've got a mild preference for 3, then shipping the result as a python-copier-template devcontainer feature, but then the question will be which prompt to use.

I'm also not sure how zsh completion works, and whether bash completion can be made to be as good as it with a bit of configuration...

@garryod @callumforrester @gilesknap @GDYendell thoughts?

@callumforrester
Copy link
Contributor

Hmm, sorry about this @gilesknap but I think we should drop ZSH. The rest of this template is very opinionated and goes the route of "there is one supported way to do this". Given that supporting ZSH and bash is already causing complexity I think we should only support one and it should be the one that more people are going to use.

@gilesknap
Copy link
Contributor

Hmm, sorry about this @gilesknap but I think we should drop ZSH. The rest of this template is very opinionated and goes the route of "there is one supported way to do this". Given that supporting ZSH and bash is already causing complexity I think we should only support one and it should be the one that more people are going to use.

@callumforrester I totally agree. This discussion has made it clear that the only thing we are really getting from common-utils is zsh.

@coretl
Copy link
Contributor Author

coretl commented Nov 11, 2024

People who want zsh can always add common-utils via "dev.containers.defaultFeatures" in user settings anyway...

@GDYendell
Copy link
Contributor

Will adding common-utils in user settings make the start up as slow as it is currently?

I have until very recently favoured the simplicity of bash in devcontainers, but now I am pretty set on zsh having adopted some modern terminal features that are too painful to make work in bash, so I expect I will do that. Or do it manually in my devcontainers dotfile install script, which has no caching.

@coretl
Copy link
Contributor Author

coretl commented Nov 14, 2024

Will adding common-utils in user settings make the start up as slow as it is currently?

Yes, unless you choose a container image that already has zsh and oh-my-zsh in it... You may be better off doing the one-liner installer in your dotfile as that is a little bit faster, but it will still be done on every container launch

having adopted some modern terminal features that are too painful to make work in bash

Interesting, which features are those?

@GDYendell
Copy link
Contributor

Interesting, which features are those?

Primarily atuin and interactive autocomplete, which require ble.sh in bash, and starship and lazygit work a bit more seamlessly than in bash.

@gilesknap
Copy link
Contributor

I've made a PR to integrate the new bash-config lightweight feature which tries to reproduce the best aspects of having zsh without requiring the expense of common-utils.

See #216

@gilesknap
Copy link
Contributor

The pip install in onCreateCommand is now leading the bottleneck charts maybe 'uv' is our next step?

@callumforrester
Copy link
Contributor

I think uv deserves its own issue, also unless we can somehow alias it to pip I think it's a breaking change (so copier template 3.0)

coretl added a commit that referenced this issue Dec 3, 2024
Use Richard Cunningham's lightweight bash-config feature instead of
common utils.

The rebuild container overhead for this is approx 10 secs as opposed to
40-60 secs according to
#208 (comment)

See below for details on what this feature does

https://github.com/DiamondLightSource/devcontainer-features/blob/main/.devcontainer/features/bash-config/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants