-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Docker build images: update design doc #8447
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
Conversation
2636528
to
f567040
Compare
e9b0590
to
cc6e739
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple note, I'll continuing thinking about this plan though. I thought a bit more on why I'm more in favor of managing asdf
or pyenv
solely at build time as I was digesting this:
While docker is a great fit for our underlying, system dependencies, and is a reasonable fit for isolating processes, our plan so far for managing images is feeling like we're working hard to make Docker fit a hole that is not Docker sized.
Overall, the benefits I see to managing pre-built binaries via asdf
and friends solely at build time are:
- We don't have to limit the number of binaries we're willing to cache. We have a hard limit with Docker because of the exponential nature of adding new supported versions.
- We have one system to manage versions: asdf at build time
- We can adapt quicker to changes in versions we want to cache because there isn't the same amount of friction as releasing a docker image
- The scope of our docker images would also be greatly reduced and there would be less friction to iterating on these images
- We probably want local caching of prebulit binaries eventually, so that we aren't overloading stress on external mirrors for these prebuilt binaries.
- There is a good amount of effort that would go into continually managing >50 Docker images -- building, rebuilding on base layer changes, managing installation at salt, and supporting this breadth of images
If caching is possible -- if a proof of concept looks promising -- caching is still just an optimization as well. We can chunk this work up into some digestible pieces, starting with a minimal docker image and management of build time installation in the application.
cc6e739
to
feab4b3
Compare
Update the design doc with the latest conversation we had about this topic. Hopefully, we can agree on it and start making some tests in production.
I liked this feedback. Eric also mentioned to me the idea of caching these somehow, but I didn't explore it too much just yet. From what you said here, I don't think there is anything blocking us from moving forward with this plan. The main change here is semantic on how to specify the requirements, basically. Instead of saying "I want to use this Docker image" (via
This seems doable by creating a mirror in our side (e.g. S3) and then defining some environment variables per language supported:
Even with a mirror for Python, we would still have to compile it. So, for Python, we may need a different approach to caching it as a binary.
If we find a way to compile Python once for each version and cache those binaries, only the I did a small test by building Python 3.9.6 on
and then running
We can set the global version and use it:
|
That's great, seems caching should be mostly doable.
I forgot to comment that this is a fantastic part of this plan overall, it's far clearer UX. I was confused by circleci's image layout when i needed both a specific python and node version and it wasn't clear how I was supposed to select an image that fit both constraints. This is directly asking the user "what do you need?" instead of "how does this fit?" and that is such a better experience. 💯
Yeah, exactly, it seems we can break this up into stages really easily. As long as we know it's possible for now, we can implement optimizations with caching later on in the plan -- probably some time before wide spread or default adoption of this approach, but we can gauge that as well. |
* mention cache for official mirrors * add support for pre-compiled Python versions from local cache
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great improvement, and I think a great direction. Just the config changes alone feel like a solid win, and this feels like the "correct" solution to the docker image name conversation we've been having forever (solve a different problem and don't expose the name :D)
I had a few comments, the most important are on the project-level requirements. I think we should move away from feature flagging a lot of things that can break on users like this, since it's totally hidden in the product and very confusing. We can find better ways to opt users in, without making a weird UX.
Another approach for the cache could be to share a volume between the Docker container and the host. In this case, we could pre-compile Python versions and install other languages versions when the AMI is created with This could reduce the complexity of having a mirror on S3 for all the languages and cached pre-compiled Python versions. However, this may require that the Ubuntu running in the AMI has to be the same as the one used for build the docs. |
Minimal implementation for POC of #8447 It uses a Feature flag for now as a way to select the new `readthedocs/build:ubuntu20` image and install Python versions via `asdf`. MinIO requires a new bucket called `languages` with a pre-compiled Python 3.9.6 version to work (*) (this version is hardcoded for now). However, if a different version is selected it will be downloaded from official mirrors, installed and used. Build times on `latest` version for `test-build`: * using the new image + cached Python version: 112s * using the new image + non cached Python version: 288s * using old image (current production): 87s > Note that all the parsing of the Config File to support `build.os` and > `build.languages` is not included in this PR on purpose. That work can be > split as a separate work and done in parallel with the rest of work required > here. (*) to pre-compile a Python version: ```bash docker run -it readthedocs/build:ubuntu20 /bin/bash asdf install python 3.9.6 asdf global python 3.9.6 python -m pip install -U pip setuptools virtualenv cd /home/docs/.asdf/installs/python tar -cfvz ubuntu20-python-3.9.6.tar.gz 3.9.6 docker cp <container id>:/home/docs/.asdf/installs/python/ubuntu20-python-3.9.6.tar.gz . ``` and upload the .tar.gz file to MinIO `languages` bucket using the web interface
Co-authored-by: Eric Holscher <[email protected]>
Minimal implementation for POC of #8447 It uses a Feature flag for now as a way to select the new `readthedocs/build:ubuntu20` image and install Python versions via `asdf` (readthedocs/readthedocs-docker-images#166) MinIO requires a new bucket called `languages` with a pre-compiled Python 3.9.6 version to work (*) (this version is hardcoded for now). However, if a different version is selected it will be downloaded from official mirrors, installed and used. Build times on `latest` version for `test-build`: * using the new image + cached Python version: 112s * using the new image + non cached Python version: 288s * using old image (current production): 87s > Note that all the parsing of the Config File to support `build.os` and > `build.languages` is not included in this PR on purpose. That work can be > split as a separate work and done in parallel with the rest of work required > here. (*) to pre-compile a Python version: ```bash docker run -it readthedocs/build:ubuntu20 /bin/bash asdf install python 3.9.6 asdf global python 3.9.6 python -m pip install -U pip setuptools virtualenv cd /home/docs/.asdf/installs/python tar -cfvz ubuntu20-python-3.9.6.tar.gz 3.9.6 docker cp <container id>:/home/docs/.asdf/installs/python/ubuntu20-python-3.9.6.tar.gz . ``` and upload the .tar.gz file to MinIO `languages` bucket using the web interface
@agjohnson @ericholscher I updated the document with all the feedback received. I think it's ready! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely better than the current structure we have. About supporting more languages and binaries, I think we should also look at allowing uploading html files directly (and processing those files to add our custom stuff).
We have several problems that would be solved by allowing to upload html files instead of building them in our platform:
- Build time
- Additional dependencies, custom builds, etc.
- Repo permissions (permissions are inverted, now users will have access to our platform instead of us access to their code).
There are already great CI services that allow great customization and whatnot, feels like we are replicating the same and with fewer features/flexibility.
Right now we are discussing re-structuring docker images to support more things, custom builders, github permissions, and allowing executing arbitrary commands in the build process. Allowing uploading html files will solve all these problems.
This is just a suggestion to consider, we would need to invest maybe the same amount of time to support this new feature.
I know we have discussed this before, but I'm bring it up since the problems we want to solve seen related.
|
||
At start only a small subset of Python version will be pre-compiled: | ||
|
||
* 2.7.x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can start dropping support for 2.7 in the new images?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can drop support for 2.7. Unfortunately, the world still depends on it.
I'm fine dropping other old 3.x versions, because people can use a newer one, but I don't think users depending on 2.7 are able to migrate to 3.x easily.
We could grab some data from our users and check how many of them are using 2.7, but still --I'm not sure it's a good idea to drop it.
As long as we can compile it on our Ubuntu images via asdf
, it should be fine to support it 😄
Thanks for the feedback!
I definitely want to support HTML upload. I agree with you that it will solve a good amout of known problems. In fact, I have planned its support on the "Future Builders" (see the project https://github.com/orgs/readthedocs/projects/108). However, the implementation of HTML upload depends on the new builders and that work is outside the scope of this "New Docker images for builds" project. |
@readthedocs/backend One thing that we haven't defined yet is how we are going to store the cached pre-built versions in the Originally I thought something like On the other hand, I was thinking something like this: We could probably start with the simplest solution and scale from there if it's needed. |
We are adding support for new languages along the way, not just updating to new docker images, that's the main reason I brought up the idea of solving that with allowing uploading of html files instead of maintaining that code and dependencies. |
We could always do something like build a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a couple notes, but it seems we're all in agreement about how to proceed. Some of the finer points of caching storage and mechanism can be ironed out as we start testing. I think we had a few really good ideas about how to accomplish a cache, but S3 seems pretty easy to start at least.
I'm going to merge these updates. There are some things that we will explore/update/refine while doing the implementation of the config file changes and the cache system; and probably in the QA phase as well. However, the general idea of the documentation is accurate and we are happy to move forward. We can come back to this document and update it again if needed. |
Update the design doc with the latest conversation we had about this topic.
Hopefully, we can agree on it and start making some tests in production.
Structure of the new
Dockerfile
(s) at readthedocs/readthedocs-docker-images#166Rendered version: https://docs--8447.org.readthedocs.build/en/8447/development/design/build-images.html
Proof of Concept: #8453