1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ # --- Builder Stage ---
16+ # This stage installs all build dependencies and compiles all Python versions.
1517FROM marketplace.gcr.io/google/ubuntu2404 AS builder
1618
1719# TODO(https://github.com/googleapis/librarian/issues/901): Install the necssary dependencies and build tools.
@@ -38,54 +40,85 @@ RUN apt-get update && \
3840# Set up environment variables for tool versions to make updates easier.
3941ENV BAZELISK_VERSION=v1.26.0
4042
43+ # Install multiple Python versions from source. `make altinstall` is used to
44+ # prevent replacing the system's default python binary.
4145RUN for PYTHON_VERSION in 3.9.23 3.10.18 3.11.13 3.12.11 3.13.5; do \
42- # Install Python from source
4346 wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \
4447 tar -xvf Python-${PYTHON_VERSION}.tgz && \
4548 cd Python-${PYTHON_VERSION} && \
46- ./configure --enable-optimizations && \
49+ ./configure --enable-optimizations --prefix=/usr/local && \
50+ make -j$(nproc) && \
4751 make altinstall && \
4852 cd / && \
4953 rm -rf Python-${PYTHON_VERSION}* \
5054 ; done
5155
52- # Get the pip installation script using the instructions below
53- # https://pip.pypa.io/en/stable/installation/#get-pip-py
54- # Attempts to use `ensurepip` instead of `get-pip.py` resulted in errors like `python3.13.5 not found`
55- RUN wget --no-check-certificate -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py'
56-
5756# Install pip for each python version
58- RUN for PYTHON_VERSION in 3.9 3.10 3.11 3.12 3.13; do \
59- python${PYTHON_VERSION} /tmp/get-pip.py \
60- ; done
61-
62- # Remove the pip installation script
63- RUN rm /tmp/get-pip.py
64-
65- # Test Pip
66- RUN for PYTHON_VERSION in 3.9 3.10 3.11 3.12 3.13; do \
67- python${PYTHON_VERSION} -m pip \
68- ; done
69-
70-
71- # TODO(https://github.com/googleapis/librarian/issues/904): Install protoc for gencode.
57+ RUN wget --no-check-certificate -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py' && \
58+ for PYTHON_VERSION in 3.9 3.10 3.11 3.12 3.13; do \
59+ python${PYTHON_VERSION} /tmp/get-pip.py; \
60+ done && \
61+ rm /tmp/get-pip.py
7262
7363# Install Bazelisk
7464RUN wget https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-amd64 -O /usr/local/bin/bazelisk && \
7565 chmod +x /usr/local/bin/bazelisk
7666
77- # TODO(https://github.com/googleapis/librarian/issues/902): Create a dedicate non-root user and
78- # switch to the non-root user to run subsequent commands.
79-
80- # Set the working directory in the container.
67+ # Set the working directory for build-related tasks.
8168WORKDIR /app
8269
70+ # TODO(https://github.com/googleapis/librarian/issues/904): Install protoc for gencode.
8371# TODO(https://github.com/googleapis/librarian/issues/907): Install Python dependencies from requirements.in.
8472# TODO(https://github.com/googleapis/librarian/issues/905): Install Synthtool by cloning its repo.
8573# TODO(https://github.com/googleapis/librarian/issues/906): Clone googleapis and run bazelisk build.
8674
87- # Copy the CLI script into the container and set ownership.
75+ # --- Final Stage ---
76+ # This stage creates the lightweight final image, copying only the
77+ # necessary artifacts from the builder stage.
78+ FROM marketplace.gcr.io/google/ubuntu2404
79+
80+ # Install only the essential runtime libraries for Python.
81+ # These are the non "-dev" versions of the libraries used in the builder.
82+ RUN apt-get update && \
83+ apt-get install -y --no-install-recommends \
84+ ca-certificates \
85+ libssl3 \
86+ zlib1g \
87+ libbz2-1.0 \
88+ libffi8 \
89+ libsqlite3-0 \
90+ libreadline8 \
91+ && apt-get clean && \
92+ rm -rf /var/lib/apt/lists/*
93+
94+ # TODO(https://github.com/googleapis/librarian/issues/902): Create a dedicate non-root user and
95+ # switch to the non-root user to run subsequent commands.
96+ # Example:
97+ # RUN groupadd --system --gid 1000 appgroup && \
98+ # useradd --system --uid 1000 --gid appgroup appuser
99+ # USER appuser
100+
101+ # Copy all Python interpreters, their pip executables, and their standard libraries from the builder.
102+ COPY --from=builder /usr/local/bin/python3.9 /usr/local/bin/
103+ COPY --from=builder /usr/local/lib/python3.9 /usr/local/lib/python3.9
104+
105+ COPY --from=builder /usr/local/bin/python3.10 /usr/local/bin/
106+ COPY --from=builder /usr/local/lib/python3.10 /usr/local/lib/python3.10
107+
108+ COPY --from=builder /usr/local/bin/python3.11 /usr/local/bin/
109+ COPY --from=builder /usr/local/lib/python3.11 /usr/local/lib/python3.11
110+
111+ COPY --from=builder /usr/local/bin/python3.12 /usr/local/bin/
112+ COPY --from=builder /usr/local/lib/python3.12 /usr/local/lib/python3.12
113+
114+ COPY --from=builder /usr/local/bin/python3.13 /usr/local/bin/
115+ COPY --from=builder /usr/local/lib/python3.13 /usr/local/lib/python3.13
116+
117+ # Set the working directory in the container.
118+ WORKDIR /app
119+
120+ # Copy the CLI script into the container.
88121COPY .generator/cli.py .
89122
90123# Set the entrypoint for the container to run the script.
91- ENTRYPOINT ["python3.11" , "./cli.py" ]
124+ ENTRYPOINT ["python3.11" , "./cli.py" ]
0 commit comments