deterministic OCI container build setup
This commit is contained in:
parent
4885e07e45
commit
f062697572
132
Dockerfile
132
Dockerfile
|
@ -1,22 +1,118 @@
|
||||||
FROM ruby:3.2.2-alpine AS builder
|
ARG DEBIAN_HASH=b91baba9c2cae5edbe3b0ff50ae8f05157e3ae6f018372dcfc3aba224acb392b
|
||||||
LABEL stage=distrust-co-builder
|
ARG BUILD_ENV=pin
|
||||||
RUN apk update && apk add g++ make git git-lfs
|
|
||||||
RUN mkdir -p /home
|
FROM debian@sha256:${DEBIAN_HASH} AS build_base
|
||||||
COPY Gemfile /home
|
|
||||||
COPY Gemfile.lock /home
|
FROM build_base AS build_pin
|
||||||
COPY _vendor /home/_vendor
|
ARG DEBIAN_RELEASE=bookworm
|
||||||
WORKDIR /home
|
ARG REQUIRED_PACKAGES="git ruby ruby-dev ruby-bundler media-types"
|
||||||
|
ONBUILD RUN \
|
||||||
|
export date=$(date +"%Y%m%dT000000Z") \
|
||||||
|
&& export url=http://snapshot.debian.org/archive/debian \
|
||||||
|
&& export rel=${DEBIAN_RELEASE} \
|
||||||
|
&& echo "deb [trusted=yes] ${url}/${date} ${rel} main" \
|
||||||
|
> apt-sources.list \
|
||||||
|
&& echo "deb [trusted=yes] ${url}-security/${date} ${rel}-security main" \
|
||||||
|
> apt-sources.list \
|
||||||
|
&& echo "deb [trusted=yes] ${url}/${date} ${rel}-updates main" \
|
||||||
|
> apt-sources.list
|
||||||
|
ONBUILD RUN \
|
||||||
|
apt-get update \
|
||||||
|
&& apt-get install \
|
||||||
|
-y \
|
||||||
|
--download-only \
|
||||||
|
dpkg-dev bzip2 ${REQUIRED_PACKAGES} \
|
||||||
|
&& ( cd /var/cache/apt/archives \
|
||||||
|
&& find . -type f \( -iname \*.deb \) -exec sha256sum {} \; \
|
||||||
|
| sed 's/.\///g' \
|
||||||
|
| LC_ALL=C sort \
|
||||||
|
) > apt-hashes.list \
|
||||||
|
&& echo "Pinned APT packages:" \
|
||||||
|
&& cat apt-hashes.list
|
||||||
|
ONBUILD RUN \
|
||||||
|
for deb in /var/cache/apt/archives/*.deb; do \
|
||||||
|
package=$(dpkg-deb -f $deb Package); \
|
||||||
|
version=$(dpkg --info ${deb} | grep "^ Version: " | sed 's/^ Version: //g'); \
|
||||||
|
echo "${package}=${version}" >> apt-pins.list; \
|
||||||
|
done \
|
||||||
|
&& mkdir apt-packages \
|
||||||
|
&& mv /var/cache/apt/archives/*.deb apt-packages \
|
||||||
|
&& apt-get install -y bzip2 dpkg-dev \
|
||||||
|
&& dpkg-scanpackages apt-packages | bzip2 > apt-packages/Packages.bz2
|
||||||
|
|
||||||
|
FROM build_base AS build_fetch
|
||||||
|
ONBUILD COPY apt-hashes.list .
|
||||||
|
ONBUILD COPY apt-sources.list .
|
||||||
|
ONBUILD COPY apt-pins.list .
|
||||||
|
ONBUILD RUN \
|
||||||
|
rm -f /etc/apt/sources.list.d/* \
|
||||||
|
&& mv apt-sources.list /etc/apt/sources.list \
|
||||||
|
&& apt update -o Acquire::Check-Valid-Until=false \
|
||||||
|
&& apt-get install \
|
||||||
|
--download-only \
|
||||||
|
--allow-downgrades \
|
||||||
|
-o Acquire::Check-Valid-Until=false \
|
||||||
|
-y $(cat apt-pins.list) \
|
||||||
|
&& cd /var/cache/apt/archives \
|
||||||
|
&& find . -type f \( -iname \*.deb \) -exec sha256sum {} \; \
|
||||||
|
| sed 's/.\///g' \
|
||||||
|
| LC_ALL=C sort \
|
||||||
|
) > apt-hashes-compare.list \
|
||||||
|
&& diff apt-hashes.list apt-hashes-compare.list \
|
||||||
|
&& mkdir apt-packages \
|
||||||
|
&& mv /var/cache/apt/archives/*.deb apt-packages \
|
||||||
|
&& dpkg-scanpackages apt-packages | bzip2 > apt-packages/Packages.bz2
|
||||||
|
|
||||||
|
FROM build_base AS build_reproduce
|
||||||
|
ONBUILD COPY apt-hashes.list .
|
||||||
|
ONBUILD COPY apt-sources.list .
|
||||||
|
ONBUILD COPY apt-pins.list .
|
||||||
|
ONBUILD COPY apt-packages .
|
||||||
|
|
||||||
|
FROM build_${BUILD_ENV} as build
|
||||||
|
RUN \
|
||||||
|
rm -f /etc/apt/sources.list.d/* \
|
||||||
|
&& echo "deb [trusted=yes] file:///. apt-packages/" > /etc/apt/sources.list \
|
||||||
|
&& apt update -o Acquire::Check-Valid-Until=false \
|
||||||
|
&& apt-get install \
|
||||||
|
--allow-downgrades \
|
||||||
|
-y $(cat apt-pins.list)
|
||||||
|
|
||||||
|
FROM build as build-httpd
|
||||||
|
ARG BUSYBOX_REPO=https://git.busybox.net/busybox
|
||||||
|
ARG BUSYBOX_HASH=1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4 # 1.36.1
|
||||||
|
RUN \
|
||||||
|
git clone https://git.busybox.net/busybox \
|
||||||
|
&& git -C busybox checkout ${BUSYBOX_HASH} \
|
||||||
|
&& git -C busybox rev-parse --verify HEAD | grep -q ${BUSYBOX_HASH} || { \
|
||||||
|
echo 'Error: Git ref/branch collision.'; exit 1; \
|
||||||
|
}
|
||||||
|
COPY config/busybox.config busybox/.config
|
||||||
|
RUN \
|
||||||
|
echo "building busybox httpd" \
|
||||||
|
&& cd busybox \
|
||||||
|
&& make \
|
||||||
|
&& bash make_single_applets.sh \
|
||||||
|
&& mv busybox_HTTPD ../httpd
|
||||||
|
|
||||||
|
FROM build as build-site
|
||||||
|
RUN mkdir build
|
||||||
|
WORKDIR build
|
||||||
|
COPY . .
|
||||||
RUN bundle install
|
RUN bundle install
|
||||||
COPY . /home
|
|
||||||
RUN jekyll build
|
RUN jekyll build
|
||||||
|
|
||||||
FROM debian:bookworm AS mime-types
|
FROM build as build-rootfs
|
||||||
RUN apt-get update && apt-get install -y media-types
|
RUN mkdir -p rootfs/etc \
|
||||||
|
&& echo "nogroup:*:100:nobody" > rootfs/etc/group \
|
||||||
|
&& echo "nobody:*:100:100:::" > rootfs/etc/passwd
|
||||||
|
|
||||||
RUN echo 'types {' > /tmp/mime.types
|
FROM scratch
|
||||||
RUN sed -e '/^$/d' -e 's/$/;/' /etc/mime.types >> /tmp/mime.types
|
COPY --from=build-rootfs --chown=100:100 rootfs /
|
||||||
RUN echo '}' >> /tmp/mime.types
|
COPY --from=build-site build/_site static
|
||||||
|
COPY --from=build-httpd httpd .
|
||||||
FROM nginx
|
USER 100:100
|
||||||
COPY --from=builder /home/_site /usr/share/nginx/html
|
EXPOSE 8080
|
||||||
COPY --from=mime-types /tmp/mime.types /etc/nginx/mime.types
|
WORKDIR static
|
||||||
|
ENTRYPOINT ["/httpd"]
|
||||||
|
CMD ["-f","-v"]
|
||||||
|
|
56
Makefile
56
Makefile
|
@ -1,22 +1,44 @@
|
||||||
.PHONY: build
|
|
||||||
build:
|
|
||||||
# Build Docker image
|
|
||||||
docker build -t distrust-co .
|
|
||||||
|
|
||||||
.PHONY: fullclean
|
|
||||||
fullclean: clean
|
|
||||||
docker rmi distrust-co || true
|
|
||||||
docker image prune -f --filter label=stage=distrust-co-builder || true
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -r _site || true
|
rm -r _site
|
||||||
|
|
||||||
_site: build
|
|
||||||
mkdir -p _site
|
|
||||||
docker run distrust-co tar c -C /usr/share/nginx/html . | tar x -C _site
|
|
||||||
|
|
||||||
.PHONY: serve
|
.PHONY: serve
|
||||||
serve: build
|
serve: build
|
||||||
# Run Docker container with listener for current dir and port mapping
|
docker run --rm -p 8080:8080/tcp -it distrust/website
|
||||||
docker run --rm -p 0.0.0.0:4000:80 -it distrust-co
|
|
||||||
|
.PHONY: build
|
||||||
|
build: out/website.oci.tar
|
||||||
|
|
||||||
|
config/apt-packages.list \
|
||||||
|
config/apt-hashes.list \
|
||||||
|
config/apt-sources.list \
|
||||||
|
fetch/apt/Packages.bz2:
|
||||||
|
buildah build \
|
||||||
|
-f Dockerfile \
|
||||||
|
-t distrust/website \
|
||||||
|
--timestamp 1 \
|
||||||
|
--format oci \
|
||||||
|
--arch amd64 \
|
||||||
|
--output cache/reproduce
|
||||||
|
cp cache/reproduce/apt-packages/* fetch/apt/
|
||||||
|
cp cache/reproduce/apt-*.list config
|
||||||
|
|
||||||
|
out/website.oci.tar:
|
||||||
|
buildah build \
|
||||||
|
-f Dockerfile \
|
||||||
|
-t distrust/website \
|
||||||
|
--timestamp 1 \
|
||||||
|
--format oci \
|
||||||
|
--arch amd64 \
|
||||||
|
buildah push \
|
||||||
|
distrust/website \
|
||||||
|
oci:cache/oci
|
||||||
|
tar \
|
||||||
|
-C cache/oci \
|
||||||
|
--sort=name \
|
||||||
|
--mtime='@0' \
|
||||||
|
--owner=0 \
|
||||||
|
--group=0 \
|
||||||
|
--numeric-owner \
|
||||||
|
-cf $@ \
|
||||||
|
.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue