diff --git a/release/docker/Dockerfile b/release/docker/Dockerfile new file mode 100644 index 000000000..425828e01 --- /dev/null +++ b/release/docker/Dockerfile @@ -0,0 +1,74 @@ +# 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 + +RUN apt-get install -yq --no-install-recommends python${PYTHON_VERSION} \ + python${PYTHON_VERSION}-dev python${PYTHON_VERSION}-venv 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 && \ + 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"] diff --git a/release/docker/README.md b/release/docker/README.md new file mode 100644 index 000000000..0db235656 --- /dev/null +++ b/release/docker/README.md @@ -0,0 +1,32 @@ +# 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 and tutorials in relatively isolated +environments. + +The script [`create_docker_images.sh`](create_docker_images.sh) creates separate +images with a range of Python versions (currently 3.9–3.12) installed in +Ubuntu 22.04 and 24.04. The result is a set of 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 configuration in `Dockerfile` 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 container +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. diff --git a/release/docker/create_docker_images.sh b/release/docker/create_docker_images.sh new file mode 100755 index 000000000..76022042d --- /dev/null +++ b/release/docker/create_docker_images.sh @@ -0,0 +1,68 @@ +#!/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=() + +ubuntu_versions+=( "22.04" "24.04" ) +python_versions+=( "3.9" "3.10" "3.11" "3.12" ) + +usage="Usage: ${0} [OPTIONS] + +Build a set of basic Ubuntu Linux x86_64 Docker images with +Python preinstalled. + +General options: + -h Show this help message and exit + -v Run Docker build with verbose progress output" + +while getopts "hv" opt; do + case "${opt}" in + h) echo "${usage}"; exit 0 ;; + v) export BUILDKIT_PROGRESS=plain ;; + ?) echo "${usage}"; exit 1 ;; + esac +done + +total_items=$(( ${#ubuntu_versions[@]} * ${#python_versions[@]})) +echo "Building a total of ${total_items} Docker images." + +start_time="$(date +"%Y-%m-%d-%H%M")" +for os_version in "${ubuntu_versions[@]}"; do + for py_version in "${python_versions[@]}"; do + echo + echo "~~~~ Python ${py_version} on Ubuntu ${os_version}" + # shellcheck disable=SC2086 # Lack of quotes around vars is ok here. + docker build --no-cache --label "build-datetime=${start_time}" \ + --build-arg PYTHON_VERSION="${py_version}" \ + --build-arg UBUNTU_VERSION="${os_version}" \ + -t ubuntu${os_version%%.*}-cp${py_version//./}:latest . + done +done + +echo +echo "~~~~ Done. The following Docker images were created:" +echo +docker images --filter "label=build-datetime=${start_time}"