From afbbf1387ec19e0b1a766c06509a3fdf4a067bb9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 1 Nov 2019 10:37:40 +0100 Subject: [PATCH] Dockerfile: use Alpine image to build static binary This patch switches the Dockerfile to use an Alpine Linux base image to build the static binary. Given that the binary is now fully static, a minimal image can be produced that only contains the essential artefacts. The static version of the Docker image does not contain the man- pages, so the existing (debian based) Dockerfile is kept, but renamed to Dockerfile.debian, and can be built by specifying the alternative Dockerfile using the `-f` flag: DOCKER_BUILDKIT=1 docker build -t jq:stretch -f Dockerfile.debian . With this patch applied, the image size is reduced drastically: DOCKER_BUILDKIT=1 docker build -t jq . docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE jq latest 7da2ea1c016d 5 seconds ago 800kB jq stretch-slim 4b7f380970f0 About a minute ago 70.3MB jq stretch c5fa8b766cd4 7 minutes ago 119MB The image can be tested, for example, by inspecting itself and pretty- printing the json: docker image inspect jq | docker run -i --rm jq . [ { "Id": "sha256:7da2ea1c016d97e7b52b09d5a323a1e7c0e4dbdbc77ce2715aedd3188721e4da", "RepoTags": [ "jq:latest", "jq:static" ], ... Signed-off-by: Sebastiaan van Stijn --- Dockerfile | 65 +++++++++++++++++------------------------------ Dockerfile.debian | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 42 deletions(-) create mode 100644 Dockerfile.debian diff --git a/Dockerfile b/Dockerfile index 5a3ada2424..f707e96a0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,54 +1,35 @@ +FROM alpine:3.10 AS build -ARG PYTHON_VERSION=3.6.7 - -FROM python:${PYTHON_VERSION}-stretch AS build -CMD ["bash"] ENV LC_ALL=C.UTF-8 -ARG DEBIAN_FRONTEND=noninteractive -ARG DEBCONF_NONINTERACTIVE_SEEN=true -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ +ENV LANG=C.UTF-8 + +RUN apk add --no-cache \ + automake \ autoconf \ + build-base \ bison \ - build-essential \ flex \ git \ libtool \ - && rm -rf /var/lib/apt/lists/* + oniguruma-dev WORKDIR /app - -# Install docs dependencies; we're only copying the Pipfile here, -# so that this is only run again if dependencies change -RUN pip3 install pipenv -COPY docs/Pipfile docs/Pipfile.lock ./docs/ -RUN cd docs && pipenv sync - -COPY .gitmodules . -COPY .git ./.git/ -RUN git submodule init -RUN git submodule update -RUN sed -i.bak '/^AM_INIT_AUTOMAKE(\[-Wno-portability 1\.14\])$/s/14/11/' modules/oniguruma/configure.ac - COPY . . RUN autoreconf -if -RUN ./configure --disable-valgrind --with-oniguruma=builtin YACC=/usr/bin/bison --prefix=/build/ -RUN make BISON_PKGDATADIR=/usr/bin/bison src/parser.c || make src/parser.c -RUN make -j8 -RUN make check -j8 -RUN make install -RUN /build/bin/jq -V - -# Collect the files for the final image -FROM debian:stretch-slim AS deploy -ENV LC_ALL=C.UTF-8 -ARG DEBIAN_FRONTEND=noninteractive -ARG DEBCONF_NONINTERACTIVE_SEEN=true -RUN apt-get update \ - && apt-get install -y --no-install-recommends man \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=build /build/. /usr/local/ -RUN jq -V -ENTRYPOINT ["/usr/local/bin/jq"] +RUN ./configure --disable-docs --enable-all-static CFLAGS='-Os -static -no-pie' CXXFLAGS='-Os -static -no-pie' +RUN make +RUN make check +RUN strip jq + +# Ensure that the built executable is really statically linked. +RUN file jq | grep -Fw 'statically linked' + +# The deploy stage is the final image, and only contains artefacts +# that should be published. +FROM scratch AS deploy +COPY --from=build /app/AUTHORS / +COPY --from=build /app/COPYING / +COPY --from=build /app/jq /jq +RUN ["/jq", "-V"] +ENTRYPOINT ["/jq"] CMD ["--help"] diff --git a/Dockerfile.debian b/Dockerfile.debian new file mode 100644 index 0000000000..5a3ada2424 --- /dev/null +++ b/Dockerfile.debian @@ -0,0 +1,54 @@ + +ARG PYTHON_VERSION=3.6.7 + +FROM python:${PYTHON_VERSION}-stretch AS build +CMD ["bash"] +ENV LC_ALL=C.UTF-8 +ARG DEBIAN_FRONTEND=noninteractive +ARG DEBCONF_NONINTERACTIVE_SEEN=true +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + autoconf \ + bison \ + build-essential \ + flex \ + git \ + libtool \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Install docs dependencies; we're only copying the Pipfile here, +# so that this is only run again if dependencies change +RUN pip3 install pipenv +COPY docs/Pipfile docs/Pipfile.lock ./docs/ +RUN cd docs && pipenv sync + +COPY .gitmodules . +COPY .git ./.git/ +RUN git submodule init +RUN git submodule update +RUN sed -i.bak '/^AM_INIT_AUTOMAKE(\[-Wno-portability 1\.14\])$/s/14/11/' modules/oniguruma/configure.ac + +COPY . . +RUN autoreconf -if +RUN ./configure --disable-valgrind --with-oniguruma=builtin YACC=/usr/bin/bison --prefix=/build/ +RUN make BISON_PKGDATADIR=/usr/bin/bison src/parser.c || make src/parser.c +RUN make -j8 +RUN make check -j8 +RUN make install +RUN /build/bin/jq -V + +# Collect the files for the final image +FROM debian:stretch-slim AS deploy +ENV LC_ALL=C.UTF-8 +ARG DEBIAN_FRONTEND=noninteractive +ARG DEBCONF_NONINTERACTIVE_SEEN=true +RUN apt-get update \ + && apt-get install -y --no-install-recommends man \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=build /build/. /usr/local/ +RUN jq -V +ENTRYPOINT ["/usr/local/bin/jq"] +CMD ["--help"]