Skip to content

Commit dff3441

Browse files
committed
Some thoughts on what versioned images look like
Based on #7566
1 parent 419e23e commit dff3441

File tree

1 file changed

+74
-67
lines changed

1 file changed

+74
-67
lines changed

docs/development/design/build-images.rst

+74-67
Original file line numberDiff line numberDiff line change
@@ -51,88 +51,101 @@ Goals
5151
* reduce size on builder VM disks by sharing Docker image layers
5252
* deprecate ``stable``, ``latest`` and ``testing``
5353
* allow use custom images for particular users/customers by sharing most layers
54-
* create a small ``nopdf`` image version without LaTeX dependencies for local development
5554

5655

5756
New build image structure
5857
-------------------------
5958

60-
.. Taken from https://github.com/readthedocs/readthedocs-docker-images/blob/master/Dockerfile
59+
.. Some of this is borrowed from CircleCI image versioning
6160
62-
* ``ubuntu20-base``
63-
* labels
64-
* environment variables
65-
* system dependencies
66-
* install requirements
67-
* user requirements
68-
* plantuml, imagemagick, rsgv-convert, swig
69-
* sphinx-js dependencies
70-
* rust
71-
* UID and GID
61+
``readthedocs/build:base``
62+
Alias of ``readthedocs/build:base-ubuntu20``, used to abstract concept of OS
63+
away from end users where it's not neccessary.
7264

73-
* ``ubuntu20-pdf`` (from ``ubuntu20-base``)
74-
* PDF/LaTeX dependencies
65+
Base images also include:
7566

76-
* ``ubuntu20`` (from ``ubuntu20-pdf``)
77-
* all Python versions (2, 3.6, 3.7, 3.8, 3.9)
78-
* conda
79-
* future extra user requirements
80-
* labels
67+
``readthedocs/build:base-ubuntu20``
68+
Base for next gen prod images. Synonymous with current concept of ``latest``
8169

82-
We will also build a ``nopdf`` version to allow quick testing in local development:
70+
``readthedocs/build:base-ubuntu18``
71+
Base for previous gen prod images. Synonymous with concept of ``stable``
8372

84-
* ``ubuntu20-nopdf`` (from ``ubuntu20-base``)
85-
* same as ``ubuntu20`` but based on ``ubuntu20-base`` instead
73+
Base images include:
8674

87-
.. note::
75+
* labels
76+
* environment variables
77+
* system dependencies
78+
* install requirements
79+
* PDF/LaTeX dependencies
80+
* Limited user requirements
81+
* plantuml, imagemagick, rsgv-convert, swig
82+
* sphinx-js dependencies
83+
* UID and GID
8884

89-
I don't think it's useful to have ``ubuntu20-py37`` exposed to users,
90-
since the Python version is selected by using the config file's ``python.version`` keyword,
91-
we only update patch versions and we don't remove them (unless together with OS changes).
85+
``readthedocs/build:python``
86+
Installs latest release of Python
9287

93-
.. Build all these images with Docker
94-
docker build -t readthedocs/build:ubuntu20-base -f Dockerfile.base .
95-
docker build -t readthedocs/build:ubuntu20-nopdf -f Dockerfile.nopdf .
96-
docker build -t readthedocs/build:ubuntu20-pdf -f Dockerfile.pdf .
97-
docker build -t readthedocs/build:ubuntu20 -f Dockerfile .
88+
``readthedocs/build:python39``
89+
Installs 3.9 release of Python
9890

99-
Check the shared space between images
100-
docker system df --verbose | grep -E 'SHARED SIZE|readthedocs'
91+
``readthedocs/build:python39-ubuntu18``
92+
Installs 3.9 release of Python on Ubuntu 18.04 base
93+
(``readthedocs/build:base-ubuntu18``)
10194

95+
``readthedocs/build:python27``
96+
Installs 3.9 release of Python
10297

103-
Custom images
104-
-------------
98+
``readthedocs/build:conda12``
99+
Installs 1.2 release of Conda
100+
101+
``readthedocs/build:node12``
102+
Installs Node 12.x release
103+
104+
``readthedocs/build:python+node``
105+
Installs latest Python and latest Node
105106

106-
There are some dependencies that are not easy to update and keep compatibility with all the users at the same time.
107-
Upgrading ``nodejs`` may make lot of old projects expecting the older version to start failing all their builds.
108-
On the other hand, sticking with an old version avoid users requiring a newer version to build their documentation.
109-
To handle this case and others, we have been thinking on supporting custom Docker images.
107+
``readthedocs/build:python39+node12``
108+
Installs Python 3.9 and Node 12.0
110109

111-
It's not clear to me how it would be the implementation of this, but I see different paths to discuss and explore:
110+
``readthedocs/build:python36+node8-ubuntu18``
111+
Installs Python 3.6 and Node 8 on Ubuntu 18.04 base
112112

113-
#. Allow a ``build.dockerfile`` config pointing to a ``Dockerfile``
114-
* ``FROM readthedocs/build:ubuntu20`` is required to be a valid image (to share layers)
115-
* the image is build each time a build is triggered consuming build time
116-
#. Create a branch per custom image in ``readthedocs-docker-images`` repository
117-
* use ``ubuntu20`` as base image and add the custom extra requirements
118-
* build the image using our current process (Docker Hub)
119-
* add the custom image to our ``-ops`` repository
120-
* re-build builders to pull down the new custom image
121-
* set the project to use this custom image, eg. ``readthedocs/build:<project-slug>``
122113

114+
Building
115+
~~~~~~~~
116+
117+
This process would be automated. CircleCI does something similar but with far
118+
more complexity than we need:
119+
120+
https://github.com/circleci/circleci-images
121+
122+
We would use envvars or generate a pile of Dockerfiles. Dockerfiles would be
123+
consumed by whatever process we are using to build images with intermediate
124+
layers.
125+
126+
Custom images
127+
-------------
128+
129+
To handle custom image requirements, we will support custom Docker images. To
130+
start, this is under feature flag. This will reduce the amount of maintenance by
131+
limiting the number of dependencies users ask us to maintain.
132+
133+
#. User builds image with base image of ``readthedocs/build:base`` or
134+
``readthedocs/build:python`` etc.
135+
* On container start, Docker fetches the missing image
136+
* The user is responsible for versioning their own image in a way that it is
137+
updated on the build servers when it does not exist.
138+
* We need to limit the number of users that can do this until we know what
139+
disk usage looks like.
123140

124141
Updating versions over time
125142
---------------------------
126143

127144
How do we add/upgrade a Python version?
128145
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129146

130-
Python patch versions can be upgraded and backported to all the images without problems.
131-
There is only needed to rebuild ``ubuntu20`` and most of the layers will remain shared with ``-base`` and ``-pdf``.
132-
133-
In case we need to *add* a new Python version, the situation is similar.
134-
We can add the new version by using ``pyenv`` and rebuilding the ``ubuntu20`` image.
135-
147+
We edit the ``python39-ubuntu18`` and ``python39-ubuntu20`` Dockerfile. There is
148+
no backporting and risk due to change is limited to these two images.
136149

137150
How do we upgrade system versions?
138151
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -154,15 +167,9 @@ Examples of these versions are:
154167
How do we add an extra requirement?
155168
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156169

157-
If a user asks for a new requirement (eg. azure CLI, ``az`` command) it should go into the
158-
"user requirements" section in the ``ubuntu20-base`` image.
159-
However, that will force us to rebuild all the images.
160-
161-
We could use the section named as "future user extra requirements" for this,
162-
and it will force us to only rebuild the ``ubuntu20`` image.
163-
164-
Both approaches will require to rebuild all the custom docker images from our users/customers
165-
that are based on the ``ubuntu20`` image.
170+
We don't. Users will manage weird requirements themselves by using custom
171+
images. If the majority of users do not need the requirement, we shouldn't bloat
172+
the base images with it.
166173

167174

168175
How do we remove an old Python version?
@@ -208,9 +215,9 @@ but by its main base difference: OS. The version of the OS will change many libr
208215
LaTeX dependencies, basic required commands like git and more,
209216
that doesn't seem to be useful to have the same OS version with different states.
210217

211-
Also, splitting images by Python version sounds complicated to maintain.
212-
Each time we need to make a small change into one of the base layers, we will end up rebuilding many images.
213-
Besides, the key ``python.version`` won't make sense anymore and bring confusions.
218+
The config key ``python.version`` will dictate the image used and most users
219+
won't need to specify an image to use at all. Only for select cases will users
220+
need to specify both.
214221

215222
Custom images is something that needs more exploration still,
216223
but both proposals seem doable in weeks as an initial proof of concept.

0 commit comments

Comments
 (0)