aptible / supercronic

Cron for containers
MIT License
1.93k stars 117 forks source link

Building multiarch docker images #148

Open my-git-hub opened 8 months ago

my-git-hub commented 8 months ago

Hi!

I'm having issues building multi-arch Docker image with supercronic.

I'm able to use TARGETARCH in URL and binary name, but not in the sha1 checksum variable.

Anyone know how to deal with this?

Could we solve this with having a separate file with .sha1 extension so that you can get the checksum value from URL.

ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.29/supercronic-linux-${TARGETARCH} \
    SUPERCRONIC=supercronic-linux-${TARGETARCH} \ 
    SUPERCRONIC_SHA1SUM=${SUPERCRONIC_URL}.sha1

RUN curl -fsSLO "$SUPERCRONIC_URL" \
   && curl -fsSLO "$SUPERCRONIC_SHA1SUM" ~
   && sha1sum -c ${SUPERCRONIC}.sha1 \
   && chmod +x "$SUPERCRONIC" \
   && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
   && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic
UserNotFound commented 8 months ago

Your idea sounds like it would work 🤷

I tried using indirect parameter expansion, with each SHA1SUM stored in it's own variable with TARGET_ARCH in the name. This works fine in Bash, but I'm apparently not clever enough to get it to work properly in a Dockerfile for what you're trying to accomplish:

FROM debian:buster-slim

RUN apt-get update \
  && apt-get install -y curl \
  && rm -rf /var/lib/apt/lists/*

ARG TARGETARCH

ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.29/supercronic-linux-${TARGETARCH} \
   SUPERCRONIC=supercronic-linux-${TARGETARCH} \
   SUPERCRONIC_SHA1SUM_arm64=512f6736450c56555e01b363144c3c9d23abed4c \
   SUPERCRONIC_SHA1SUM_amd64=cd48d45c4b10f3f0bfdd3a57d054cd05ac96812b

ENV SUPERCRONIC_SHA1SUM=SUPERCRONIC_SHA1SUM_${TARGETARCH}

# This fails, unfortnately:
# /bin/sh: 1: Bad substitution
RUN echo "${!SUPERCRONIC_SHA1SUM}"

RUN curl -fsSLO "$SUPERCRONIC_URL" \
  && echo "${!SUPERCRONIC_SHA1SUM}  ${SUPERCRONIC}" | sha1sum -c - \
  && chmod +x "$SUPERCRONIC" \
  && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
  && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic

This is probably outside of the scope of support we can provide, but I'll keep this in mind if we build docker images: if we make them multi-arch, you should be able to use multi-stage builds to copy out the supercronic binary.

YOU54F commented 7 months ago

We do this over in our Pact Broker project.

Example

FROM ruby:3.2.3-alpine3.19 as base

# Supercronic - setup sha1sum for each supported architecture
FROM base AS base-amd64
ENV SUPERCRONIC_SHA1SUM=cd48d45c4b10f3f0bfdd3a57d054cd05ac96812b
FROM base AS base-arm64
ENV SUPERCRONIC_SHA1SUM=512f6736450c56555e01b363144c3c9d23abed4c
FROM base AS base-arm
ENV SUPERCRONIC_SHA1SUM=75e065bf0909f920b06d5bd797c0e6b31e68b112

# Supercronic - use base-$TARGETARCH to select correct base image SUPERCRONIC_SHA1SUM
ARG TARGETARCH
FROM base-$TARGETARCH AS pb-dev

# Install Supercronic
ARG TARGETARCH
ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.29/supercronic-linux-${TARGETARCH} \
    SUPERCRONIC=supercronic-linux-${TARGETARCH}
RUN wget "$SUPERCRONIC_URL" \
 && echo "${SUPERCRONIC_SHA1SUM}  ${SUPERCRONIC}" | sha1sum -c - \
 && chmod +x "$SUPERCRONIC" \
 && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
 && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic

Source

If you download the shasum, and the binary was modified (was by a malicious actor), the shasum would mostly likely have been modified as well, so I'm not sure what value your check is?

By recording the shasum in your Dockerfile, you've at least grabbed it at a point in time, where you always expect your binary to now match that.

The malicious actor might update the shasum, binary and the shasum on the release description, but now it would differ from the point in time you took the snapshot

YOU54F commented 7 months ago

As a side note, but related to multi-arch images, would you be open to adding more targets, to the project, it's pretty trivial with golang

eg delta

as that allowed me to support as many targets as I could target and build with docker buildx

https://github.com/YOU54F/pact-broker-docker/blob/fd19519208156ba74c7d264a712aa7f8fe291e6e/Dockerfile#L9-L25

jonasgeiler commented 2 months ago

If supercronic where to have checksum files in the release assets, wouldn't it also be high time to switch to SHA256 or SHA512 for the checksum? SHA1 is deprecated since 2011.

I would also propose to just use GoReleaser, which many other Go-based software seem to use for releases, like Caddy, Traefik and many other big names.