Skip to content

New image structure based on design document #166

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

Merged
merged 21 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ If you'd like to add a feature to any of the images, you'll need to verify the
image works locally first. After making changes to the ``Dockerfile``, you can
build your image with::

docker build -t readthedocs/build:testing .
docker build -t readthedocs/build:ubuntu20 .

This will take quite a long time, mostly due to LaTeX dependencies. The
resulting image will be around 8GB.
resulting image will be around 5GB.

Once your image is built, you can test your image locally by running a shell in
a container using your new image::

docker run --rm -t -i readthedocs/build:testing /bin/bash
docker run --rm -t -i readthedocs/build:ubuntu20 /bin/bash

This will put you into the root path in the container, as the ``docs`` user.
From here you can head to your home path (``cd ~docs``) and run normal
Expand All @@ -44,21 +44,12 @@ These images are all built from our `automated Docker Hub repository`_. The
automated build rules include pattern matching on Git tags. The current tags
are defined in the :doc:`README`.

We follow `semantic versioning`_, but drop the bug fix level version number for
our images, as this level of granularity is not important for any application of
these images.
We follow `calendar versioning`_ together with the Ubuntu LTS version for that particular image.
For example, if the Ubuntu version is 20.04 and it is released today,
it will be ``ubuntu20-2020.08.30`` (YYYY.MM.DD)

Releases should be merged into one of the ``releases/`` branches, for instance
``releases/2.x``. This commit should then also be tagged using the new version number.

If the version number was ``2.0.1`` before, and you implement
a bug fix to the image, the new image will be ``2.0.2``. The output image from
Docker Hub will still be ``2.0`` however. If a new feature is introduced, the
new version tagged will be ``2.1``.

We don't care about bug fix version numbers here, as Read the Docs will only ever have one
main ``2.x`` image at a time. There is no need for us to run multiple bug fix
versions at the same time.
``releases/ubuntu20-2020.08.30``. This commit should then also be tagged using the new version number.

.. _automated Docker Hub repository: https://hub.docker.com/r/readthedocs/build/
.. _semantic versioning: http://semver.org
.. _calendar versioning: https://calver.org/
230 changes: 58 additions & 172 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ FROM ubuntu:20.04
LABEL mantainer="Read the Docs <[email protected]>"

ENV DEBIAN_FRONTEND noninteractive
ENV APPDIR /app
ENV LANG C.UTF-8

USER root
WORKDIR /

# System dependencies
RUN apt-get -y update
RUN apt-get -y install \
Expand Down Expand Up @@ -48,32 +50,18 @@ RUN apt-get -y install \
subversion \
zlib1g-dev

# pyenv extra requirements
# https://github.com/pyenv/pyenv/wiki/Common-build-problems
RUN apt-get install -y \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
libssl-dev \
llvm \
make \
python-openssl \
tk-dev \
wget \
xz-utils

# LaTeX -- split to reduce image layer size
RUN apt-get -y install \
texlive-fonts-extra
texlive-fonts-extra
RUN apt-get -y install \
texlive-latex-extra-doc \
texlive-pictures-doc \
texlive-publishers-doc
texlive-latex-extra-doc \
texlive-pictures-doc \
texlive-publishers-doc
RUN apt-get -y install \
texlive-lang-english \
texlive-lang-japanese
texlive-lang-english \
texlive-lang-japanese
RUN apt-get -y install \
texlive-full
texlive-full

# lmodern: extra fonts
# https://github.com/rtfd/readthedocs.org/issues/5494
Expand All @@ -85,49 +73,41 @@ RUN apt-get -y install \
# fonts-hanazono: chinese fonts
# https://github.com/readthedocs/readthedocs.org/issues/6319
RUN apt-get -y install \
fonts-symbola \
lmodern \
latex-cjk-chinese-arphic-bkai00mp \
latex-cjk-chinese-arphic-gbsn00lp \
latex-cjk-chinese-arphic-gkai00mp \
texlive-fonts-recommended \
fonts-noto-cjk-extra \
fonts-hanazono \
xindy

# plantuml: is to support sphinxcontrib-plantuml
# https://pypi.org/project/sphinxcontrib-plantuml/
#
# imagemagick: is to support sphinx.ext.imgconverter
# http://www.sphinx-doc.org/en/master/usage/extensions/imgconverter.html
#
# rsvg-convert: is for SVG -> PDF conversion
# using Sphinx extension sphinxcontrib.rsvgconverter, see
# https://github.com/missinglinkelectronics/sphinxcontrib-svg2pdfconverter
#
# swig: is required for different purposes
# https://github.com/rtfd/readthedocs-docker-images/issues/15
RUN apt-get -y install \
imagemagick \
librsvg2-bin \
plantuml \
swig

# Install Python tools/libs
ENV RTD_VIRTUALENV_VERSION 16.7.9
RUN apt-get -y install \
python3-pip && \
pip3 install -U \
auxlib \
virtualenv==$RTD_VIRTUALENV_VERSION
fonts-symbola \
lmodern \
latex-cjk-chinese-arphic-bkai00mp \
latex-cjk-chinese-arphic-gbsn00lp \
latex-cjk-chinese-arphic-gkai00mp \
texlive-fonts-recommended \
fonts-noto-cjk-extra \
fonts-hanazono \
xindy

# asdf Python extra requirements
# https://github.com/pyenv/pyenv/wiki#suggested-build-environment
RUN apt-get install -y \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
libssl-dev \
libxmlsec1-dev \
llvm \
make \
python-openssl \
tk-dev \
wget \
xz-utils

# asdf nodejs extra requirements
# https://github.com/asdf-vm/asdf-nodejs#linux-debian
RUN apt-get install -y \
dirmngr \
gpg

# sphinx-js dependencies: jsdoc and typedoc (TypeScript support)
RUN apt-get -y install \
nodejs \
npm \
&& npm install --global \
jsdoc \
typedoc
# asdf Golang extra requirements
# https://github.com/kennyp/asdf-golang#linux-debian
RUN apt-get install -y \
coreutils

# UID and GID from readthedocs/user
RUN groupadd --gid 205 docs
Expand All @@ -136,115 +116,21 @@ RUN useradd -m --uid 1005 --gid 205 docs
USER docs
WORKDIR /home/docs

# Install pyenv
RUN wget https://github.com/pyenv/pyenv/archive/master.zip
RUN unzip master.zip && \
rm -f master.zip && \
mv pyenv-master ~docs/.pyenv
ENV PYENV_ROOT /home/docs/.pyenv
ENV PATH /home/docs/.pyenv/shims:$PATH:/home/docs/.pyenv/bin

# Define Python versions to be installed via pyenv
ENV RTD_PYTHON_VERSION_27 2.7.18
ENV RTD_PYTHON_VERSION_35 3.5.10
ENV RTD_PYTHON_VERSION_36 3.6.12
ENV RTD_PYTHON_VERSION_37 3.7.9
ENV RTD_PYTHON_VERSION_38 3.8.6
ENV RTD_PYTHON_VERSION_39 3.9.1
ENV RTD_PYPY_VERSION_35 pypy3.5-7.0.0

# Install supported Python versions
RUN pyenv install $RTD_PYTHON_VERSION_27 && \
pyenv install $RTD_PYTHON_VERSION_39 && \
pyenv install $RTD_PYTHON_VERSION_38 && \
pyenv install $RTD_PYTHON_VERSION_37 && \
pyenv install $RTD_PYTHON_VERSION_35 && \
pyenv install $RTD_PYTHON_VERSION_36 && \
pyenv install $RTD_PYPY_VERSION_35 && \
pyenv global \
$RTD_PYTHON_VERSION_27 \
$RTD_PYTHON_VERSION_39 \
$RTD_PYTHON_VERSION_38 \
$RTD_PYTHON_VERSION_37 \
$RTD_PYTHON_VERSION_36 \
$RTD_PYTHON_VERSION_35 \
$RTD_PYPY_VERSION_35

WORKDIR /tmp

# Python2 dependencies are hardcoded because Python2 is
# deprecated. Updating them to their latest versions may raise
# incompatibility issues.
RUN pyenv local $RTD_PYTHON_VERSION_27 && \
pyenv exec pip install --no-cache-dir -U pip==20.0.1 && \
pyenv exec pip install --no-cache-dir -U setuptools==44.0.0 && \
pyenv exec pip install --no-cache-dir --only-binary numpy,scipy numpy scipy && \
pyenv exec pip install --no-cache-dir pandas matplotlib virtualenv==16.7.9

ENV RTD_PIP_VERSION 20.0.1
ENV RTD_SETUPTOOLS_VERSION 45.1.0
RUN pyenv local $RTD_PYTHON_VERSION_39 && \
pyenv exec pip install --no-cache-dir -U pip==$RTD_PIP_VERSION && \
pyenv exec pip install --no-cache-dir -U setuptools==$RTD_SETUPTOOLS_VERSION && \
pyenv exec pip install --no-cache-dir virtualenv==$RTD_VIRTUALENV_VERSION

RUN pyenv local $RTD_PYTHON_VERSION_38 && \
pyenv exec pip install --no-cache-dir -U pip==$RTD_PIP_VERSION && \
pyenv exec pip install --no-cache-dir -U setuptools==$RTD_SETUPTOOLS_VERSION && \
pyenv exec pip install --no-cache-dir --only-binary numpy numpy && \
pyenv exec pip install --no-cache-dir pandas matplotlib virtualenv==$RTD_VIRTUALENV_VERSION

RUN pyenv local $RTD_PYTHON_VERSION_37 && \
pyenv exec pip install --no-cache-dir -U pip==$RTD_PIP_VERSION && \
pyenv exec pip install --no-cache-dir -U setuptools==$RTD_SETUPTOOLS_VERSION && \
pyenv exec pip install --no-cache-dir --only-binary numpy,scipy numpy scipy && \
pyenv exec pip install --no-cache-dir pandas matplotlib virtualenv==$RTD_VIRTUALENV_VERSION

RUN pyenv local $RTD_PYTHON_VERSION_36 && \
pyenv exec pip install --no-cache-dir -U pip==$RTD_PIP_VERSION && \
pyenv exec pip install --no-cache-dir -U setuptools==$RTD_SETUPTOOLS_VERSION && \
pyenv exec pip install --no-cache-dir --only-binary numpy,scipy numpy scipy && \
pyenv exec pip install --no-cache-dir pandas matplotlib virtualenv==$RTD_VIRTUALENV_VERSION

RUN pyenv local $RTD_PYTHON_VERSION_35 && \
pyenv exec pip install --no-cache-dir -U pip==$RTD_PIP_VERSION && \
pyenv exec pip install --no-cache-dir -U setuptools==$RTD_SETUPTOOLS_VERSION && \
pyenv exec pip install --no-cache-dir --only-binary numpy,scipy numpy scipy && \
pyenv exec pip install --no-cache-dir pandas matplotlib virtualenv==$RTD_VIRTUALENV_VERSION

RUN pyenv local $RTD_PYPY_VERSION_35 && \
pyenv exec python -m ensurepip && \
pyenv exec pip3 install --no-cache-dir -U pip==$RTD_PIP_VERSION && \
pyenv exec pip install --no-cache-dir -U setuptools==$RTD_SETUPTOOLS_VERSION && \
pyenv exec pip install --no-cache-dir virtualenv==$RTD_VIRTUALENV_VERSION

# Install Conda
WORKDIR /home/docs
# Note: 4.7.12.1 drastically increases memory usage
ENV RTD_CONDA_VERSION 4.6.14
RUN curl -L -O https://repo.continuum.io/miniconda/Miniconda2-${RTD_CONDA_VERSION}-Linux-x86_64.sh
RUN bash Miniconda2-${RTD_CONDA_VERSION}-Linux-x86_64.sh -b -p /home/docs/.conda/
ENV PATH $PATH:/home/docs/.conda/bin
RUN rm -f Miniconda2-${RTD_CONDA_VERSION}-Linux-x86_64.sh

# Install Rust
ENV RTD_RUST_VERSION 1.46.0
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RTD_RUST_VERSION}
ENV PATH="/home/docs/.cargo/bin:$PATH"
# Install asdf
RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --depth 1 --branch v0.8.1
RUN echo ". /home/docs/.asdf/asdf.sh" >> /home/docs/.bashrc
RUN echo ". /home/docs/.asdf/completions/asdf.bash" >> /home/docs/.bashrc

WORKDIR /
# Activate asdf in current session
ENV PATH /home/docs/.asdf/shims:/home/docs/.asdf/bin:$PATH

# Install asdf plugins
RUN asdf plugin-add python
RUN asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
RUN asdf plugin-add rust https://github.com/code-lever/asdf-rust.git
RUN asdf plugin-add golang https://github.com/kennyp/asdf-golang.git

# Adding labels for external usage
LABEL python.version_27=$PYTHON_VERSION_27
LABEL python.version_35=$PYTHON_VERSION_35
LABEL python.version_36=$PYTHON_VERSION_36
LABEL python.version_37=$PYTHON_VERSION_37
LABEL python.version_38=$PYTHON_VERSION_38
LABEL python.version_39=$PYTHON_VERSION_39
LABEL python.pip=$_PIP_VERSION
LABEL python.setuptools=$SETUPTOOLS_VERSION
LABEL python.virtualenv=$VIRTUALENV_VERSION
LABEL pypy.version_35=$PYPY_VERSION_35
LABEL conda.version=$CONDA_VERSION
# Create directories for languages installations
RUN mkdir -p /home/docs/.asdf/installs/{python,nodejs,rust,golang}

CMD ["/bin/bash"]
39 changes: 9 additions & 30 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,15 @@ environments to encapsulate the build process.
You can find these images on Docker Hub, on the `readthedocs/build`_
repository:

`readthedocs/build:1.0`
**Deprecated**
Ubuntu 14.04 based image.
`readthedocs/build:ubuntu20-YYYY.MM.DD`
Ubuntu 20.04 supporting multiple versions of Python, PyPy, conda, mamba, nodejs, rust and go.
Available for public usage as ``build.os: ubuntu20``

`readthedocs/build:1.0-dotnet`
**Deprecated**
Ubuntu 14.04 based image, plus .NET.
Note that these images only contains the basic dependencies:

`readthedocs/build:2.0`
**Deprecated**
Ubuntu 16.04 based image.

`readthedocs/build:4.0`
**Deprecated**
Ubuntu 18.04 supporting Python 2.7, 3.5, 3.6, 3.7.

`readthedocs/build:5.0`
``stable``
Ubuntu 18.04 supporting Python 2.7, 3.6, 3.7 and pypy3.5-7.0.0.
This is the **stable** image supported by Read the Docs.

`readthedocs/build:6.0`
``latest``
Ubuntu 18.04 supporting Python 2.7, 3.5, 3.6, 3.7, 3.8 and PyPy3.5-7.0.0.
This is the **latest** default image used for documentation builds and supported by Read the Docs.

`readthedocs/build:7.0`
``testing``
Ubuntu 18.04 supporting Python 2.7, 3.5, 3.6, 3.7, 3.8, 3.9, and PyPy3.5-7.0.0.
Available for public usage as **testing** image. You should expect some breaking changes here.
Comment on lines -26 to -40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these not still important to document, since they are still in use?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a little (too much) opinionated 😄

  • I think we shouldn't explain these images here "to the final user"
  • I think users wanting to use these images should be pointed to the Read the Docs documentation instead (config file)
  • I would try to keep this repository hidden from the regular users because it only generates confusion
  • I wanted to only expose the newer image to avoid people finding this and using the old images

That said, it may make sense to remove the phrase "Available for public usage as build.os: ubuntu-20.04" as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would try to keep this repository hidden from the regular users because it only generates confusion

Perhaps we should make it private, then? And move these docs to our public-facing docs & config file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it private may be too much. I think we will lose some issues/prs references linked everywhere.

Definitely, how to use the docker image and what it contains should be documented in the Read the Docs documentation for the config file.

- ``asdf`` CLI manager to install the languages versions
- LaTeX packages to build PDFs
- Chinese fonts

.. _readthedocs/build: https://hub.docker.com/r/readthedocs/build/

Expand All @@ -46,11 +25,11 @@ Usage

To use the pre-built images, you can pull from Docker Hub:

docker pull readthedocs/build:latest
docker pull readthedocs/build:ubuntu20-YYYY.MM.DD

You can also compile these images locally:

docker build -t readthedocs/build:testing .
docker build -t readthedocs/build:ubuntu20-YYYY.MM.DD .

See `CONTRIBUTING`_ for more information on building and testing.

Expand Down
Loading