From 783939f439393476fe65a0a2045cba86ea06c7f8 Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Sat, 6 Mar 2021 09:09:17 -0500 Subject: [PATCH] Switch to building from source for multi-platform images (#1) ...so we can support platforms that official releases don't exist for (namely Linux on ARM64). Just building x86_64 and ARM64 for now, so I can work on my M1 mac. --- .github/workflows/build.yml | 78 +++++++++++++++++++++++++++++++++++ .github/workflows/publish.yml | 52 ----------------------- Dockerfile | 63 +++++++++++++++++++--------- 3 files changed, 121 insertions(+), 72 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..414b93d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,78 @@ +name: Build + +on: + push: + branches: + - master + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Prepare + id: prep + env: + HUB_IMAGE: jakejarvis/hugo-extended + GHCR_IMAGE: ghcr.io/jakejarvis/hugo-extended + run: | + TAGS="${HUB_IMAGE}:latest,${GHCR_IMAGE}:latest" + + # If triggered by a new tag, add a version tag to the image + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/v} + TAGS="$TAGS,${HUB_IMAGE}:${VERSION},${GHCR_IMAGE}:${VERSION}" + fi + + # Set output parameters + echo ::set-output name=tags::${TAGS} + + - name: Set up QEMU + uses: docker/setup-qemu-action@master + with: + platforms: all + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@master + + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v1 + with: + username: jakejarvis + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: Login to GitHub Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GHCR_PAT }} + + - name: Build and push + id: build + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ./ + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.prep.outputs.tags }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + + - name: Image digest + run: echo ${{ steps.build.outputs.digest }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index e38d224..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Publish to GitHub Container Registry - -on: - push: - # Publish `v*` tags as releases. - tags: - - v* - pull_request: - -env: - IMAGE_NAME: hugo-extended - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build image - run: docker build . --file Dockerfile - - # Push image to GitHub Container Registry - push: - runs-on: ubuntu-latest - if: github.event_name == 'push' - needs: build - steps: - - uses: actions/checkout@v2 - - name: Build image - run: docker build . --file Dockerfile --tag $IMAGE_NAME - - name: Login to GitHub Container Registry - run: echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - - name: Push image to GitHub - run: | - IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - - # Strip git ref prefix from version - VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') - - # Strip "v" prefix from tag name - [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') - - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - - # Push image with both version tag and `latest` tag - docker tag $IMAGE_NAME $IMAGE_ID:$VERSION - docker tag $IMAGE_NAME $IMAGE_ID:latest - docker push $IMAGE_ID:$VERSION - docker push $IMAGE_ID:latest diff --git a/Dockerfile b/Dockerfile index 88d9584..53ed6bb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ # Hugo doesn't require Go to run, *except* if you're using Hugo Modules. It's # much easier to install Node on the Go base image than vice-versa. -FROM amd64/golang:1.16-alpine +FROM golang:1.16-alpine AS build # the following version can be overridden at image build time with --build-arg ARG HUGO_VERSION=0.81.0 # remove/comment the following line completely to build with vanilla Hugo: -ARG HUGO_EXTENDED=1 +ARG HUGO_BUILD_TAGS=extended LABEL version="${HUGO_VERSION}" LABEL repository="https://github.com/jakejarvis/hugo-docker" @@ -15,8 +15,40 @@ LABEL maintainer="Jake Jarvis " # https://docs.github.com/en/free-pro-team@latest/packages/managing-container-images-with-github-container-registry/connecting-a-repository-to-a-container-image#connecting-a-repository-to-a-container-image-on-the-command-line LABEL org.opencontainers.image.source https://github.com/jakejarvis/hugo-docker -# only install libc6-compat & libstdc++ if we're building extended Hugo -# https://gitlab.com/yaegashi/hugo/commit/22f0d5cbd6114210ba7835468facbdee60609aa2 +ARG CGO=1 +ENV CGO_ENABLED=${CGO} +ENV GOOS=linux +ENV GO111MODULE=on + +WORKDIR /go/src/github.com/gohugoio/hugo + +# gcc/g++ are required to build SASS libraries for extended version +RUN apk update && \ + apk add --no-cache \ + gcc \ + g++ \ + musl-dev && \ + go get github.com/magefile/mage + +RUN wget https://github.com/gohugoio/hugo/archive/v${HUGO_VERSION}.tar.gz && \ + tar xf v${HUGO_VERSION}.tar.gz --strip-components=1 && \ + rm v${HUGO_VERSION}.tar.gz + +RUN mage -v hugo && mage install + +# fix potential stack size problems on Alpine +# https://github.com/microsoft/vscode-dev-containers/blob/fb63f7e016877e13535d4116b458d8f28012e87f/containers/hugo/.devcontainer/Dockerfile#L19 +RUN go get github.com/yaegashi/muslstack && \ + muslstack -s 0x800000 /go/bin/hugo + +# --- + +FROM alpine:3.13 + +COPY --from=build /go/bin/hugo /usr/local/bin/hugo + +# libc6-compat & libstdc++ are required for extended SASS libraries +# ca-certificates are required to fetch outside resources (like Twitter oEmbeds) RUN apk update && \ apk add --no-cache \ ca-certificates \ @@ -24,32 +56,23 @@ RUN apk update && \ nodejs \ npm \ yarn \ + go \ python3 \ py3-pip \ ruby \ - ${HUGO_EXTENDED:+libc6-compat libstdc++} && \ + libc6-compat \ + libstdc++ && \ update-ca-certificates # download Hugo and miscellaneous optional dependencies RUN npm install --global postcss postcss-cli autoprefixer @babel/core @babel/cli && \ - pip3 install --upgrade Pygments==2.* && \ gem install asciidoctor && \ - wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_EXTENDED:+extended_}${HUGO_VERSION}_Linux-64bit.tar.gz && \ - wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_checksums.txt && \ - grep hugo_${HUGO_EXTENDED:+extended_}${HUGO_VERSION}_Linux-64bit.tar.gz hugo_${HUGO_VERSION}_checksums.txt | sha256sum -c && \ - tar xf hugo_${HUGO_EXTENDED:+extended_}${HUGO_VERSION}_Linux-64bit.tar.gz && \ - mv ./hugo /usr/local/bin/ && \ - chmod +x /usr/local/bin/hugo && \ - rm -rf hugo_* LICENSE README.md - -# fix potential stack size problems on Alpine -# https://github.com/microsoft/vscode-dev-containers/blob/fb63f7e016877e13535d4116b458d8f28012e87f/containers/hugo/.devcontainer/Dockerfile#L19 -RUN go get github.com/yaegashi/muslstack && \ - muslstack -s 0x800000 /usr/local/bin/hugo + pip3 install --upgrade Pygments==2.* # verify everything's OK, exit otherwise -RUN hugo version && \ - hugo env && \ +RUN hugo env && \ + go version && \ + node --version && \ postcss --version && \ autoprefixer --version && \ babel --version && \