Skip to content

Commit 7dfa7a6

Browse files
authored
Add new scripts for creating Docker containers to enable better testing of TFQ builds (#952)
This adds a new subdirectory `release/docker/` that contains a `Dockerfile` and a script to create Docker images. These are useful for testing TensorFlow Quantum builds in more isolated environments with different versions of Python. The setup is not fancy, but it is useful when (e.g.) trying different combinations of dependencies with different Python versions. Running the script `create_docker_images.sh` in that directory creates a total of eight images, with names like `ubuntu22-cp310`, `ubuntu22-cp311`, etc. The images are based on Ubuntu Linux 22.04 and 24.04, with the addition of Python preinstalled and very little else. More information can be found in the README file `release/docker/README.md`.
1 parent f73e642 commit 7dfa7a6

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

release/docker/Dockerfile

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Copyright 2025 The TensorFlow Quantum Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# =============================================================================
15+
16+
# Summary: build file for making isolated Docker environments for testing.
17+
# This accepts 2 optional build arguments to set the Ubuntu & Python versions.
18+
# Usage example:
19+
#
20+
# docker build --no-cache --build-arg PYTHON_VERSION=3.10 \
21+
# --build-arg UBUNTU_VERSION=24.04 -t my-image:latest .
22+
#
23+
# Note that the name and tag ("my-image" and "latest" in the example above) are
24+
# yours to choose. They're not set using the arguments or linked to their values.
25+
26+
# Default values for build arguments:
27+
ARG PYTHON_VERSION=3.10
28+
ARG UBUNTU_VERSION=22.04
29+
30+
FROM ubuntu:${UBUNTU_VERSION}
31+
32+
# Make the Python version argument visible to the rest of this file after FROM.
33+
ARG PYTHON_VERSION
34+
ENV PYTHON_VERSION=${PYTHON_VERSION}
35+
36+
ENV LANG=C.UTF-8
37+
ENV LC_ALL=C.UTF-8
38+
ENV DEBIAN_FRONTEND=noninteractive
39+
40+
# Ensure the shell is Bash.
41+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
42+
43+
# Tell the Dockerfile linter not to warn about how we use apt.
44+
# hadolint global ignore=DL3008,DL3009
45+
46+
RUN apt-get -q update -q && \
47+
apt-get install -y --no-install-recommends ca-certificates \
48+
pkg-config gnupg curl lsb-release git zip unzip
49+
50+
# We avoid the use of "add-apt-repository" because it is only available from the
51+
# "software-properties-common" package, and installing that package brings in a
52+
# lot of other unrelated unnecessary packages. Instead, we fetch the GPG key for
53+
# the deadsnakes package archive and install it where apt can find it.
54+
ENV ID=0xF23C5A6CF475977595C89F51BA6932366A755776
55+
ENV GPG_FILE="/etc/apt/trusted.gpg.d/deadsnakes.gpg"
56+
RUN curl -sSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=${ID}" | \
57+
gpg --dearmor -o ${GPG_FILE}
58+
59+
ENV PPA_URL="https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu"
60+
ENV APT_FILE="/etc/apt/sources.list.d/deadsnakes.list"
61+
RUN echo "deb [signed-by=${GPG_FILE}] ${PPA_URL} $(lsb_release -cs) main" > "${APT_FILE}"
62+
63+
RUN apt-get -q update -q && \
64+
apt-get install -yq --no-install-recommends make clang g++ zlib1g-dev \
65+
python${PYTHON_VERSION} python${PYTHON_VERSION}-dev \
66+
python${PYTHON_VERSION}-venv python-is-python3
67+
68+
# Use update-alternatives to make the desired version be the default.
69+
# hadolint ignore=SC3010
70+
RUN python_path="" bin="/usr/bin" && \
71+
case "$(lsb_release -rs)" in \
72+
"24.04") python_path="${bin}/python3.12" ;; \
73+
"22.04") python_path="${bin}/python3.10" ;; \
74+
"20.04") python_path="${bin}/python3.8" ;; \
75+
*) python_path=$(readlink -f ${bin}/python3) ;; \
76+
esac && \
77+
update-alternatives --install ${bin}/python3 python3 "${python_path}" 1 && \
78+
update-alternatives --install ${bin}/python3 python3 "${bin}/python${PYTHON_VERSION}" 2
79+
80+
# Install pip, trying ensurepip first and falling back to get-pip.py.
81+
RUN export PIP_BREAK_SYSTEM_PACKAGES=1 PIP_ROOT_USER_ACTION=ignore && \
82+
(python3 -m ensurepip --upgrade --default-pip || \
83+
(curl -sS https://bootstrap.pypa.io/get-pip.py | python3)) && \
84+
python3 -m pip install --no-cache-dir --upgrade 'pip>19'
85+
86+
# Clean up before finishing.
87+
RUN apt-get clean
88+
89+
CMD ["/bin/bash"]

release/docker/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Docker images for basic testing
2+
3+
This directory contains a [`Dockerfile`](Dockerfile) for creating Ubuntu
4+
containers with Python installed and very little else compared to the stock
5+
Ubuntu images from https://hub.docker.com/_/ubuntu/. These can be used for
6+
testing TensorFlow Quantum builds and tutorials in relatively isolated
7+
environments.
8+
9+
The script [`create_docker_images.sh`](create_docker_images.sh) creates separate
10+
images with a range of Python versions installed in Ubuntu 22.04 and 24.04. The
11+
result is a set of images with names like `ubuntu22-cp310`, `ubuntu22-cp311`,
12+
etc. The script `create_docker_images.sh` is meant to be run simply like this:
13+
14+
```shell
15+
./create_docker_images.sh
16+
```
17+
18+
The configuration in `Dockerfile` runs a Bash shell as the last step if a
19+
container is not started with any other command to run. When combined with
20+
Docker's `-v` argument, you can easily run commands inside the container
21+
environment while accessing your TensorFlow Quantum source files. For example:
22+
23+
```shell
24+
# The next cd command moves to the root of the source tree.
25+
cd $(git rev-parse --show-toplevel)
26+
docker run -it --rm --network host -v .:/tfq ubuntu24-cp312
27+
```
28+
29+
will leave you with a shell prompt inside a basic Ubuntu 24.04 environment with
30+
Python 3.12 preinstalled and your local TensorFlow Quantum source directory
31+
accessible at `/tfq` from inside the container.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
# Copyright 2025 The TensorFlow Quantum Authors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
# =============================================================================
16+
17+
# Summary: create a set of Docker images for testing TFQ distributions.
18+
# This loops over a set of Ubuntu versions and Python versions, and builds
19+
# Docker images using the Dockerfile in this directory.
20+
#
21+
# Example of how the resulting images can be run
22+
# docker run -it --rm --network host -v .:/tfq ubuntu22-cp310
23+
24+
set -e
25+
26+
declare -a ubuntu_versions=()
27+
declare -a python_versions=()
28+
29+
ubuntu_versions+=( "22.04" "24.04" )
30+
python_versions+=( "3.10" "3.11" "3.12" "3.13" )
31+
32+
usage="Usage: ${0} [OPTIONS]
33+
34+
Build a set of basic Ubuntu Linux x86_64 Docker images with
35+
Python preinstalled.
36+
37+
General options:
38+
-h Show this help message and exit
39+
-v Run Docker build with verbose progress output"
40+
41+
while getopts "hv" opt; do
42+
case "${opt}" in
43+
h) echo "${usage}"; exit 0 ;;
44+
v) export BUILDKIT_PROGRESS=plain ;;
45+
?) echo "${usage}"; exit 1 ;;
46+
esac
47+
done
48+
49+
total_items=$(( ${#ubuntu_versions[@]} * ${#python_versions[@]}))
50+
echo "Building a total of ${total_items} Docker images."
51+
52+
start_time="$(date +"%Y-%m-%d-%H%M")"
53+
for os_version in "${ubuntu_versions[@]}"; do
54+
for py_version in "${python_versions[@]}"; do
55+
echo
56+
echo "~~~~ Python ${py_version} on Ubuntu ${os_version}"
57+
# shellcheck disable=SC2086 # Lack of quotes around vars is ok here.
58+
docker build --no-cache --label "build-datetime=${start_time}" \
59+
--build-arg PYTHON_VERSION="${py_version}" \
60+
--build-arg UBUNTU_VERSION="${os_version}" \
61+
-t ubuntu${os_version%%.*}-cp${py_version//./}:latest .
62+
done
63+
done
64+
65+
echo
66+
echo "~~~~ Done. The following Docker images were created:"
67+
echo
68+
docker images --filter "label=build-datetime=${start_time}"

0 commit comments

Comments
 (0)