From 64dac6df3d5ffa1ac173f889744a98918edede88 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Tue, 14 May 2024 17:46:38 +0200 Subject: [PATCH 1/8] feat(framework:ci) add alpine base image Signed-off-by: Robert Steiner --- .github/workflows/docker-base.yml | 2 +- ...contributor-how-to-build-docker-images.rst | 2 +- src/docker/base/alpine/Dockerfile | 70 +++++++++++++++++++ src/docker/base/{ => ubuntru}/Dockerfile | 0 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/docker/base/alpine/Dockerfile rename src/docker/base/{ => ubuntru}/Dockerfile (100%) diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml index f2cd2ef99d08..080b9168dbd9 100644 --- a/.github/workflows/docker-base.yml +++ b/.github/workflows/docker-base.yml @@ -48,7 +48,7 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] with: namespace-repository: flwr/base - file-dir: src/docker/base + file-dir: src/docker/base/ubuntu build-args: | PYTHON_VERSION=${{ matrix.python-version }} PIP_VERSION=${{ needs.parameters.outputs.pip-version }} diff --git a/doc/source/contributor-how-to-build-docker-images.rst b/doc/source/contributor-how-to-build-docker-images.rst index bac201f6a7b9..3d25fcc78606 100644 --- a/doc/source/contributor-how-to-build-docker-images.rst +++ b/doc/source/contributor-how-to-build-docker-images.rst @@ -66,7 +66,7 @@ The following example creates a base image with Python 3.11.0, pip 23.0.1 and se .. code-block:: bash - $ cd src/docker/base/ + $ cd src/docker/base/ubuntu $ docker build \ --build-arg PYTHON_VERSION=3.11.0 \ --build-arg PIP_VERSION=23.0.1 \ diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile new file mode 100644 index 000000000000..03172530a77d --- /dev/null +++ b/src/docker/base/alpine/Dockerfile @@ -0,0 +1,70 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. + +# Multi-stage base image build +# +# Building the base image for ARM64 requires installing some additional system dependencies to +# compile the grpcio package, as they do not provide a pre-built package. However, we don't want +# the dependencies in the final base image as they are only needed to compile the package. +# That's why we're creating a multi-stage build. When installing the flwr, we are using a +# virtual environment to keep all files in a single isolated directory as described here: +# https://pythonspeed.com/articles/multi-stage-docker-python/ + +ARG PYTHON_VERSION=3.11 +ARG ALPINE_VERSION=alpine3.19 +FROM python:${PYTHON_VERSION}-${ALPINE_VERSION} as compile + +# Install system dependencies +RUN apk add --no-cache \ + # require for compiling grpcio on ARM64 + g++=13.2.1_git20231014-r0 \ + libffi-dev=3.4.4-r3 \ + # create virtual env + && python -m venv /opt/venv + +# Make sure we use the virtualenv +ENV PATH="/opt/venv/bin:$PATH" + +# Install specific version of pip, setuptools and flwr +ARG PIP_VERSION +ARG SETUPTOOLS_VERSION +ARG FLWR_VERSION +ARG FLWR_PACKAGE=flwr +RUN pip install -U --no-cache-dir \ + pip==${PIP_VERSION} \ + setuptools==${SETUPTOOLS_VERSION} \ + ${FLWR_PACKAGE}==${FLWR_VERSION} + +FROM python:${PYTHON_VERSION}-${ALPINE_VERSION} as base + +# required by the grpc package +RUN apk add --no-cache \ + libstdc++=13.2.1_git20231014-r0 + +COPY --from=compile /opt/venv /opt/venv + +# Make sure we use the virtualenv +ENV ENV PATH="/opt/venv/bin:$PATH" \ + # Send stdout and stderr stream directly to the terminal. Ensures that no + # output is retained in a buffer if the application crashes. + PYTHONUNBUFFERED=1 \ + # Typically, bytecode is created on the first invocation to speed up following invocation. + # However, in Docker we only make a single invocation (when we start the container). + # Therefore, we can disable bytecode writing. + PYTHONDONTWRITEBYTECODE=1 \ + # Ensure that python encoding is always UTF-8. + PYTHONIOENCODING=UTF-8 \ + LANG=C.UTF-8 \ + LC_ALL=C.UTF-8 + +# add non-root user +RUN adduser \ + --no-create-home \ + --disabled-password \ + --gecos "" \ + --uid 49999 app \ + && mkdir -p /app \ + && chown -R app:app /app + +WORKDIR /app +USER app +ENV HOME=/app diff --git a/src/docker/base/Dockerfile b/src/docker/base/ubuntru/Dockerfile similarity index 100% rename from src/docker/base/Dockerfile rename to src/docker/base/ubuntru/Dockerfile From ca8f43b3e0dfd3142db4450c600fc665543e8f90 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 16 May 2024 09:15:44 +0200 Subject: [PATCH 2/8] fix typo Signed-off-by: Robert Steiner --- src/docker/base/{ubuntru => ubuntu}/Dockerfile | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/docker/base/{ubuntru => ubuntu}/Dockerfile (100%) diff --git a/src/docker/base/ubuntru/Dockerfile b/src/docker/base/ubuntu/Dockerfile similarity index 100% rename from src/docker/base/ubuntru/Dockerfile rename to src/docker/base/ubuntu/Dockerfile From 201bb5a5dd4e77f31637f3e3d765219edd1195d5 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 16 May 2024 10:27:57 +0200 Subject: [PATCH 3/8] Add alpine to workflow Signed-off-by: Robert Steiner --- .github/workflows/docker-base.yml | 15 +++++++-------- src/docker/base/alpine/Dockerfile | 6 +++--- src/docker/base/ubuntu/Dockerfile | 4 ++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml index 080b9168dbd9..0d33bc07a197 100644 --- a/.github/workflows/docker-base.yml +++ b/.github/workflows/docker-base.yml @@ -13,9 +13,6 @@ on: permissions: contents: read -env: - DEFAULT_UBUNTU: 22.04 - jobs: parameters: name: Collect build parameters @@ -24,7 +21,6 @@ jobs: outputs: pip-version: ${{ steps.versions.outputs.pip-version }} setuptools-version: ${{ steps.versions.outputs.setuptools-version }} - ubuntu-version: ${{ steps.versions.outputs.ubuntu-version }} steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -36,7 +32,6 @@ jobs: run: | echo "pip-version=${{ steps.bootstrap.outputs.pip-version }}" >> "$GITHUB_OUTPUT" echo "setuptools-version=${{ steps.bootstrap.outputs.setuptools-version }}" >> "$GITHUB_OUTPUT" - echo "ubuntu-version=${{ env.DEFAULT_UBUNTU }}" >> "$GITHUB_OUTPUT" build-base-images: name: Build base images @@ -46,15 +41,19 @@ jobs: fail-fast: false matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] + os: + - tag: ubuntu22.04 + version: 22.04 + file-dir: src/docker/base/ubuntu with: namespace-repository: flwr/base - file-dir: src/docker/base/ubuntu + file-dir: ${{ matrix.os.file-dir }} build-args: | PYTHON_VERSION=${{ matrix.python-version }} PIP_VERSION=${{ needs.parameters.outputs.pip-version }} SETUPTOOLS_VERSION=${{ needs.parameters.outputs.setuptools-version }} - UBUNTU_VERSION=${{ needs.parameters.outputs.ubuntu-version }} - tags: py${{ matrix.python-version }}-ubuntu${{ needs.parameters.outputs.ubuntu-version }} + OS_VERSION=${{ matrix.os.version }} + tags: py${{ matrix.python-version }}-${{ matrix.os.tag }} secrets: dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index 03172530a77d..49a07ae297c6 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -10,8 +10,8 @@ # https://pythonspeed.com/articles/multi-stage-docker-python/ ARG PYTHON_VERSION=3.11 -ARG ALPINE_VERSION=alpine3.19 -FROM python:${PYTHON_VERSION}-${ALPINE_VERSION} as compile +ARG OS_VERSION=alpine3.19 +FROM python:${PYTHON_VERSION}-${OS_VERSION} as compile # Install system dependencies RUN apk add --no-cache \ @@ -34,7 +34,7 @@ RUN pip install -U --no-cache-dir \ setuptools==${SETUPTOOLS_VERSION} \ ${FLWR_PACKAGE}==${FLWR_VERSION} -FROM python:${PYTHON_VERSION}-${ALPINE_VERSION} as base +FROM python:${PYTHON_VERSION}-${OS_VERSION} as base # required by the grpc package RUN apk add --no-cache \ diff --git a/src/docker/base/ubuntu/Dockerfile b/src/docker/base/ubuntu/Dockerfile index 9cd410ba3fb5..3946c75ed650 100644 --- a/src/docker/base/ubuntu/Dockerfile +++ b/src/docker/base/ubuntu/Dockerfile @@ -1,7 +1,7 @@ # Copyright 2023 Flower Labs GmbH. All Rights Reserved. -ARG UBUNTU_VERSION=22.04 -FROM ubuntu:$UBUNTU_VERSION as base +ARG OS_VERSION=22.04 +FROM ubuntu:$OS_VERSION as base ENV DEBIAN_FRONTEND noninteractive # Send stdout and stderr stream directly to the terminal. Ensures that no From dc41f34689ec7d1bb3559b91ef070321e7a542c7 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 16 May 2024 16:11:31 +0200 Subject: [PATCH 4/8] update copyright Signed-off-by: Robert Steiner --- src/docker/base/alpine/Dockerfile | 13 +++++++++++++ src/docker/base/ubuntu/Dockerfile | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index 49a07ae297c6..8447ca1411c4 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -1,4 +1,17 @@ # Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# 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 +# +# http://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. +# ============================================================================== # Multi-stage base image build # diff --git a/src/docker/base/ubuntu/Dockerfile b/src/docker/base/ubuntu/Dockerfile index 3946c75ed650..8149b9a9121b 100644 --- a/src/docker/base/ubuntu/Dockerfile +++ b/src/docker/base/ubuntu/Dockerfile @@ -1,4 +1,17 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# 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 +# +# http://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. +# ============================================================================== ARG OS_VERSION=22.04 FROM ubuntu:$OS_VERSION as base From 0a4d23cf089b3694d9b1437f23f60cf848f30e60 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 16 May 2024 16:38:55 +0200 Subject: [PATCH 5/8] rename os to distro Signed-off-by: Robert Steiner --- .github/workflows/docker-base.yml | 8 ++++---- src/docker/base/alpine/Dockerfile | 6 +++--- src/docker/base/ubuntu/Dockerfile | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml index 0d33bc07a197..8095186ad6c5 100644 --- a/.github/workflows/docker-base.yml +++ b/.github/workflows/docker-base.yml @@ -41,19 +41,19 @@ jobs: fail-fast: false matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] - os: + distro: - tag: ubuntu22.04 version: 22.04 file-dir: src/docker/base/ubuntu with: namespace-repository: flwr/base - file-dir: ${{ matrix.os.file-dir }} + file-dir: ${{ matrix.distro.file-dir }} build-args: | PYTHON_VERSION=${{ matrix.python-version }} PIP_VERSION=${{ needs.parameters.outputs.pip-version }} SETUPTOOLS_VERSION=${{ needs.parameters.outputs.setuptools-version }} - OS_VERSION=${{ matrix.os.version }} - tags: py${{ matrix.python-version }}-${{ matrix.os.tag }} + DISTRO_VERSION=${{ matrix.distro.version }} + tags: py${{ matrix.python-version }}-${{ matrix.distro.tag }} secrets: dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index 8447ca1411c4..22a82ede4e34 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -23,8 +23,8 @@ # https://pythonspeed.com/articles/multi-stage-docker-python/ ARG PYTHON_VERSION=3.11 -ARG OS_VERSION=alpine3.19 -FROM python:${PYTHON_VERSION}-${OS_VERSION} as compile +ARG DISTRO_VERSION=alpine3.19 +FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as compile # Install system dependencies RUN apk add --no-cache \ @@ -47,7 +47,7 @@ RUN pip install -U --no-cache-dir \ setuptools==${SETUPTOOLS_VERSION} \ ${FLWR_PACKAGE}==${FLWR_VERSION} -FROM python:${PYTHON_VERSION}-${OS_VERSION} as base +FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as base # required by the grpc package RUN apk add --no-cache \ diff --git a/src/docker/base/ubuntu/Dockerfile b/src/docker/base/ubuntu/Dockerfile index 8149b9a9121b..31efe653210e 100644 --- a/src/docker/base/ubuntu/Dockerfile +++ b/src/docker/base/ubuntu/Dockerfile @@ -13,8 +13,8 @@ # limitations under the License. # ============================================================================== -ARG OS_VERSION=22.04 -FROM ubuntu:$OS_VERSION as base +ARG DISTRO_VERSION=22.04 +FROM ubuntu:$DISTRO_VERSION as base ENV DEBIAN_FRONTEND noninteractive # Send stdout and stderr stream directly to the terminal. Ensures that no From fcd23c17f3ec871395317099b0c2f3f512353468 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 16 May 2024 16:41:10 +0200 Subject: [PATCH 6/8] remove explicit package versions Signed-off-by: Robert Steiner --- src/docker/base/alpine/Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index 22a82ede4e34..e266c74e66e8 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -22,6 +22,7 @@ # virtual environment to keep all files in a single isolated directory as described here: # https://pythonspeed.com/articles/multi-stage-docker-python/ +# hadolint global ignore=DL3018 ARG PYTHON_VERSION=3.11 ARG DISTRO_VERSION=alpine3.19 FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as compile @@ -29,8 +30,8 @@ FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as compile # Install system dependencies RUN apk add --no-cache \ # require for compiling grpcio on ARM64 - g++=13.2.1_git20231014-r0 \ - libffi-dev=3.4.4-r3 \ + g++ \ + libffi-dev \ # create virtual env && python -m venv /opt/venv @@ -51,7 +52,7 @@ FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as base # required by the grpc package RUN apk add --no-cache \ - libstdc++=13.2.1_git20231014-r0 + libstdc++ COPY --from=compile /opt/venv /opt/venv From 5e5cdacaa5a7c6ac0dfc7e356e744e597cc57c0c Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 16 May 2024 17:33:05 +0200 Subject: [PATCH 7/8] add distro name Signed-off-by: Robert Steiner --- .github/workflows/docker-base.yml | 8 ++++---- src/docker/base/alpine/Dockerfile | 7 ++++--- src/docker/base/ubuntu/Dockerfile | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml index 8095186ad6c5..b8692c86903d 100644 --- a/.github/workflows/docker-base.yml +++ b/.github/workflows/docker-base.yml @@ -42,18 +42,18 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] distro: - - tag: ubuntu22.04 + - name: ubuntu version: 22.04 - file-dir: src/docker/base/ubuntu with: namespace-repository: flwr/base - file-dir: ${{ matrix.distro.file-dir }} + file-dir: src/docker/base/${{ matrix.distro.name }} build-args: | PYTHON_VERSION=${{ matrix.python-version }} PIP_VERSION=${{ needs.parameters.outputs.pip-version }} SETUPTOOLS_VERSION=${{ needs.parameters.outputs.setuptools-version }} + DISTRO=${{ matrix.distro.name }} DISTRO_VERSION=${{ matrix.distro.version }} - tags: py${{ matrix.python-version }}-${{ matrix.distro.tag }} + tags: py${{ matrix.python-version }}-${{ matrix.distro.name }}${{ matrix.distro.version }} secrets: dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index e266c74e66e8..d5a98f108a1d 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -24,8 +24,9 @@ # hadolint global ignore=DL3018 ARG PYTHON_VERSION=3.11 -ARG DISTRO_VERSION=alpine3.19 -FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as compile +ARG DISTRO=alpine +ARG DISTRO_VERSION=3.19 +FROM python:${PYTHON_VERSION}-${DISTRO}${DISTRO_VERSION} as compile # Install system dependencies RUN apk add --no-cache \ @@ -48,7 +49,7 @@ RUN pip install -U --no-cache-dir \ setuptools==${SETUPTOOLS_VERSION} \ ${FLWR_PACKAGE}==${FLWR_VERSION} -FROM python:${PYTHON_VERSION}-${DISTRO_VERSION} as base +FROM python:${PYTHON_VERSION}-${DISTRO}${DISTRO_VERSION} as base # required by the grpc package RUN apk add --no-cache \ diff --git a/src/docker/base/ubuntu/Dockerfile b/src/docker/base/ubuntu/Dockerfile index 31efe653210e..5a4adf09df2d 100644 --- a/src/docker/base/ubuntu/Dockerfile +++ b/src/docker/base/ubuntu/Dockerfile @@ -13,8 +13,9 @@ # limitations under the License. # ============================================================================== +ARG DISTRO=ubuntu ARG DISTRO_VERSION=22.04 -FROM ubuntu:$DISTRO_VERSION as base +FROM $DISTRO:$DISTRO_VERSION as base ENV DEBIAN_FRONTEND noninteractive # Send stdout and stderr stream directly to the terminal. Ensures that no From 7b32567c043a044ca1e6d4e639bfe4b4fb81e656 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Fri, 17 May 2024 11:38:30 +0200 Subject: [PATCH 8/8] fix env Signed-off-by: Robert Steiner --- src/docker/base/alpine/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index d5a98f108a1d..d1c24d7d5480 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -58,7 +58,7 @@ RUN apk add --no-cache \ COPY --from=compile /opt/venv /opt/venv # Make sure we use the virtualenv -ENV ENV PATH="/opt/venv/bin:$PATH" \ +ENV PATH="/opt/venv/bin:$PATH" \ # Send stdout and stderr stream directly to the terminal. Ensures that no # output is retained in a buffer if the application crashes. PYTHONUNBUFFERED=1 \