Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker: Build for debian by default #450

Closed
SimonKagstrom opened this issue Jul 10, 2024 · 16 comments · Fixed by #452
Closed

docker: Build for debian by default #450

SimonKagstrom opened this issue Jul 10, 2024 · 16 comments · Fixed by #452

Comments

@SimonKagstrom
Copy link
Owner

Good to test in musl.

@kinow
Copy link

kinow commented Jul 12, 2024

Hi @SimonKagstrom ! Hijacking this issue, as it's somewhat related to an issue on our CICD pipeline.

We used kcov/kcov in a Docker multi-stage container, based on Debian, and noticed it started failing recently. I looked at the commits, and saw this one that changed the image to alpine: 275e922

And also saw the dockerhub image was uploaded a few days ago. It'd be great if there were alpine + debian images in DockerHub, but that would be a burden on maintenance. I will build kcov in our container using debian instead, but just in case you hear from anyone else with issues like this one 👍

Cheers

@SimonKagstrom
Copy link
Owner Author

What was the failure?

@williamdes might also be interested, although I take the responsibility since I pushed for alpine-based docker builds :-)

@williamdes
Copy link
Contributor

Can you share your workflow?

I think there is maybe something wrong as my CI does not pass as I said here #437 (comment)

@kinow
Copy link

kinow commented Jul 12, 2024

My pipelines are executed on a private GitLab repository, but they simply run kcov in a container that contained:

# -----------------------------------------------------------------------------
# kcov is a coverage tool for binaries that works with Bash shell
# ...
FROM kcov:latest AS kcov

# nothing here, image includes kcov

# -----------------------------------------------------------------------------
# bats is an old (one of the oldest?) Shell unit test libraries. It
# ...
FROM debian:bullseye-slim AS bats

# build bats

# -----------------------------------------------------------------------------
# Final base image.
FROM python:3.8.19-slim-bookworm

# Copy bats.

COPY --from=bats /usr/local/bin/bats* /usr/local/bin/
COPY --from=bats /usr/local/lib/bats-core/ /usr/local/lib/bats-core/
COPY --from=bats /usr/local/libexec/bats-core/ /usr/local/libexec/bats-core/
COPY --from=bats /usr/lib/bats/bats-assert/ /usr/lib/bats/bats-assert/
COPY --from=bats /usr/lib/bats/bats-support/ /usr/lib/bats/bats-support/

# Copy kcov.

COPY --from=kcov /usr/local/bin/kcov* /usr/local/bin/
COPY --from=kcov /usr/local/share/doc/kcov /usr/local/share/doc/kcov

WORKDIR "/code"

# ENTRYPOINT ["/bin/sh", "-c"]
CMD ["/usr/local/bin/bats"]

With the change to alpine, running ldd I could confirm that it was missing the musl libc when running the copied kcov. Which makes sense, since it's dangerous to copy binaries between musl & glibc binaries (even though I could try to make it work... probably could lead to more/other issues, I guess).

My first intention was to pin the kcov to a previous tag. But I did not see any recent tags on DockerHub.

Then I searched for an -slim or ubuntu etc. image, and noticed there was only an Alpine image (which is already very useful to have :)).

My fix was to update the first stage in the container to build kcov with debian, and then copy just the binary for the final image:

FROM debian:bullseye-slim AS kcov

ARG KCOV_COMMIT="9133fec158a11fd6b101f34da9152d695c7f47f7"

# Install build-time dependencies.

RUN apt-get update && \
    apt-get install --yes --no-install-suggests --no-install-recommends \
      binutils-dev \
      build-essential \
      ca-certificates \
      cmake \
      git \
      libssl-dev \
      libcurl4-openssl-dev \
      python3 \
      zlib1g-dev libdw-dev libiberty-dev && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

WORKDIR "/usr/src"

# Get kcov code, for a working commit (they are not tagging...).

RUN git clone \
      --depth 1 \
      https://github.com/SimonKagstrom/kcov.git && \
    cd kcov && \
    git checkout "${KCOV_COMMIT}"

# Build kcov.

RUN cd kcov && \
    mkdir build && \
    cd build && \
    cmake .. && \
    make && \
    make install

# other stages...
# ...

# Final base image.
FROM python:3.8.19-slim-bookworm

# Install run-time dependencies.

RUN apt-get update && \
    apt-get install --yes --no-install-suggests --no-install-recommends \
      binutils \
      ca-certificates \
      git \
      jq \
      libcurl4 \
      libdw1 \
      zlib1g && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Copy bats.

COPY --from=bats /usr/local/bin/bats* /usr/local/bin/
COPY --from=bats /usr/local/lib/bats-core/ /usr/local/lib/bats-core/
COPY --from=bats /usr/local/libexec/bats-core/ /usr/local/libexec/bats-core/
COPY --from=bats /usr/lib/bats/bats-assert/ /usr/lib/bats/bats-assert/
COPY --from=bats /usr/lib/bats/bats-support/ /usr/lib/bats/bats-support/

# Copy kcov.

COPY --from=kcov /usr/local/bin/kcov* /usr/local/bin/
COPY --from=kcov /usr/local/share/doc/kcov /usr/local/share/doc/kcov

WORKDIR "/code"

# ENTRYPOINT ["/bin/sh", "-c"]
CMD ["/usr/local/bin/bats"]

@kinow
Copy link

kinow commented Jul 12, 2024

BTW, I think the image is useful for others testing it, and maybe for CI tests in this repo. And I wouldn't want to add any extra burden on the maintainer 🙂 The INSTALL instructions were very helpful, and it only took a bit longer.

The tag in DockerHub would be helpful to allow me to procrastinate a bit, and fix it later, but not a big issue 👍

Thanks a lot again for kcov! (p.s. I also updated our CI to drop jq, and now we are only using the new --dump-summary option ❤️ )

@williamdes
Copy link
Contributor

I have to read all this soon
But before switching to alpine I upgraded to bookworm
and left the Debian instructions in the Dockerfile to users to build for Debian: https://github.com/SimonKagstrom/kcov/blob/master/Dockerfile
Maybe we can provide a Debian alternative

@SimonKagstrom
Copy link
Owner Author

Well, I see that this can be a problem, and I'm maybe inclined to go with a debian-based image as default. However, is this really how the docker images should be used? In this case, it fails since the image is copied from an alpine-based build, but I guess it could also fail if e.g., the debian version would mismatch after the copy?

Anyway, I'd say we revert back to debian for the docker images, and that's probably good enough for now. Maybe in the future, it could make sense to build for alpine as well.

@kinow
Copy link

kinow commented Jul 13, 2024

There are some initiatives to have support to both 1, but I never tried that. For popular images it's common to have a glibc and musl version.

But for smaller projects I believe it's totally fine to a) provide instructions only, b) provide a Dockerfile only, c) provide a single image on DockerHub without promises that it can be used in production. Any of these are fine for me (and the option a), is pretty much what you have in INSTALL, that's enough for anyone to build a container).

I know maintaining Open Source projects is hard, and there is already a toll on doing that and having to make something that's a bit generic and works for everybody.

But IMHO, your personal life & happiness maintaining the project comes first.

Anyway, I'd say we revert back to debian for the docker images, and that's probably good enough for now. Maybe in the future, it could make sense to build for alpine as well.

Up to you, but it really does not bother me at all to have to build it on my CICD. Maybe later I will be able to use it if Debian stable adds kcov (I couldn't install it with bookworm), or if I switch to a Ubuntu based image. There are probably other workarounds... but being able to have coverage for my shell scripts with kcov is already a great thing 🙂

Thanks!

p.s.: Not sure how you are building and uploading the images, but most (if not everything?) of that nowadays can be automated with GitHub Actions, which helps to ease a bit the burden of testing, maintaining the images, uploading to DockerHub, tagging, etc.

Footnotes

  1. https://changelog.com/shipit/76

@SimonKagstrom SimonKagstrom changed the title ci: Build in Alpine Linux as well docker: Build for debian by default Jul 14, 2024
@SimonKagstrom
Copy link
Owner Author

Anyway, I'd say we revert back to debian for the docker images, and that's probably good enough for now. Maybe in the future, it could make sense to build for alpine as well.

Up to you, but it really does not bother me at all to have to build it on my CICD. Maybe later I will be able to use it if Debian stable adds kcov (I couldn't install it with bookworm), or if I switch to a Ubuntu based image. There are probably other workarounds... but being able to have coverage for my shell scripts with kcov is already a great thing 🙂

@williamdes already did the transition to bookworm, so I'll revert to that and hopefully it should be easier to use in this usecase.

In #444 , there's also some work to make it easier for debian packaging, but even with an updated version, the distribution version will always lag behind.

p.s.: Not sure how you are building and uploading the images, but most (if not everything?) of that nowadays can be automated with GitHub Actions, which helps to ease a bit the burden of testing, maintaining the images, uploading to DockerHub, tagging, etc.

Yeah, @williamdes did a lot of improvements there, so it's automated, so not much burden to maintain (except waiting for the builds).

I rephrased this issue to be more aligned with the discussion :-) Will create a new one for the original issue.

@kinow
Copy link

kinow commented Jul 14, 2024

As I'm using this at $work, I can also help here with testing/doc/code/etc. if needed 🙂 Thank you @SimonKagstrom !

@williamdes
Copy link
Contributor

williamdes commented Jul 14, 2024

@williamdes already did the transition to bookworm, so I'll revert to that and hopefully it should be easier to use in this usecase

Ha, but I really liked the alpine version and need it for my GitHub actions to be quick

Could we have both versions on docker hub?
latest-alpine
latest > is bookworm

and vxx-alpine and vxx is bookworm
@SimonKagstrom I can do a PR for that

@SimonKagstrom
Copy link
Owner Author

@williamdes yes, sounds like a splendid idea!

While I don't use kcov from docker builds personally, I tend to base my other docker builds on alpine since it's generally faster and smaller, so having both sounds good.

I only just started on the change (so far failing the build), but feel free to take over! I'm also on MacOS and haven't bothered with a docker setup locally, so it's kind of a churn to test the changes for me.

@williamdes
Copy link
Contributor

Okay, working on it!

@williamdes
Copy link
Contributor

Done #452
Some more minor things about Docker labels and it will be okay

@williamdes
Copy link
Contributor

@kinow there is now official documentation on how to copy kcov into your Dockerfile
See: https://github.com/SimonKagstrom/kcov/blob/master/doc/docker.md#copy-into-your-image

@kinow
Copy link

kinow commented Jul 16, 2024

@kinow there is now official documentation on how to copy kcov into your Dockerfile See: https://github.com/SimonKagstrom/kcov/blob/master/doc/docker.md#copy-into-your-image

Documentation tested, and it worked like a charm. I've reverted my previous changes, and our Docker image is now a lot simpler. Thanks @SimonKagstrom , @williamdes ! 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants