-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Misc Docker + Go version upgrade #12921
Conversation
The previous build workflow used emulation to build the Docker image, which results in a somewhat complicated push-by-digest and merge workflow to create a multi-platform image. This commit changes the Docker build to use cross-compilation instead, resulting in a faster and more straightforward build. Signed-off-by: David Karlsson <[email protected]>
4cc240a
to
a1813dc
Compare
@jmooring I have spent some hours today trying to get up to speed re. the current Docker "scene"; I'm reasonably happy but the I wouldn't mind if we as the next step added a On my MacBook Pro M1 the image size increases from 135MB to to 406MB, which I suspect some will complain about, but it's not dramatic enough for me to even consider breaking it up into multiple setups. What do you think? The entrypoint/npm install setup is a little opinionated, but I think it should work. I have tested it would most of my Hugo projects with a What do you think? /cc @dvdksn |
0d16f77
to
6501676
Compare
I'm taking a look at the build failure, looks like something related to cross-comp with the new Dockerfile |
OK so here are some changes that I came up with;
diff --git a/Dockerfile b/Dockerfile
index 6da83a3cc..921215c59 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,14 +2,15 @@
# Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/
+ARG GO_VERSION="1.23.2"
+
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
-FROM --platform=$BUILDPLATFORM golang:1.23.2-alpine AS base
-FROM base AS build
+FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS build
# Set up cross-compilation helpers
COPY --from=xx / /
-
-# gcc/g++ are required to build libsass and libwebp libraries for the extended version.
+RUN apk add clang lld
+ARG TARGETPLATFORM
RUN xx-apk add --no-scripts --no-cache gcc g++
# Optionally set HUGO_BUILD_TAGS to "none" or "nodeploy" when building like so:
@@ -20,7 +21,7 @@ ARG HUGO_BUILD_TAGS="extended"
ENV GOPROXY=https://proxy.golang.org
ENV GOCACHE=/root/.cache/go-build
ENV GOMODCACHE=/go/pkg/mod
-ARG TARGETPLATFORM
+ENV CGO_ENABLED=1
WORKDIR /go/src/github.com/gohugoio/hugo
@@ -36,7 +37,10 @@ RUN --mount=target=. \
xx-verify /usr/bin/hugo
EOT
-FROM base AS final
+FROM golang:${GO_VERSION}-alpine AS final
+
+# libsass and libwebp also require gcc/g++ as runtime dependencies
+RUN apk add --no-scripts --no-cache gcc g++
COPY --from=build /usr/bin/hugo /usr/bin/hugo
@@ -60,8 +64,8 @@ VOLUME /project
WORKDIR /project
USER hugo:hugo
ENV HUGO_CACHEDIR=/cache
-ARG BUILDARCH
-ENV BUILDARCH=${BUILDARCH}
+ARG TARGETARCH
+ENV ARCH=${TARGETARCH/amd64/x64}
COPY scripts/docker scripts/docker
diff --git a/scripts/docker/install_runtimedeps_default.sh b/scripts/docker/install_runtimedeps_default.sh
index 0b6c2c617..4ca88fd67 100755
--- a/scripts/docker/install_runtimedeps_default.sh
+++ b/scripts/docker/install_runtimedeps_default.sh
@@ -4,17 +4,10 @@ set -ex
export DART_SASS_VERSION=1.79.3
-# If $BUILDARCH=arm64, then we need to install the arm64 version of Dart Sass,
-# otherwise we install the x64 version.
-ARCH="x64"
-if [ "$BUILDARCH" = "arm64" ]; then
- ARCH="arm64"
-fi
-
cd /tmp
curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-${ARCH}.tar.gz
ls -ltr
tar -xf dart-sass-${DART_SASS_VERSION}-linux-${ARCH}.tar.gz
rm dart-sass-${DART_SASS_VERSION}-linux-${ARCH}.tar.gz && \
# The dart-sass folder is added to the PATH by the caller.
-mv dart-sass /var/hugo/bin
\ No newline at end of file
+mv dart-sass /var/hugo/bin |
01114fb
to
9de2ec4
Compare
I noticed you pushed some more changes, and I also noticed that the way dart-sass is installed could be improved, e.g. we install edit: I realized my diff doesn't apply after the force pushes, so here's the Dockerfile I have. I have tested the image with (note: to run the server with the Docker image you need to also bind to 0.0.0.0, so the docker run command becomes: # GitHub: https://github.com/gohugoio
# Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/
ARG GO_VERSION="1.23.2"
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS build
# Set up cross-compilation helpers
COPY --from=xx / /
RUN apk add clang lld
ARG TARGETPLATFORM
RUN xx-apk add --no-scripts --no-cache gcc g++
# Optionally set HUGO_BUILD_TAGS to "none" or "nodeploy" when building like so:
# docker build --build-arg HUGO_BUILD_TAGS=nodeploy .
#
# We build the extended version by default.
ARG HUGO_BUILD_TAGS="extended"
ENV GOPROXY=https://proxy.golang.org
ENV GOCACHE=/root/.cache/go-build
ENV GOMODCACHE=/go/pkg/mod
ENV CGO_ENABLED=1
WORKDIR /go/src/github.com/gohugoio/hugo
# For --mount=type=cache the value of target is the default cache id, so
# for the go mod cache it would be good if we could share it with other Go images using the same setup,
# but the go build cache needs to be per platform.
# See this comment: https://github.com/moby/buildkit/issues/1706#issuecomment-702238282
RUN --mount=target=. \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build,id=go-build-$TARGETPLATFORM <<EOT
set -ex
xx-go build -tags "$HUGO_BUILD_TAGS" -ldflags "-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=docker" -o /usr/bin/hugo
xx-verify /usr/bin/hugo
EOT
FROM alpine:latest AS dart-sass
ARG TARGETARCH
ARG ARCH=${TARGETARCH/amd64/x64}
ARG DART_SASS_VERSION=1.79.3
WORKDIR /tmp
RUN apk add --no-cache curl
RUN <<EOT
set -ex
curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-${ARCH}.tar.gz
tar -xf dart-sass-${DART_SASS_VERSION}-linux-${ARCH}.tar.gz
EOT
FROM golang:${GO_VERSION}-alpine AS final
# Install runtime dependencies
RUN apk add --no-cache \
g++ \
gcc \
git \
libc6-compat \
libstdc++ \
nodejs \
npm \
runuser
COPY --from=dart-sass /tmp/dart-sass /var/hugo/bin/dart-sass
COPY --from=build /usr/bin/hugo /usr/bin/hugo
ENV PATH="/var/hugo/bin:/var/hugo/bin/dart-sass:$PATH"
RUN <<EOT
mkdir -p /var/hugo/bin /cache
addgroup -Sg 1000 hugo
adduser -Sg hugo -u 1000 -h /var/hugo hugo
chown -R hugo: /var/hugo /cache
# For the Hugo's Git integration to work.
runuser -u hugo -- git config --global --add safe.directory /project
# See https://github.com/gohugoio/hugo/issues/9810
runuser -u hugo -- git config --global core.quotepath false
EOT
USER hugo:hugo
VOLUME /project
WORKDIR /project
ENV HUGO_CACHEDIR=/cache
RUN sass --version
RUN hugo version
COPY scripts/docker/entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["--help"] |
9de2ec4
to
ef96d96
Compare
@dvdksn thanks for the input; one of my goals of this work is to remove (at least most of) the guess work from the Docker setup (e.g. "It seems like gcc/g++ are also runtime dependencies for libsass and libwebp"; we need a libc implementation, but not the full grown compiler). |
OK, then I think you can just remove
from the Dockerfile above and it should work |
a9cf8bb
to
7c47bd4
Compare
9125f37
to
4dc3c95
Compare
4dc3c95
to
4c3347a
Compare
@bep Support for asciidoc, pandoc, and rst can wait for another day. I think this covers > 95% of use cases. I don't have any opinion on size... I suppose if someone wants something thinner they can grow their own, as many have already done. |
As to the Docker image adjustments, I have tested OK:
hugoDocs
(Go modules, Git etc.) and misc others Go modules setups.ENV HUGO_CACHEDIR=/cache
allowing the Hugo cache to survive builds.On MacOS, an example build line would be:
Starting the server:
This is the entry point file:
If a custom
hugo-docker-entrypoint.sh
script exists in the root of the Hugo project, that script will be executed instead of the default entrypoint script.