Skip to content

Commit

Permalink
feat: add Python 3.13 (#144)
Browse files Browse the repository at this point in the history
setuptools and wheel are not installed by default on Python 3
remove requirements directory
  • Loading branch information
cesarcoatl authored Oct 7, 2024
1 parent 8b16e49 commit 546d325
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 103 deletions.
37 changes: 12 additions & 25 deletions .github/workflows/auto-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ name: auto-update

on:
schedule:
- cron: '30 18 * * 0,4' # Python packages
- cron: '0 18 14,28 * *' # Git
- cron: '0 18 10 2-12/2 *' # Python 3.12 release schedule; see: https://peps.python.org/pep-0693/#bugfix-releases
- cron: '0 18 10 2-12/2 *' # Python release schedule
workflow_dispatch:

jobs:
Expand All @@ -26,37 +25,25 @@ jobs:
- name: Fetch latest Python 3.12 release
if: ${{ github.event.schedule == '0 18 10 2-12/2 *' || github.event_name == 'workflow_dispatch' }}
run: |
python3_version=$(curl -s https://www.python.org/ftp/python/ | grep -oP '3\.12\.\d+/' | uniq | sort -V | tail -n 1 | tr -d '/')
python_version=$(curl -s https://www.python.org/ftp/python/ | grep -oP '3\.12\.\d+/' | uniq | sort -V | tail -n 1 | tr -d '/')
echo "python312: $python3_version"
echo "python3.12: $python_version"
sed -i "s/ENV PYTHON3_VERSION=.*/ENV PYTHON3_VERSION=$python3_version/" Dockerfile
sed -i "s/ENV PYTHON312_VERSION=.*/ENV PYTHON312_VERSION=$python_version/" Dockerfile
- name: Update requirements
uses: coatl-dev/actions/pip-compile@v3
with:
path: requirements
- name: Fetch latest Python 3.13 release
if: ${{ github.event.schedule == '0 18 10 2-12/2 *' || github.event_name == 'workflow_dispatch' }}
run: |
python_version=$(curl -s https://www.python.org/ftp/python/ | grep -oP '3\.13\.\d+/' | uniq | sort -V | tail -n 1 | tr -d '/')
echo "python3.13: $python_version"
sed -i "s/ENV PYTHON313_VERSION=.*/ENV PYTHON313_VERSION=$python_version/" Dockerfile
- name: Detect changes
id: git-diff
uses: coatl-dev/actions/simple-git-diff@v3

- name: Extract package versions and update Dockerfile
if: ${{ steps.git-diff.outputs.diff == 'true' }}
run: |
pip_version=$(grep '^pip==' requirements/base.txt | cut -d'=' -f3)
setuptools_version=$(grep '^setuptools==' requirements/base.txt | cut -d'=' -f3)
wheel_version=$(grep '^wheel==' requirements/base.txt | cut -d'=' -f3)
echo "Extracted versions:"
echo "pip: $pip_version"
echo "setuptools: $setuptools_version"
echo "wheel: $wheel_version"
sed -i "s/ENV PYTHON3_PIP_VERSION=.*/ENV PYTHON3_PIP_VERSION=$pip_version/" Dockerfile
sed -i "s/ENV PYTHON3_SETUPTOOLS_VERSION=.*/ENV PYTHON3_SETUPTOOLS_VERSION=$setuptools_version/" Dockerfile
sed -i "s/ENV PYTHON3_WHEEL_VERSION=.*/ENV PYTHON3_WHEEL_VERSION=$wheel_version/" Dockerfile
- name: Import GPG key
if: ${{ steps.git-diff.outputs.diff == 'true' }}
id: gpg-import
Expand Down
164 changes: 107 additions & 57 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -96,26 +96,26 @@ RUN set -eux; \

# >============================================================================<

FROM builder AS python2-builder
FROM builder AS python27-builder

ENV PYTHON2_VERSION=2.7.18
ENV PYTHON217_VERSION=2.7.18

WORKDIR /tmp

RUN set -eux; \
\
wget -q "https://www.python.org/ftp/python/${PYTHON2_VERSION%%[a-z]*}/Python-${PYTHON2_VERSION}.tgz"; \
tar -zxf "Python-${PYTHON2_VERSION}.tgz"
wget -q "https://www.python.org/ftp/python/${PYTHON217_VERSION%%[a-z]*}/Python-${PYTHON217_VERSION}.tgz"; \
tar -zxf "Python-${PYTHON217_VERSION}.tgz"

WORKDIR "/tmp/Python-${PYTHON2_VERSION}"
WORKDIR "/tmp/Python-${PYTHON217_VERSION}"

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN set -eux; \
\
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
./configure \
--build="$gnuArch" \
--prefix="${PYTHON_ROOT}/2/" \
--prefix="${PYTHON_ROOT}/2.7/" \
--enable-optimizations \
--enable-option-checking=fatal \
--enable-shared \
Expand Down Expand Up @@ -162,7 +162,7 @@ RUN set -eux; \
\
make altinstall; \
\
echo "${PYTHON_ROOT}/2/lib" | tee /etc/ld.so.conf.d/python2.conf; \
echo "${PYTHON_ROOT}/2.7/lib" | tee /etc/ld.so.conf.d/python2.7.conf; \
ldconfig; \
\
find "${PYTHON_ROOT}" -depth \
Expand All @@ -173,62 +173,54 @@ RUN set -eux; \
\) -exec rm -rf '{}' + \
;

# if this is called "PIP_VERSION", pip explodes with "ValueError: invalid truth value '<VERSION>'"
ENV PYTHON2_PIP_VERSION=20.3.4
ENV PYTHON2_SETUPTOOLS_VERSION=44.1.1
ENV PYTHON2_WHEEL_VERSION=0.37.1
# https://github.com/pypa/get-pip
ENV PYTHON_GET_PIP_URL=https://raw.githubusercontent.com/pypa/get-pip/HEAD/public/2.7/get-pip.py

RUN set -eux; \
\
wget -q "$PYTHON_GET_PIP_URL"; \
\
"${PYTHON_ROOT}/2/bin/python${PYTHON2_VERSION%.*}" get-pip.py \
--disable-pip-version-check \
--no-cache-dir \
"pip==$PYTHON2_PIP_VERSION" \
"setuptools==$PYTHON2_SETUPTOOLS_VERSION" \
"wheel==$PYTHON2_WHEEL_VERSION"
"${PYTHON_ROOT}/2.7/bin/python${PYTHON217_VERSION%.*}" get-pip.py \
--disable-pip-version-check

# add some soft links for comfortable usage
WORKDIR "${PYTHON_ROOT}/2/bin"
WORKDIR "${PYTHON_ROOT}/2.7/bin"
RUN set -eux; \
\
ln -s idle idle2; \
ln -s "python${PYTHON2_VERSION%.*}" python2; \
ln -s "python${PYTHON2_VERSION%.*}" python; \
ln -s "python${PYTHON2_VERSION%.*}-config" python-config
ln -svT idle idle2; \
ln -svT "python${PYTHON217_VERSION%.*}" python2; \
ln -svT "python${PYTHON217_VERSION%.*}" python; \
ln -svT "python${PYTHON217_VERSION%.*}-config" python-config

# >============================================================================<

FROM builder AS python3-builder
FROM builder AS python312-builder

ENV PYTHON3_VERSION=3.12.7
ENV PYTHON312_VERSION=3.12.7

WORKDIR /tmp

RUN set -eux; \
\
wget -q "https://www.python.org/ftp/python/${PYTHON3_VERSION%%[a-z]*}/Python-${PYTHON3_VERSION}.tgz"; \
tar -zxf "Python-${PYTHON3_VERSION}.tgz"
wget -q "https://www.python.org/ftp/python/${PYTHON312_VERSION%%[a-z]*}/Python-${PYTHON312_VERSION}.tgz"; \
tar -zxf "Python-${PYTHON312_VERSION}.tgz"

WORKDIR "/tmp/Python-${PYTHON3_VERSION}"
WORKDIR "/tmp/Python-${PYTHON312_VERSION}"

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN set -eux; \
\
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
./configure \
--build="$gnuArch" \
--prefix="${PYTHON_ROOT}/3/" \
--prefix="${PYTHON_ROOT}/3.12/" \
--enable-loadable-sqlite-extensions \
--enable-optimizations \
--enable-option-checking=fatal \
--enable-shared \
--with-lto \
--with-system-expat \
--without-ensurepip \
--with-ensurepip \
; \
nproc="$(nproc)"; \
EXTRA_CFLAGS="$(dpkg-buildflags --get CFLAGS)"; \
Expand All @@ -251,7 +243,7 @@ RUN set -eux; \
; \
make altinstall; \
\
echo "${PYTHON_ROOT}/3/lib" | tee /etc/ld.so.conf.d/python3.conf; \
echo "${PYTHON_ROOT}/3.12/lib" | tee /etc/ld.so.conf.d/python3.12.conf; \
ldconfig; \
\
find "${PYTHON_ROOT}" -depth \
Expand All @@ -261,50 +253,108 @@ RUN set -eux; \
\) -exec rm -rf '{}' + \
;

# if this is called "PIP_VERSION", pip explodes with "ValueError: invalid truth value '<VERSION>'"
ENV PYTHON3_PIP_VERSION=24.2
ENV PYTHON3_SETUPTOOLS_VERSION=75.1.0
ENV PYTHON3_WHEEL_VERSION=0.44.0
# https://github.com/pypa/get-pip
ENV PYTHON_GET_PIP_URL=https://raw.githubusercontent.com/pypa/get-pip/HEAD/public/get-pip.py
# add some soft links for comfortable usage
WORKDIR "${PYTHON_ROOT}/3.12/bin"
RUN set -eux; \
\
ln -svT "2to3-${PYTHON312_VERSION%.*}" 2to3; \
ln -svT "idle${PYTHON312_VERSION%.*}" idle3; \
ln -svT "idle${PYTHON312_VERSION%.*}" idle; \
ln -svT "pip${PYTHON312_VERSION%.*}" pip3; \
ln -svT "pip${PYTHON312_VERSION%.*}" pip; \
ln -svT "pydoc${PYTHON312_VERSION%.*}" pydoc; \
ln -svT "python${PYTHON312_VERSION%.*}" python3; \
ln -svT "python${PYTHON312_VERSION%.*}" python; \
ln -svT "python${PYTHON312_VERSION%.*}-config" python-config

# >============================================================================<

FROM builder AS python313-builder

ENV PYTHON313_VERSION=3.13.0

WORKDIR /tmp

RUN set -eux; \
\
wget -q "$PYTHON_GET_PIP_URL"; \
wget -q "https://www.python.org/ftp/python/${PYTHON313_VERSION%%[a-z]*}/Python-${PYTHON313_VERSION}.tgz"; \
tar -zxf "Python-${PYTHON313_VERSION}.tgz"

WORKDIR "/tmp/Python-${PYTHON313_VERSION}"

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN set -eux; \
\
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
./configure \
--build="$gnuArch" \
--prefix="${PYTHON_ROOT}/3.13/" \
--enable-loadable-sqlite-extensions \
--enable-optimizations \
--enable-option-checking=fatal \
--enable-shared \
--with-lto \
--with-system-expat \
--with-ensurepip \
; \
nproc="$(nproc)"; \
EXTRA_CFLAGS="$(dpkg-buildflags --get CFLAGS)"; \
LDFLAGS="$(dpkg-buildflags --get LDFLAGS)"; \
LDFLAGS="${LDFLAGS:--Wl},--strip-all"; \
make -s -j "$nproc" \
"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}" \
"LDFLAGS=${LDFLAGS:-}" \
"PROFILE_TASK=${PROFILE_TASK:-}" \
; \
\
# https://github.com/docker-library/python/issues/784
# prevent accidental usage of a system installed libpython of the same version
rm python; \
make -s -j "$nproc" \
"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}" \
"LDFLAGS=${LDFLAGS:--Wl},-rpath='\$\$ORIGIN/../lib'" \
"PROFILE_TASK=${PROFILE_TASK:-}" \
python \
; \
make altinstall; \
\
export PYTHONDONTWRITEBYTECODE=1; \
echo "${PYTHON_ROOT}/3.13/lib" | tee /etc/ld.so.conf.d/python3.13.conf; \
ldconfig; \
\
"${PYTHON_ROOT}/3/bin/python${PYTHON3_VERSION%.*}" get-pip.py \
--disable-pip-version-check \
--no-cache-dir \
--no-compile \
"pip==$PYTHON3_PIP_VERSION" \
"setuptools==$PYTHON3_SETUPTOOLS_VERSION" \
"wheel==$PYTHON3_WHEEL_VERSION"
find "${PYTHON_ROOT}" -depth \
\( \
\( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \
-o \( -type f -a \( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \) \) \
\) -exec rm -rf '{}' + \
;

# add some soft links for comfortable usage
WORKDIR "${PYTHON_ROOT}/3/bin"
WORKDIR "${PYTHON_ROOT}/3.13/bin"
RUN set -eux; \
\
ln -s "idle${PYTHON3_VERSION%.*}" idle3; \
ln -s "idle${PYTHON3_VERSION%.*}" idle; \
ln -s "pydoc${PYTHON3_VERSION%.*}" pydoc; \
ln -s "python${PYTHON3_VERSION%.*}" python3; \
ln -s "python${PYTHON3_VERSION%.*}" python; \
ln -s "python${PYTHON3_VERSION%.*}-config" python-config
ln -svT "idle${PYTHON313_VERSION%.*}" idle3; \
ln -svT "idle${PYTHON313_VERSION%.*}" idle; \
ln -svT "pip${PYTHON313_VERSION%.*}" pip3; \
ln -svT "pip${PYTHON313_VERSION%.*}" pip; \
ln -svT "pydoc${PYTHON313_VERSION%.*}" pydoc; \
ln -svT "python${PYTHON313_VERSION%.*}" python3; \
ln -svT "python${PYTHON313_VERSION%.*}" python; \
ln -svT "python${PYTHON313_VERSION%.*}-config" python-config

# >============================================================================<

FROM base AS final

COPY --from=git-builder /usr/local /usr/local
COPY --from=python2-builder ${PYTHON_ROOT}/2/ ${PYTHON_ROOT}/2/
COPY --from=python2-builder /etc/ld.so.conf.d/python2.conf /etc/ld.so.conf.d/python2.conf
COPY --from=python3-builder ${PYTHON_ROOT}/3/ ${PYTHON_ROOT}/3/
COPY --from=python3-builder /etc/ld.so.conf.d/python3.conf /etc/ld.so.conf.d/python3.conf
COPY --from=python27-builder ${PYTHON_ROOT}/2.7/ ${PYTHON_ROOT}/2.7/
COPY --from=python27-builder /etc/ld.so.conf.d/python2.7.conf /etc/ld.so.conf.d/python2.7.conf
COPY --from=python312-builder ${PYTHON_ROOT}/3.12/ ${PYTHON_ROOT}/3.12/
COPY --from=python312-builder /etc/ld.so.conf.d/python3.12.conf /etc/ld.so.conf.d/python3.12.conf
COPY --from=python313-builder ${PYTHON_ROOT}/3.13/ ${PYTHON_ROOT}/3.13/
COPY --from=python313-builder /etc/ld.so.conf.d/python3.13.conf /etc/ld.so.conf.d/python3.13.conf

# ensure local python is preferred over distribution python
ENV PATH="${PYTHON_ROOT}/3/bin:${PYTHON_ROOT}/2/bin:$PATH"
ENV PATH="${PYTHON_ROOT}/3.13/bin:${PYTHON_ROOT}/3.12/bin:${PYTHON_ROOT}/2.7/bin:$PATH"

# link Python libraries
RUN set -eux; \
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
[![Docker Repository on Docker Hub](https://img.shields.io/badge/hub.docker.com-white?logo=docker "Docker Repository on Docker Hub")](https://hub.docker.com/r/coatldev/six)
[![Docker Repository on Quay](https://img.shields.io/badge/quay.io-red?logo=red-hat "Docker Repository on Quay")](https://quay.io/repository/coatldev/six)

Docker image based on Ubuntu 24.04 (Noble Numbat) with Python 3.12 and 2.7.18
pre-installed.
Docker image based on Ubuntu 24.04 (Noble Numbat) with Python 3.13, 3.12 and
2.7.18 pre-installed.

## Supported tags

- [`3.12`, `latest`]
- [`3.13`, `3.13.0`, `latest`]

For the full list of supported tags, see:

Expand Down Expand Up @@ -139,9 +139,10 @@ Based on the [Docker "Official Image"] for [python] using the following

- [2.7/buster/slim]
- [3.12/slim-bullseye]
- [3.13/slim-bullseye]

<!-- External links -->
[`3.12`, `latest`]: https://github.com/coatl-dev/docker-six/blob/coatl/Dockerfile
[`3.13`, `3.13.0`, `latest`]: https://github.com/coatl-dev/docker-six/blob/coatl/Dockerfile
[Azure Pipelines]: https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/jobs-job-container?view=azure-pipelines
[GitHub Workflows]: https://docs.github.com/en/actions/using-jobs/running-jobs-in-a-container
[Docker Hub]: https://hub.docker.com/r/coatldev/six
Expand All @@ -153,3 +154,4 @@ Based on the [Docker "Official Image"] for [python] using the following
<!-- Inspiration -->
[2.7/buster/slim]: https://github.com/docker-library/python/blob/f1e613f48eb4fc88748b36787f5ed74c14914636/2.7/buster/slim/Dockerfile
[3.12/slim-bullseye]: https://github.com/docker-library/python/blob/HEAD/3.12/slim-bullseye/Dockerfile
[3.13/slim-bullseye]: https://github.com/docker-library/python/blob/HEAD/3.13/slim-bullseye/Dockerfile
3 changes: 0 additions & 3 deletions requirements/base.in

This file was deleted.

14 changes: 0 additions & 14 deletions requirements/base.txt

This file was deleted.

0 comments on commit 546d325

Please sign in to comment.