Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Simplify kuksa-client docker build and reducing resulting image size #683

Merged
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
6 changes: 5 additions & 1 deletion .github/workflows/kuksa-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,14 @@ jobs:
linux/arm64
context: .
file: kuksa-client/Dockerfile
push: false
push: true
tags: "ttl.sh/kuksa.val/kuksa-client-${{github.sha}}"
labels: ${{ steps.meta.outputs.labels }}

- name: Posting temporary container location
uses: ./.github/actions/post-container-location
with:
image: ttl.sh/kuksa.val/kuksa-client-${{github.sha}}

kuksa-client-test:
runs-on: ubuntu-latest
Expand Down
42 changes: 30 additions & 12 deletions kuksa-client/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,41 @@

# Note: This dockerfile needs to be executed one level above in the root folder

FROM python:3.10-alpine as build
RUN apk update && apk add git alpine-sdk linux-headers
RUN pip install --upgrade pip build

FROM python:3.10-slim-bookworm as build
Copy link
Contributor

@erikbosch erikbosch Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we possibly document our strategy (and experiences) for Docker environments somewhere. Like, should we stop using alpine everywhere? Today we have a quite big mix, and are there not some possible benefits of using the same environment as often as possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"probably", although I think it might differ depending on technology

So "historically" there was Alpine used, as for the C++ Val-Server it really made a difference size-wise.

For Python based things the savings are not that large, and using glibc builds are just easiest. Current stable debian just seems a common choice in many docker workloads. The solution here basically already includes learnings from the past , e.g. the pyinstaller technique from DBC feeder, except it does not condense all pyinstaller collected things in one file (as it does not offer benefits inside a container, but a runtime penalty unpacking it)

For rust it is a bit different, as we are using "from scratch" images (e.g. only one binary in the container, no distro), and glibc isn't really suited to be statically linked - you CAN do it, but then some rust crates/dependecies break that, hence we have MUSL there.

tldr; We should, I think this on represents our current "best practice" in pyhton, and maybe we should adapt our python stuff

# binutils is required by pyinstaller to strip any .so libs that are collected
# git is used to determine & embed version information during build time
RUN apt update && apt -yy install binutils git
RUN pip install --upgrade pip build pyinstaller

# We must copy the whole repository otherwise version lookup by tag would not work
COPY . /kuksa.val/
WORKDIR /kuksa.val/kuksa-client
RUN rm -rf dist

RUN python3 -m build
RUN mkdir /kuksa-client
RUN pip install --target /kuksa-client --no-cache-dir dist/*.whl
# We install globally on build container, so pyinstaller can easily gather all files
RUN pip install --no-cache-dir dist/*.whl

WORKDIR /
RUN rm -rf dist
# Letting pyinstaller collect everything that is required
RUN pyinstaller --collect-data kuksa_certificates --collect-data kuksa_client --clean -s /usr/local/bin/kuksa-client


# Debian 12 is bookworm, so the glibc version matches. Distroless is a lot smaller than
# Debian slim versions
# For development add :debug like this
# FROM gcr.io/distroless/base-debian12:debug to get a busybox shell as well
FROM gcr.io/distroless/base-debian12

FROM python:3.10-alpine
COPY --from=build /dist/kuksa-client /kuksa-client

# pyinstaller doesn't pick up transient libz dependency, so copying it manually
COPY --from=build /usr/lib/*-linux-gnu/libz.so.1 /lib/
# stty is required by cmd2
COPY --from=build /usr/bin/stty /bin/

RUN apk add --no-cache libstdc++
COPY --from=build /kuksa-client /kuksa-client
ENV PYTHONUNBUFFERED=yes
ENV GRPC_ENABLE_FORK_SUPPORT=false
ENV PYTHONPATH=/kuksa-client

WORKDIR /kuksa-client
ENTRYPOINT ["bin/kuksa-client"]
ENTRYPOINT ["/kuksa-client/kuksa-client"]