@@ -65,6 +65,9 @@ FROM ubuntu:22.04 AS python-builder
6565# Prevent interactive prompts during package installation
6666ENV DEBIAN_FRONTEND=noninteractive
6767
68+ # Accept architecture from Docker BuildKit (for multi-arch builds)
69+ ARG TARGETARCH
70+
6871# Install minimal dependencies for downloading
6972RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
7073 --mount=type=cache,target=/var/lib/apt,sharing=locked \
@@ -75,15 +78,23 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
7578
7679# Download and extract pre-built Python 3.11.14 from python-build-standalone
7780# Using PGO+LTO optimized builds for better performance
81+ # Supports multi-arch: amd64 (x86_64) and arm64 (aarch64)
7882RUN --mount=type=cache,target=/tmp/python-cache \
83+ # Map Docker TARGETARCH to python-build-standalone arch naming
84+ if [ "$TARGETARCH" = "amd64" ]; then \
85+ PYTHON_ARCH="x86_64-unknown-linux-gnu" ; \
86+ elif [ "$TARGETARCH" = "arm64" ]; then \
87+ PYTHON_ARCH="aarch64-unknown-linux-gnu" ; \
88+ else \
89+ echo "Unsupported architecture: $TARGETARCH" && exit 1; \
90+ fi && \
7991 cd /tmp/python-cache && \
80- wget -nc https://github.com/indygreg/python-build-standalone/releases/download/20251028/cpython-3.11.14+20251028-aarch64-unknown-linux-gnu -install_only.tar.gz && \
92+ wget -nc https://github.com/indygreg/python-build-standalone/releases/download/20251028/cpython-3.11.14+20251028-${PYTHON_ARCH} -install_only.tar.gz && \
8193 cd /tmp && \
82- tar -xzf /tmp/python-cache/cpython-3.11.14+20251028-aarch64-unknown-linux-gnu -install_only.tar.gz && \
94+ tar -xzf /tmp/python-cache/cpython-3.11.14+20251028-${PYTHON_ARCH} -install_only.tar.gz && \
8395 mv python /usr/local/ && \
8496 # Create symlinks for standard Python locations
8597 ln -s /usr/local/python/bin/python3.11 /usr/local/bin/python3.11 && \
86- ln -s /usr/local/python/lib /usr/local/lib/python && \
8798 rm -rf /tmp/cpython-*
8899
89100# ============================================================================
@@ -106,7 +117,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
106117 rm -f /etc/apt/apt.conf.d/docker-clean && \
107118 echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
108119 apt-get update && apt-get install -y --no-install-recommends \
109- ca-certificates curl wget procps git unzip zip jq file binutils \
120+ ca-certificates curl wget procps git unzip zip jq \
110121 libssl3 zlib1g libbz2-1.0 libreadline8 libsqlite3-0 \
111122 libncursesw6 libtinfo6 libxml2 libxmlsec1 libffi8 liblzma5 libtk8.6 && \
112123 update-ca-certificates
@@ -117,21 +128,18 @@ COPY --from=python-builder /usr/local/python /usr/local/python
117128# Create symlinks and update shared library cache
118129RUN ln -s /usr/local/python/bin/python3.11 /usr/local/bin/python3.11 && \
119130 ln -s /usr/local/python/bin/python3 /usr/local/bin/python3 && \
131+ ln -s /usr/local/python/bin/pip3 /usr/local/bin/pip3 && \
120132 echo "/usr/local/python/lib" > /etc/ld.so.conf.d/python.conf && \
121133 ldconfig
122134
123- # Set Python 3.11 as default python3, install pip, and clean up
135+ # Set Python 3.11 as default python3 and clean up
124136RUN update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.11 1 && \
125- /usr/local/bin/python3.11 -m ensurepip && \
126- /usr/local/bin/python3.11 -m pip install --no-cache-dir --upgrade pip && \
127137 # Remove unnecessary Python files to reduce image size
128138 find /usr/local/python/lib -type d -name "test" -exec rm -rf {} + 2>/dev/null || true && \
129139 find /usr/local/python/lib -type d -name "tests" -exec rm -rf {} + 2>/dev/null || true && \
130140 find /usr/local/python/lib -name "*.pyc" -delete && \
131141 find /usr/local/python/lib -name "*.pyo" -delete && \
132- find /usr/local/python/lib -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true && \
133- # Strip debug symbols from Python binary (already stripped in pre-built)
134- strip /usr/local/python/bin/python3.11 2>/dev/null || true
142+ find /usr/local/python/lib -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
135143
136144# Install Python packages and clean up
137145RUN --mount=type=cache,target=/root/.cache/pip \
@@ -140,17 +148,13 @@ RUN --mount=type=cache,target=/root/.cache/pip \
140148 find /usr/local/python/lib/python3.11/site-packages -type d -name "test" -exec rm -rf {} + 2>/dev/null || true && \
141149 find /usr/local/python/lib/python3.11/site-packages -type d -name "tests" -exec rm -rf {} + 2>/dev/null || true && \
142150 find /usr/local/python/lib/python3.11/site-packages -name "*.pyc" -delete && \
143- find /usr/local/python/lib/python3.11/site-packages -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true && \
144- # Strip debug symbols from .so files
145- find /usr/local/python/lib/python3.11/site-packages -name "*.so" -exec strip {} \; 2>/dev/null || true && \
146- # Remove binutils after stripping
147- apt-get remove -y binutils && apt-get autoremove -y
151+ find /usr/local/python/lib/python3.11/site-packages -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
148152
149- # Install Node.js 20 LTS using official NodeSource setup script
150- RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
151- --mount=type=cache,target=/var/ lib/apt,sharing=locked \
152- curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
153- && apt-get install -y nodejs
153+ # Install Node.js 20 LTS from official Node image
154+ COPY --from=node:20-slim /usr/local/bin/node /usr/local/bin/node
155+ COPY --from=node:20-slim /usr/local/ lib/node_modules /usr/local/lib/node_modules
156+ RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
157+ ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
154158
155159# Install Bun runtime from official image
156160COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
0 commit comments