From 45e6a1ae86ab5b19a5c3e63b79f503f9558198b7 Mon Sep 17 00:00:00 2001 From: Jeppe Fihl-Pearson Date: Wed, 2 Mar 2022 16:08:03 +0000 Subject: [PATCH 1/4] fix(docker): fix base image for multi-platform build (#2099) * Correct indentation of run commands * Split installation of packages into the ones needed at run time and build time This allows us to now repeat the packages which need to be uninstalled again by making use of a virtual package, which - when removed - removes the packages installed as a dependency of it. * Remove unnecessary `rm -rf /var/cache/apk/*` command It's no needed when `apt add` is run with the `--no-cache` option. * Add vertical spacing so it's clearer what is happening when * Test the downloaded binaries to make sure they work on the platform This can help find issues where binaries are downloaded for the wrong platform compared to the architecture the Docker image is built for. * Install dumb-init via apk It's available as a package for Alpine Linux in version 1.2.5 as well, which makes it easier to handle for the different architectures. * Get git-lfs binaries in the right architecture for the Docker image This makes use of the `TARGETPLATFORM` argument which automatically is populated by Docker BuildKit with a string such as "linux/amd64" when the image is being build for an x86_64 architecture. * Install gosu for the right architecture The `case` statement was taken from https://github.com/BretFisher/multi-platform-docker-build as a way of translating the platform name into what we needed for downloading gosu. --- docker-base/Dockerfile | 46 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/docker-base/Dockerfile b/docker-base/Dockerfile index f05cb3f9a2..e9c0f4394f 100644 --- a/docker-base/Dockerfile +++ b/docker-base/Dockerfile @@ -17,21 +17,35 @@ RUN addgroup atlantis && \ chmod g=u /home/atlantis/ && \ chmod g=u /etc/passwd -# Install dumb-init, gosu and git-lfs. -ENV DUMB_INIT_VERSION=1.2.5 +# Install gosu and git-lfs. ENV GOSU_VERSION=1.14 ENV GIT_LFS_VERSION=3.1.2 -RUN apk add --no-cache ca-certificates gnupg curl git unzip bash openssh libcap openssl && \ - curl -L -s --output /bin/dumb-init "https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_x86_64" && \ - chmod +x /bin/dumb-init && \ + +# Automatically populated with the architecture the image is being built for. +ARG TARGETPLATFORM + +# Install packages needed for running Atlantis. +RUN apk add --no-cache ca-certificates curl git unzip bash openssh libcap dumb-init && \ + # Install packages needed for building dependencies. + apk add --no-cache --virtual .build-deps gnupg openssl && \ mkdir -p /tmp/build && \ cd /tmp/build && \ - curl -L -s --output git-lfs.tar.gz "https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-amd64-v${GIT_LFS_VERSION}.tar.gz" && \ + + # git-lfs + curl -L -s --output git-lfs.tar.gz "https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-${TARGETPLATFORM##*/}-v${GIT_LFS_VERSION}.tar.gz" && \ tar -xf git-lfs.tar.gz && \ chmod +x git-lfs && \ mv git-lfs /usr/bin/git-lfs && \ - curl -L -s --output gosu "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64" && \ - curl -L -s --output gosu.asc "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64.asc" && \ + git-lfs --version && \ + + # gosu + case ${TARGETPLATFORM} in \ + "linux/amd64") GOSU_ARCH=amd64 ;; \ + "linux/arm64") GOSU_ARCH=arm64 ;; \ + "linux/arm/v7") GOSU_ARCH=armhf ;; \ + esac && \ + curl -L -s --output gosu "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${GOSU_ARCH}" && \ + curl -L -s --output gosu.asc "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${GOSU_ARCH}.asc" && \ for server in $(shuf -e ipv4.pool.sks-keyservers.net \ hkp://p80.pool.sks-keyservers.net:80 \ keyserver.ubuntu.com \ @@ -42,13 +56,15 @@ RUN apk add --no-cache ca-certificates gnupg curl git unzip bash openssh libcap gpg --batch --verify gosu.asc gosu && \ chmod +x gosu && \ cp gosu /bin && \ - cd /tmp && \ - rm -rf /tmp/build && \ - gpgconf --kill dirmngr && \ - gpgconf --kill gpg-agent && \ - apk del gnupg openssl && \ - rm -rf /root/.gnupg && \ - rm -rf /var/cache/apk/* + gosu --version && \ + + # Cleanup + cd /tmp && \ + rm -rf /tmp/build && \ + gpgconf --kill dirmngr && \ + gpgconf --kill gpg-agent && \ + apk del .build-deps && \ + rm -rf /root/.gnupg # Set up nsswitch.conf for Go's "netgo" implementation # - https://github.com/golang/go/blob/go1.9.1/src/net/conf.go#L194-L275 From 0646a8f54c173a5a351b128c5fc8336393991183 Mon Sep 17 00:00:00 2001 From: Jeppe Fihl-Pearson Date: Wed, 2 Mar 2022 16:29:28 +0000 Subject: [PATCH 2/4] fix(docker): fix installation of git-lfs in armv7 image (#2100) This uses a similar pattern than what is used for `GOSU_ARCH` to map the `TARGETPLATFORM` argument into the name of the architecture git-lfs use for their release binaries, as "linux/arm/v7" otherwise would be mapped into "v7" which is wrong. --- docker-base/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docker-base/Dockerfile b/docker-base/Dockerfile index e9c0f4394f..1e05829296 100644 --- a/docker-base/Dockerfile +++ b/docker-base/Dockerfile @@ -32,7 +32,12 @@ RUN apk add --no-cache ca-certificates curl git unzip bash openssh libcap dumb-i cd /tmp/build && \ # git-lfs - curl -L -s --output git-lfs.tar.gz "https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-${TARGETPLATFORM##*/}-v${GIT_LFS_VERSION}.tar.gz" && \ + case ${TARGETPLATFORM} in \ + "linux/amd64") GIT_LFS_ARCH=amd64 ;; \ + "linux/arm64") GIT_LFS_ARCH=arm64 ;; \ + "linux/arm/v7") GIT_LFS_ARCH=arm ;; \ + esac && \ + curl -L -s --output git-lfs.tar.gz "https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-${GIT_LFS_ARCH}-v${GIT_LFS_VERSION}.tar.gz" && \ tar -xf git-lfs.tar.gz && \ chmod +x git-lfs && \ mv git-lfs /usr/bin/git-lfs && \ From bec07ecc0c5cec6ab0da6a65f773f52fddd684b9 Mon Sep 17 00:00:00 2001 From: Jeppe Fihl-Pearson Date: Wed, 2 Mar 2022 17:20:00 +0000 Subject: [PATCH 3/4] fix(docker): download Terraform and conftest versions maching image architecture (#2101) * Remove Terraform versions from Docker image which don't have all archs Terraform versions earlier than 0.11.15 does not have binaries available for both amd64, arm64 and armv7, so are being dropped as we can't install the older versions in all the architectures the Docker image is built for. * Download Terraform version depending on the architecture Docker image is for This avoids us having arm64 binaries for the ARM Docker images, which won't work. * Download arm64 conftest binaries for arm64 Docker image This doesn't fix the armv7 Docker image because conftest doesn't have a binary available for that, so it for now still downloads the x86_64 binary, which is likely to not work - but it's the same as it did before. --- Dockerfile | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index aba1322df8..5d6e078074 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,19 +9,27 @@ RUN CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -v -o atlantis . # The runatlantis/atlantis-base is created by docker-base/Dockerfile. FROM ghcr.io/runatlantis/atlantis-base:2022.03.03 AS base +# Get the architecture the image is being built for +ARG TARGETPLATFORM + # install terraform binaries ENV DEFAULT_TERRAFORM_VERSION=1.1.7 # In the official Atlantis image we only have the latest of each Terraform version. -RUN AVAILABLE_TERRAFORM_VERSIONS="0.8.8 0.9.11 0.10.8 0.11.15 0.12.31 0.13.7 0.14.11 0.15.5 1.0.11 ${DEFAULT_TERRAFORM_VERSION}" && \ +RUN AVAILABLE_TERRAFORM_VERSIONS="0.11.15 0.12.31 0.13.7 0.14.11 0.15.5 1.0.11 ${DEFAULT_TERRAFORM_VERSION}" && \ + case ${TARGETPLATFORM} in \ + "linux/amd64") TERRAFORM_ARCH=amd64 ;; \ + "linux/arm64") TERRAFORM_ARCH=arm64 ;; \ + "linux/arm/v7") TERRAFORM_ARCH=arm ;; \ + esac && \ for VERSION in ${AVAILABLE_TERRAFORM_VERSIONS}; do \ - curl -LOs https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_linux_amd64.zip && \ + curl -LOs https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_linux_${TERRAFORM_ARCH}.zip && \ curl -LOs https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_SHA256SUMS && \ - sed -n "/terraform_${VERSION}_linux_amd64.zip/p" terraform_${VERSION}_SHA256SUMS | sha256sum -c && \ + sed -n "/terraform_${VERSION}_linux_${TERRAFORM_ARCH}.zip/p" terraform_${VERSION}_SHA256SUMS | sha256sum -c && \ mkdir -p /usr/local/bin/tf/versions/${VERSION} && \ - unzip terraform_${VERSION}_linux_amd64.zip -d /usr/local/bin/tf/versions/${VERSION} && \ + unzip terraform_${VERSION}_linux_${TERRAFORM_ARCH}.zip -d /usr/local/bin/tf/versions/${VERSION} && \ ln -s /usr/local/bin/tf/versions/${VERSION}/terraform /usr/local/bin/terraform${VERSION} && \ - rm terraform_${VERSION}_linux_amd64.zip && \ + rm terraform_${VERSION}_linux_${TERRAFORM_ARCH}.zip && \ rm terraform_${VERSION}_SHA256SUMS; \ done && \ ln -s /usr/local/bin/tf/versions/${DEFAULT_TERRAFORM_VERSION}/terraform /usr/local/bin/terraform @@ -29,14 +37,20 @@ RUN AVAILABLE_TERRAFORM_VERSIONS="0.8.8 0.9.11 0.10.8 0.11.15 0.12.31 0.13.7 0.1 ENV DEFAULT_CONFTEST_VERSION=0.30.0 RUN AVAILABLE_CONFTEST_VERSIONS="${DEFAULT_CONFTEST_VERSION}" && \ + case ${TARGETPLATFORM} in \ + "linux/amd64") CONFTEST_ARCH=x86_64 ;; \ + "linux/arm64") CONFTEST_ARCH=arm64 ;; \ + # There is currently no compiled version of conftest for armv7 + "linux/arm/v7") CONFTEST_ARCH=x86_64 ;; \ + esac && \ for VERSION in ${AVAILABLE_CONFTEST_VERSIONS}; do \ - curl -LOs https://github.com/open-policy-agent/conftest/releases/download/v${VERSION}/conftest_${VERSION}_Linux_x86_64.tar.gz && \ + curl -LOs https://github.com/open-policy-agent/conftest/releases/download/v${VERSION}/conftest_${VERSION}_Linux_${CONFTEST_ARCH}.tar.gz && \ curl -LOs https://github.com/open-policy-agent/conftest/releases/download/v${VERSION}/checksums.txt && \ - sed -n "/conftest_${VERSION}_Linux_x86_64.tar.gz/p" checksums.txt | sha256sum -c && \ + sed -n "/conftest_${VERSION}_Linux_${CONFTEST_ARCH}.tar.gz/p" checksums.txt | sha256sum -c && \ mkdir -p /usr/local/bin/cft/versions/${VERSION} && \ - tar -C /usr/local/bin/cft/versions/${VERSION} -xzf conftest_${VERSION}_Linux_x86_64.tar.gz && \ + tar -C /usr/local/bin/cft/versions/${VERSION} -xzf conftest_${VERSION}_Linux_${CONFTEST_ARCH}.tar.gz && \ ln -s /usr/local/bin/cft/versions/${VERSION}/conftest /usr/local/bin/conftest${VERSION} && \ - rm conftest_${VERSION}_Linux_x86_64.tar.gz && \ + rm conftest_${VERSION}_Linux_${CONFTEST_ARCH}.tar.gz && \ rm checksums.txt; \ done From 697ea1723ebca89be49d4049a94861fcc056f77c Mon Sep 17 00:00:00 2001 From: Jeppe Fihl-Pearson Date: Fri, 4 Mar 2022 14:03:22 +0000 Subject: [PATCH 4/4] Correct path to dumb-init in docker-entrypoint.sh The path changed after dumb-init was switched to be installed via `apk` rather than downloaded directly as a binary. --- docker-entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 572b270d42..5936a09a19 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/dumb-init /bin/sh +#!/usr/bin/dumb-init /bin/sh set -e # Modified: https://github.com/hashicorp/docker-consul/blob/2c2873f9d619220d1eef0bc46ec78443f55a10b5/0.X/docker-entrypoint.sh