Skip to content

Commit

Permalink
Upgrade to latest Go version + Some Docker image improvements (note)
Browse files Browse the repository at this point in the history
* Rename /site to /project
* Add ldflags
* Add go and node to the default image
* Add Dart Sass to the default image
* Build the extended version by default
* Add "npm i" install support with custom entry script override
* Adjust cache logic to speed up CGO rebuilds

Closes #12920
See #12885
  • Loading branch information
bep committed Oct 11, 2024
1 parent a3a0001 commit e19b3f5
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ parameters:
defaults: &defaults
resource_class: large
docker:
- image: bepsays/ci-hugoreleaser:1.22300.20000
- image: bepsays/ci-hugoreleaser:1.22300.20200
environment: &buildenv
GOMODCACHE: /root/project/gomodcache
version: 2
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
environment:
<<: [*buildenv]
docker:
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20000
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20200
steps:
- *restore-cache
- &attach-workspace
Expand Down
95 changes: 67 additions & 28 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,95 @@
# Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/

ARG GO_VERSION="1.23.2"
ARG ALPINE_VERSION=3.20

FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS gobuild
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS gorun

FROM --platform=$BUILDPLATFORM golang:1.22.6-alpine AS build

FROM gobuild AS build
# Set up cross-compilation helpers
COPY --from=xx / /
RUN apk add clang lld

# Optionally set HUGO_BUILD_TAGS to "extended" or "nodeploy" when building like so:
# docker build --build-arg HUGO_BUILD_TAGS=extended .
ARG HUGO_BUILD_TAGS="none"
ARG TARGETPLATFORM
RUN xx-apk add --no-scripts --no-cache gcc g++ musl-dev

ARG CGO=1
ENV CGO_ENABLED=${CGO}
ENV GOOS=linux
ENV GO111MODULE=on
# 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 CGO_ENABLED=1
ENV GOPROXY=https://proxy.golang.org
ENV GOCACHE=/root/.cache/go-build
ENV GOMODCACHE=/go/pkg/mod
ARG TARGETPLATFORM

WORKDIR /go/src/github.com/gohugoio/hugo

RUN --mount=src=go.mod,target=go.mod \
--mount=src=go.sum,target=go.sum \
--mount=type=cache,target=/go/pkg/mod \
go mod download

ARG TARGETPLATFORM
# gcc/g++ are required to build SASS libraries for extended version
RUN xx-apk add --no-scripts --no-cache gcc g++ musl-dev git
# 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 <<EOT
--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" -o /usr/bin/hugo
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:3.18
FROM gorun AS final

COPY --from=build /usr/bin/hugo /usr/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 libc6-compat libstdc++ git
# libc6-compat are required for extended libraries (libsass, libwebp).
RUN apk add --no-cache \
libc6-compat \
git \
runuser \
curl \
nodejs \
npm

RUN mkdir -p /var/hugo/bin && \
addgroup -Sg 1000 hugo && \
adduser -Sg hugo -u 1000 -h /var/hugo hugo && \
chown -R hugo: /var/hugo && \
# 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

VOLUME /project
WORKDIR /project
USER hugo:hugo
ENV HUGO_CACHEDIR=/cache
ARG BUILDARCH
ENV BUILDARCH=${BUILDARCH}
ENV PATH="/var/hugo/bin:$PATH"

VOLUME /site
WORKDIR /site
COPY scripts/docker scripts/docker
COPY scripts/docker/entrypoint.sh /entrypoint.sh

# Install default dependencies.
RUN scripts/docker/install_runtimedeps_default.sh
# Update PATH to reflect the new dependencies.
# For more complex setups, we should probably find a way to
# delegate this to the script itself, but this will have to do for now.
# Also, the dart-sass binary is a little special, other binaries can be put/linked
# directly in /var/hugo/bin.
ENV PATH="/var/hugo/bin/dart-sass:$PATH"

RUN hugo version
RUN sass --version

# Expose port for live server
EXPOSE 1313

ENTRYPOINT ["hugo"]
ENTRYPOINT ["/entrypoint.sh"]
CMD ["--help"]

34 changes: 34 additions & 0 deletions notesdocker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
docker run --rm -v .:/project -v $HOME/Library/Caches/hugo_cache:/cache -u $(id -u):$(id -g) testing_bullseye build


docker build -t testing_alpine .

docker run --rm -v .:/project -v $HOME/Library/Caches/hugo_cache:/cache -p 1313:1313 testing_alpine server --bind="0.0.0.0"


This is the entry point file:

```sh
#!/bin/sh

# Check if a custom hugo-docker-entrypoint.sh file exists.
if [ -f hugo-docker-entrypoint.sh ]; then
# Execute the custom entrypoint file.
sh hugo-docker-entrypoint.sh "$@"
exit $?
fi

# Check if a package.json file exists.
if [ -f package.json ]; then
# Check if node_modules exists.
if [ ! -d node_modules ]; then
# Install npm packages.
npm i
fi
fi

exec "hugo" "$@"
```

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.
21 changes: 21 additions & 0 deletions scripts/docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh

# Check if a custom hugo-docker-entrypoint.sh file exists.
if [ -f hugo-docker-entrypoint.sh ]; then
# Execute the custom entrypoint file.
sh hugo-docker-entrypoint.sh "$@"
exit $?
fi

# Check if a package.json file exists.
if [ -f package.json ]; then
# Check if node_modules exists.
if [ ! -d node_modules ]; then
# Install npm packages.
# Note that we deliberately do not use `npm ci` here, as it would fail if the package-lock.json file is not up-to-date,
# which would be the case if you run the container with a different OS or architecture than the one used to create the package-lock.json file.
npm i
fi
fi

exec "hugo" "$@"
20 changes: 20 additions & 0 deletions scripts/docker/install_runtimedeps_default.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh

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

0 comments on commit e19b3f5

Please sign in to comment.