Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions release/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Copyright 2025 The TensorFlow Quantum Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================

# Summary: build file for making isolated Docker environments for testing.
# This accepts 2 optional build arguments to set the Ubuntu & Python versions.
# Usage example:
#
# docker build --no-cache --build-arg PYTHON_VERSION=3.9 \
# --build-arg UBUNTU_VERSION=24.04 -t my-image:latest .
#
# Note that the name and tag ("my-image" and "latest" in the example above) are
# yours to choose. They're not set using the arguments or linked to their values.

# Default values for build arguments:
ARG PYTHON_VERSION=3.9
ARG UBUNTU_VERSION=22.04

FROM ubuntu:${UBUNTU_VERSION}

# Make the Python version argument visible to the rest of this file after FROM.
ARG PYTHON_VERSION
ENV PYTHON_VERSION=${PYTHON_VERSION}

ENV TZ=UTC
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive

# Ensure the shell is Bash.
SHELL ["/bin/bash", "-e", "-c"]

# Tell the Dockerfile linter not to warn about how we use apt.
# hadolint global ignore=DL3008,DL3009

# Add the deadsnakes Python package archive to access older Python versions.
RUN apt-get update -q && \
apt-get install -yq --no-install-recommends software-properties-common \
gnupg pkg-config git zip unzip zlib1g-dev && \
add-apt-repository -y ppa:deadsnakes/ppa && \
apt-get update -q

# The following conditional is to handle Python 3.12's removal of distutils.
RUN distutils_pkg="python${PYTHON_VERSION}-distutils" && \
if [[ "${PYTHON_VERSION#*.}" -ge 12 ]]; then \
distutils_pkg="python3-setuptools"; \
fi && \
apt-get install -yq --no-install-recommends python${PYTHON_VERSION} \
python${PYTHON_VERSION}-dev python${PYTHON_VERSION}-venv ${distutils_pkg} \
python3-pip python-is-python3

# Use update-alternatives to make the desired version be the default.
# hadolint ignore=SC3010
RUN python_path="" bin="/usr/bin" && \
case "$(lsb_release -rs)" in \
"24.04") python_path="${bin}/python3.12" ;; \
"22.04") python_path="${bin}/python3.10" ;; \
"20.04") python_path="${bin}/python3.8" ;; \
*) python_path=$(readlink -f ${bin}/python3) ;; \
esac && \
if [[ ! -f "${python_path}" ]]; then \
echo "ERROR: ${python_path} does not exist." >&2; \
exit 1; \
fi && \
update-alternatives --install ${bin}/python3 python3 "${python_path}" 1 && \
update-alternatives --install ${bin}/python3 python3 "${bin}/python${PYTHON_VERSION}" 2

# Clean up before finishing.
# hadolint ignore=DL3027
RUN apt clean

CMD ["/bin/bash"]
31 changes: 31 additions & 0 deletions release/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Docker images for basic testing

This directory contains a [`Dockerfile`](Dockerfile) for creating Ubuntu
containers with Python installed and very little else compared to the stock
Ubuntu images from https://hub.docker.com/_/ubuntu/. These can be used for
testing TensorFlow Quantum builds in relatively isolated environments.

The script [`create_docker_images.sh`](create_docker_images.sh) creates
separate images with Python 3.9–3.12 installed in Ubuntu 22.04 and 24.04.
The result is a total of eight images, with names like `ubuntu22-cp39`,
`ubuntu22-cp310`, etc. The script `create_docker_images.sh` is meant to be run
simply like this:

```shell
./create_docker_images.sh
```

The Dockerfile configuration runs a Bash shell as the last step if a container
is not started with any other command to run. When combined with Docker's `-v`
argument, you can easily run commands inside the containere environment while
accessing your TensorFlow Quantum source files. For example:

```shell
# The next cd command moves to the root of the source tree.
cd $(git rev-parse --show-toplevel)
docker run -it --rm --network host -v .:/tfq ubuntu24-cp312
```

will leave you with a shell prompt inside a basic Ubuntu 24.04 environment with
Python 3.12 preinstalled and your local TensorFlow Quantum source directory
accessible at `/tfq` from inside the container.
55 changes: 55 additions & 0 deletions release/docker/create_docker_images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash
# Copyright 2025 The TensorFlow Quantum Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================

# Summary: create a set of Docker images for testing TFQ distributions.
# This loops over a set of Ubuntu versions and Python versions, and builds
# Docker images using the Dockerfile in this directory.
#
# Example of how the resulting images can be run
# docker run -it --rm --network host -v .:/tfq ubuntu22-cp39

set -e

declare -a ubuntu_versions=()
declare -a python_versions=()
declare -a docker_args=()

ubuntu_versions+=( "22.04" "24.04" )
python_versions+=( "3.9" "3.10" "3.11" "3.12" )
total_items=$(( ${#ubuntu_versions[@]} * ${#python_versions[@]}))

echo "~~~~ Building a total of ${total_items} Docker images"

# Flag --no-cache forces containers to be rebuilt.
docker_args+=( "--no-cache" )

# shellcheck disable=SC2068,SC2145
for os_version in "${ubuntu_versions[@]}"; do
for py_version in "${python_versions[@]}"; do
echo
echo "~~~~ Python ${py_version} on Ubuntu ${os_version}"
docker build \
--build-arg PYTHON_VERSION="${py_version}" \
--build-arg UBUNTU_VERSION="${os_version}" \
${docker_args[@]}\
-t ubuntu${os_version%%.*}-cp${py_version//./}:latest .
done
done

echo
echo "~~~~ Done. Created the following Docker images:"
echo
docker images --filter "reference=ubuntu*-cp*"
Loading