diff --git a/Dockerfile b/Dockerfile index 1505b53c83..3c8a602390 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,58 +1,55 @@ +# syntax=docker/dockerfile:1 + # This Dockerfile builds the docs for https://docs.docker.com/ # from the master branch of https://github.com/docker/docker.github.io -# -# Here is the sequence: -# 1. Set up base stages for building and deploying -# 2. Collect and build the reference documentation (from upstream resources) -# 3. Build static HTML from the current branch -# 4. Build the final image, combining the reference docs and current version -# of the documentation -# -# When the image is run, it starts Nginx and serves the docs at port 4000 -# Jekyll environment (development/production) +# Use same ruby version as the one in .ruby-version +# that is used by Netlify +ARG RUBY_VERSION=2.6.10 +# Same as the one in Gemfile.lock +ARG BUNDLER_VERSION=2.3.13 + ARG JEKYLL_ENV=development +ARG DOMAIN=docs.docker.com -# Engine ARG ENGINE_BRANCH="20.10" - -# Distribution ARG DISTRIBUTION_BRANCH="release/2.7" - -# Compose CLI ARG COMPOSE_CLI_BRANCH="main" - -# extensions SDK ARG EXTENSIONS_SDK_BRANCH="main" -### -# Set up base stages for building and deploying -### -FROM starefossen/github-pages:198 AS builderbase -ENV TARGET=/usr/share/nginx/html -WORKDIR /usr/src/app/md_source/ +# Base stage for building +FROM ruby:${RUBY_VERSION}-alpine AS base +WORKDIR /src +RUN apk add --no-cache bash build-base git subversion wget -# Set vars used by fetch-upstream-resources.sh script as an environment variable, -# so that they are persisted in the image for use in later stages. -ARG ENGINE_BRANCH -ENV ENGINE_BRANCH=${ENGINE_BRANCH} +# Gem stage will install bundler used as dependency manager +# for our dependencies in Gemfile for Jekyll +FROM base AS gem +ARG BUNDLER_VERSION +COPY Gemfile* . +RUN gem uninstall -aIx bundler \ + && gem install bundler -v ${BUNDLER_VERSION} \ + && bundle install --jobs 4 --retry 3 -ARG DISTRIBUTION_BRANCH -ENV DISTRIBUTION_BRANCH=${DISTRIBUTION_BRANCH} +# Vendor Gemfile for Jekyll +FROM gem AS vendored +ARG BUNDLER_VERSION +RUN bundle update \ + && mkdir /out \ + && cp Gemfile.lock /out -ARG COMPOSE_CLI_BRANCH -ENV COMPOSE_CLI_BRANCH=${COMPOSE_CLI_BRANCH} - -ARG EXTENSIONS_SDK_BRANCH -ENV EXTENSIONS_SDK_BRANCH=${EXTENSIONS_SDK_BRANCH} +# Stage used to output the vendored Gemfile.lock: +# > make vendor +# or +# > docker buildx bake vendor +FROM scratch AS vendor +COPY --from=vendored /out / # Fetch upstream resources (reference documentation) # Only add the files that are needed to build these reference docs, so that these # docs are only rebuilt if changes were made to ENGINE_BRANCH or DISTRIBUTION_BRANCH. -# Disable caching (docker build --no-cache) to force updating these docs. -FROM alpine AS upstream-resources -RUN apk add --no-cache subversion wget -WORKDIR /usr/src/app/md_source/ +FROM base AS upstream-resources +WORKDIR /out COPY ./_scripts/fetch-upstream-resources.sh ./_scripts/ ARG ENGINE_BRANCH ARG DISTRIBUTION_BRANCH @@ -60,49 +57,59 @@ ARG COMPOSE_CLI_BRANCH ARG EXTENSIONS_SDK_BRANCH RUN ./_scripts/fetch-upstream-resources.sh . - # Build the static HTML for the current docs. # After building with jekyll, fix up some links -FROM builderbase AS current +FROM gem AS generate +ARG JEKYLL_ENV +ARG DOMAIN +ENV TARGET=/out COPY . . -COPY --from=upstream-resources /usr/src/app/md_source/. ./ +COPY --from=upstream-resources /out . +RUN --mount=type=cache,target=/src/.jekyll-cache </#https://docs.docker.com/#' "${TARGET}/sitemap.xml"; \ - else \ - jekyll build --profile -d ${TARGET}; \ - echo '[]' > ${TARGET}/js/metadata.json; \ - fi; \ - find ${TARGET} -type f -name '*.html' | while read i; do sed -i 's#\(]* href="\)https://docs.docker.com/#\1/#g' "$i"; done; +(set -x ; ./_scripts/update-api-toc.sh) +if [ "${JEKYLL_ENV}" = "production" ]; then + ( + set -x + bundle exec jekyll build --profile -d ${TARGET} --config _config.yml,_config_production.yml + sed -i 's#/#https://${DOMAIN}/#' "${TARGET}/sitemap.xml" + ) +else + ( + set -x + bundle exec jekyll build --trace --profile -d ${TARGET} + mkdir -p ${TARGET}/js + echo '[]' > ${TARGET}/js/metadata.json + ) +fi -# This stage only contains the generated files. It can be used to host the -# documentation on a non-containerised service (e.g. to deploy to an s3 bucket). -# When using BuildKit, use the '--output' option to build the files and to copy -# them to your local filesystem. -# -# DOCKER_BUILDKIT=1 docker build --target=deploy-source --output=./_site . -FROM scratch AS deploy-source -COPY --from=current /usr/share/nginx/html / +find ${TARGET} -type f -name '*.html' | while read i; do + sed -i 's#\(]* href="\)https://${DOMAIN}/#\1/#g' "$i" +done +EOT -# Final stage, which includes nginx, and the current docs. -# -# To build current docs: -# DOCKER_BUILDKIT=1 docker build -t docs . +# Release the generated files in a scratch image +# Can be output to your host with: +# > make release +# or +# > docker buildx bake release +FROM scratch AS release +COPY --from=generate /out / + +# Create a runnable nginx instance with generated HTML files. +# When the image is run, it starts Nginx and serves the docs at port 4000: +# > make deploy +# or +# > docker-compose up --build FROM nginx:alpine AS deploy -ENV TARGET=/usr/share/nginx/html -WORKDIR $TARGET - -COPY --from=current /usr/share/nginx/html . - -# Configure NGINX +COPY --from=release / /usr/share/nginx/html COPY _deploy/nginx/default.conf /etc/nginx/conf.d/default.conf ARG JEKYLL_ENV ENV JEKYLL_ENV=${JEKYLL_ENV} CMD echo -e "Docker docs are viewable at:\nhttp://0.0.0.0:4000 (build target: ${JEKYLL_ENV})"; exec nginx -g 'daemon off;' + +FROM deploy diff --git a/Makefile b/Makefile index 9b3c6f1275..f1e20b6022 100644 --- a/Makefile +++ b/Makefile @@ -19,3 +19,19 @@ buildx-yaml: rm -rf ./_data/buildx/* cp -R "$($@_TMP_OUT)"/out/reference/*.yaml ./_data/buildx/ rm -rf $($@_TMP_OUT)/* + +# Build website and output to _site folder +release: + rm -rf _site + $(BUILDX_CMD) bake release + +# Vendor Gemfile.lock +vendor: + $(BUILDX_CMD) bake vendor + +# Deploy website and run it through Docker compose +# Available in your browser at http://localhost:4000 +deploy: + docker compose up --build + +.PHONY: buildx-yaml release vendor deploy diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000000..ac57825290 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,21 @@ +variable "JEKYLL_ENV" { + default = "development" +} + +group "default" { + targets = ["release"] +} + +target "release" { + target = "release" + args = { + JEKYLL_ENV = JEKYLL_ENV + } + no-cache-filter = ["upstream-resources"] + output = ["./_site"] +} + +target "vendor" { + target = "vendor" + output = ["."] +}