dependabot-core / python /Dockerfile
AbdulElahGwaith's picture
Upload folder using huggingface_hub
e98c0d7 verified
# syntax=docker.io/docker/dockerfile:1.20
# This list must match the versions specified in
# python/lib/dependabot/python/language.rb: PRE_INSTALLED_PYTHON_VERSIONS_RAW
# python/spec/dependabot/python/file_fetcher_spec.rb: exposes the expected ecosystem_versions metric spec
# Python versions are pinned to the release of each minor/patch version.
ARG PY_3_14=3.14.2
ARG PY_3_13=3.13.11
ARG PY_3_12=3.12.12
ARG PY_3_11=3.11.14
ARG PY_3_10=3.10.19
ARG PY_3_9=3.9.24
# https://github.com/pyenv/pyenv/releases
ARG PYENV_VERSION=v2.6.16
FROM ghcr.io/dependabot/dependabot-updater-core AS python-core
ARG PY_3_14
ARG PY_3_13
ARG PY_3_12
ARG PY_3_11
ARG PY_3_10
ARG PY_3_9
ARG PYENV_VERSION
USER root
COPY --chown=dependabot:dependabot python/helpers /opt/python/helpers
# TODO: Now that switched from `pyenv install` which compiled from source to downloading / copying a pre-compiled python
# we could entirely drop pyenv if we change our ruby code that calls `pyenv exec` to track which version of python to
# call and uses the full python paths.
ENV PYENV_ROOT=/usr/local/.pyenv \
PATH="/usr/local/.pyenv/bin:$PATH"
RUN mkdir -p "$PYENV_ROOT" && chown dependabot:dependabot "$PYENV_ROOT"
USER dependabot
ENV REQUESTS_CA_BUNDLE /etc/ssl/certs/ca-certificates.crt
ENV SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt
ENV DEPENDABOT_NATIVE_HELPERS_PATH="/opt"
RUN git -c advice.detachedHead=false clone https://github.com/pyenv/pyenv.git --branch $PYENV_VERSION --single-branch --depth=1 /usr/local/.pyenv
# We used to use `pyenv install 3.x.y` but it's really slow because it compiles from source (~500s). So instead, we hack
# around that by downloading pre-compiled versions, then placing them where pyenv expects it in the `versions` subfolder.
# In the future, we should consider dropping pyenv completely, as it's mostly used here for legacy reasons...
# Although it is convenient when debugging to be able to quickly flip through environments.
RUN mkdir "${PYENV_ROOT}/versions"
## 3.9
# Docker doesn't support parametrizing `COPY --from:python:$PY_1_23-bookworm`, so work around it using an alias.
# TODO: If upstream adds support for Ubuntu, use that instead of Debian as the base suffix: https://github.com/docker-library/python/pull/791
FROM docker.io/library/python:$PY_3_9-bookworm AS upstream-python-3.9
FROM python-core AS python-3.9
ARG PYTHON_INSTALL_LOCATION="$PYENV_ROOT/versions/$PY_3_9"
COPY --from=upstream-python-3.9 --chown=dependabot:dependabot /usr/local/bin $PYTHON_INSTALL_LOCATION/bin
COPY --from=upstream-python-3.9 --chown=dependabot:dependabot /usr/local/include $PYTHON_INSTALL_LOCATION/include
COPY --from=upstream-python-3.9 --chown=dependabot:dependabot /usr/local/lib $PYTHON_INSTALL_LOCATION/lib
# `pip` and other scripts need their shebangs rewritten for the new location
RUN find $PYTHON_INSTALL_LOCATION/bin -type f -exec sed -i "1s|^#!/usr/local/bin/python|#!$PYTHON_INSTALL_LOCATION/bin/python|" {} +
# Ensure pyenv works and it's the python version we expect
RUN PYENV_VERSION=$PY_3_9 pyenv exec python --version | grep "Python $PY_3_9" || exit 1
RUN bash /opt/python/helpers/build $PY_3_9
# This python environment occupies ~0.5 GB and gets used for a fraction of jobs, so store it compressed.
RUN cd $PYENV_ROOT/versions \
&& tar -acf $PY_3_9.tar.zst $PY_3_9
## 3.10
# Docker doesn't support parametrizing `COPY --from:python:$PY_1_23-bookworm`, so work around it using an alias.
# TODO: If upstream adds support for Ubuntu, use that instead of Debian as the base suffix: https://github.com/docker-library/python/pull/791
FROM docker.io/library/python:$PY_3_10-bookworm AS upstream-python-3.10
FROM python-core AS python-3.10
ARG PYTHON_INSTALL_LOCATION="$PYENV_ROOT/versions/$PY_3_10"
COPY --from=upstream-python-3.10 --chown=dependabot:dependabot /usr/local/bin $PYTHON_INSTALL_LOCATION/bin
COPY --from=upstream-python-3.10 --chown=dependabot:dependabot /usr/local/include $PYTHON_INSTALL_LOCATION/include
COPY --from=upstream-python-3.10 --chown=dependabot:dependabot /usr/local/lib $PYTHON_INSTALL_LOCATION/lib
# `pip` and other scripts need their shebangs rewritten for the new location
RUN find $PYTHON_INSTALL_LOCATION/bin -type f -exec sed -i "1s|^#!/usr/local/bin/python|#!$PYTHON_INSTALL_LOCATION/bin/python|" {} +
# Ensure pyenv works and it's the python version we expect
RUN PYENV_VERSION=$PY_3_10 pyenv exec python --version | grep "Python $PY_3_10" || exit 1
RUN bash /opt/python/helpers/build $PY_3_10
# This python environment occupies ~0.5 GB and gets used for a fraction of jobs, so store it compressed.
RUN cd $PYENV_ROOT/versions \
&& tar -acf $PY_3_10.tar.zst $PY_3_10
## 3.11
# Docker doesn't support parametrizing `COPY --from:python:$PY_1_23-bookworm`, so work around it using an alias.
# TODO: If upstream adds support for Ubuntu, use that instead of Debian as the base suffix: https://github.com/docker-library/python/pull/791
FROM docker.io/library/python:$PY_3_11-bookworm AS upstream-python-3.11
FROM python-core AS python-3.11
ARG PYTHON_INSTALL_LOCATION="$PYENV_ROOT/versions/$PY_3_11"
COPY --from=upstream-python-3.11 --chown=dependabot:dependabot /usr/local/bin $PYTHON_INSTALL_LOCATION/bin
COPY --from=upstream-python-3.11 --chown=dependabot:dependabot /usr/local/include $PYTHON_INSTALL_LOCATION/include
COPY --from=upstream-python-3.11 --chown=dependabot:dependabot /usr/local/lib $PYTHON_INSTALL_LOCATION/lib
# `pip` and other scripts need their shebangs rewritten for the new location
RUN find $PYTHON_INSTALL_LOCATION/bin -type f -exec sed -i "1s|^#!/usr/local/bin/python|#!${PYTHON_INSTALL_LOCATION}/bin/python|" {} +
# Ensure pyenv works and it's the python version we expect
RUN PYENV_VERSION=$PY_3_11 pyenv exec python --version | grep "Python $PY_3_11" || exit 1
RUN bash /opt/python/helpers/build $PY_3_11
# This python environment occupies ~0.5 GB and gets used for a fraction of jobs, so store it compressed.
RUN cd $PYENV_ROOT/versions \
&& tar -acf $PY_3_11.tar.zst $PY_3_11
## 3.12
# Docker doesn't support parametrizing `COPY --from:python:$PY_1_23-bookworm`, so work around it using an alias.
# TODO: If upstream adds support for Ubuntu, use that instead of Debian as the base suffix: https://github.com/docker-library/python/pull/791
FROM docker.io/library/python:$PY_3_12-bookworm AS upstream-python-3.12
FROM python-core AS python-3.12
ARG PYTHON_INSTALL_LOCATION="$PYENV_ROOT/versions/$PY_3_12"
COPY --from=upstream-python-3.12 --chown=dependabot:dependabot /usr/local/bin $PYTHON_INSTALL_LOCATION/bin
COPY --from=upstream-python-3.12 --chown=dependabot:dependabot /usr/local/include $PYTHON_INSTALL_LOCATION/include
COPY --from=upstream-python-3.12 --chown=dependabot:dependabot /usr/local/lib $PYTHON_INSTALL_LOCATION/lib
# `pip` and other scripts need their shebangs rewritten for the new location
RUN find $PYTHON_INSTALL_LOCATION/bin -type f -exec sed -i "1s|^#!/usr/local/bin/python|#!${PYTHON_INSTALL_LOCATION}/bin/python|" {} +
# Ensure pyenv works and it's the python version we expect
RUN PYENV_VERSION=$PY_3_12 pyenv exec python --version | grep "Python $PY_3_12" || exit 1
RUN bash /opt/python/helpers/build $PY_3_12
# This python environment occupies ~0.5 GB and gets used for a fraction of jobs, so store it compressed.
RUN cd $PYENV_ROOT/versions \
&& tar -acf $PY_3_12.tar.zst $PY_3_12
## 3.13
# Docker doesn't support parametrizing `COPY --from:python:$PY_1_23-bookworm`, so work around it using an alias.
# TODO: If upstream adds support for Ubuntu, use that instead of Debian as the base suffix: https://github.com/docker-library/python/pull/791
FROM docker.io/library/python:$PY_3_13-bookworm AS upstream-python-3.13
FROM python-core AS python-3.13
ARG PYTHON_INSTALL_LOCATION="$PYENV_ROOT/versions/$PY_3_13"
COPY --from=upstream-python-3.13 --chown=dependabot:dependabot /usr/local/bin $PYTHON_INSTALL_LOCATION/bin
COPY --from=upstream-python-3.13 --chown=dependabot:dependabot /usr/local/include $PYTHON_INSTALL_LOCATION/include
COPY --from=upstream-python-3.13 --chown=dependabot:dependabot /usr/local/lib $PYTHON_INSTALL_LOCATION/lib
# `pip` and other scripts need their shebangs rewritten for the new location
RUN find $PYTHON_INSTALL_LOCATION/bin -type f -exec sed -i "1s|^#!/usr/local/bin/python|#!${PYTHON_INSTALL_LOCATION}/bin/python|" {} +
# Ensure pyenv works and it's the python version we expect
RUN PYENV_VERSION=$PY_3_13 pyenv exec python --version | grep "Python $PY_3_13" || exit 1
RUN bash /opt/python/helpers/build $PY_3_13
RUN cd $PYENV_ROOT/versions \
&& tar -acf $PY_3_13.tar.zst $PY_3_13
## 3.14
# Docker doesn't support parametrizing `COPY --from:python:$PY_1_23-bookworm`, so work around it using an alias.
# TODO: If upstream adds support for Ubuntu, use that instead of Debian as the base suffix: https://github.com/docker-library/python/pull/791
FROM docker.io/library/python:$PY_3_14-bookworm AS upstream-python-3.14
FROM python-core AS python-3.14
ARG PYTHON_INSTALL_LOCATION="$PYENV_ROOT/versions/$PY_3_14"
COPY --from=upstream-python-3.14 --chown=dependabot:dependabot /usr/local/bin $PYTHON_INSTALL_LOCATION/bin
COPY --from=upstream-python-3.14 --chown=dependabot:dependabot /usr/local/include $PYTHON_INSTALL_LOCATION/include
COPY --from=upstream-python-3.14 --chown=dependabot:dependabot /usr/local/lib $PYTHON_INSTALL_LOCATION/lib
# `pip` and other scripts need their shebangs rewritten for the new location
RUN find $PYTHON_INSTALL_LOCATION/bin -type f -exec sed -i "1s|^#!/usr/local/bin/python|#!${PYTHON_INSTALL_LOCATION}/bin/python|" {} +
# Ensure pyenv works and it's the python version we expect
RUN PYENV_VERSION=$PY_3_14 pyenv exec python --version | grep "Python $PY_3_14" || exit 1
RUN bash /opt/python/helpers/build $PY_3_14
# This is the default Python, so no need to tar it
FROM python-core
# Install C-libs needed to build users' Python packages. Please document why each package is needed.
USER root
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
# Used by pycurl
libcurl4-openssl-dev \
# Used by mysqlclient
libmysqlclient-dev \
pkg-config \
# Used by psycopg Postgres Client
libpq-dev \
# Used by python zoneinfo core lib
tzdata \
# Needed to build `gssapi`/`krb5`
libkrb5-dev \
# Used by pycairo and pygobject
libcairo2-dev \
libgirepository-2.0-dev \
&& rm -rf /var/lib/apt/lists/*
USER dependabot
COPY --chown=dependabot:dependabot --parents python common $DEPENDABOT_HOME/
COPY --chown=dependabot:dependabot updater $DEPENDABOT_HOME/dependabot-updater
# Running these steps last means that if the builds in the concurrent stages take longer it doesn't block the pipeline until the end.
COPY --from=python-3.9 $PYENV_ROOT/versions/$PY_3_9.tar.zst $PYENV_ROOT/versions/$PY_3_9.tar.zst
COPY --from=python-3.10 $PYENV_ROOT/versions/$PY_3_10.tar.zst $PYENV_ROOT/versions/$PY_3_10.tar.zst
COPY --from=python-3.11 $PYENV_ROOT/versions/$PY_3_11.tar.zst $PYENV_ROOT/versions/$PY_3_11.tar.zst
COPY --from=python-3.12 $PYENV_ROOT/versions/$PY_3_12.tar.zst $PYENV_ROOT/versions/$PY_3_12.tar.zst
COPY --from=python-3.13 $PYENV_ROOT/versions/$PY_3_13.tar.zst $PYENV_ROOT/versions/$PY_3_13.tar.zst
COPY --from=python-3.14 $PYENV_ROOT/versions/ $PYENV_ROOT/versions/
# Copy the output of the build script, it should be identical across Python versions
COPY --from=python-3.14 /opt/python/ /opt/python/
RUN pyenv global $PY_3_14
USER root
# Install Rust
ENV RUSTUP_HOME=/opt/rust \
CARGO_HOME=/opt/rust \
CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse \
PATH="${PATH}:/opt/rust/bin"
RUN mkdir -p "$RUSTUP_HOME" && chown dependabot:dependabot "$RUSTUP_HOME"
USER dependabot
COPY --from=rust /usr/local/rustup $RUSTUP_HOME
COPY --from=rust /usr/local/cargo $CARGO_HOME
# Configure cargo to use Git CLI so the Git shim works
RUN mkdir -p ~/.cargo && printf "[net]\ngit-fetch-with-cli = true\n" >> ~/.cargo/config.toml
COPY --chown=dependabot:dependabot --parents cargo common $DEPENDABOT_HOME/
COPY --chown=dependabot:dependabot updater $DEPENDABOT_HOME/dependabot-updater