Skip to content

Commit

Permalink
Merge branch 'docker' into ci
Browse files Browse the repository at this point in the history
  • Loading branch information
rpatterson committed Jun 22, 2024
2 parents 3bff1af + aaa2ec9 commit 3e244ea
Show file tree
Hide file tree
Showing 44 changed files with 1,686 additions and 1,721 deletions.
1 change: 1 addition & 0 deletions .alexrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"host-hostess",
"hostesses-hosts",
"kill",
"color",
"dummy"
]
}
6 changes: 3 additions & 3 deletions .env.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CI_REGISTRY_PASSWORD=${CI_REGISTRY_PASSWORD}
PROJECT_GITHUB_PAT=${PROJECT_GITHUB_PAT}

# Constants specific to this project or checkout used in variable substitutions in
# `./docker-compose*.yml`. Don't change these during the ordinary course of development:
# `./compose*.yml`. Don't change these during the ordinary course of development:
# Capture the path of the checkout directory as seen by the real host running `#
# dockerd` so that following bind volumes have the correct source paths:
CHECKOUT_DIR=${CHECKOUT_DIR}
Expand All @@ -30,6 +30,6 @@ DOCKER_GID=${DOCKER_GID}
DOCKER_DOCKER_PUSHRM_DIGEST=@sha256:812a950e5be7dca26cef33b61eb2076bfcfb6c2a8ec96c126371fc049c3b6608
DOCKER_GITLAB_RELEASE_CLI_DIGEST=@sha256:696013aea0f2a20482800ce3a77341f840d7c7ec17bd78bd555e0bd6c00e4f11
DOCKER_HADOLINT_DIGEST=@sha256:9cef74a390694cdc01dd119cbba9adac5bb6671ce67d8d79eb7ec68f497a3684
DOCKER_PANDOC_DIGEST=@sha256:336f9e79cb3132fa6ff4a497f0953a7e5b71592c16472b7c960eb774dcea9a14
DOCKER_PANDOC_DIGEST=@sha256:108fa6ae7c872fad83064c8b3841dab27b2634496acca14ef95c57694da6de52
DOCKER_REUSE_DIGEST=@sha256:a0dca4eb014908af80608c06de3470b770a9c97f91041777d0c1cfbfeb8709f7
DOCKER_VALE_DIGEST=@sha256:da6a0901858421b282aa8d935e72831c84cebf716ae4e276658e9e5d382fad20
DOCKER_VALE_DIGEST=@sha256:2ae44f1276470dbf9e2f472c30caa9e8b0340f297a0ca7d02f5064d32ad6a35f
8 changes: 8 additions & 0 deletions .vale.ini
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ RedHat.RepeatedWords = error
write-good.Illusions = NO
Vale.Repetition = NO

# Conflicts with `RedHat.TermsWarnings` and `RedHat.TermsWarnings` covers more terms and
# includes replacements:
Microsoft.Avoid = warning


# Exceptions for rules not enforced:

Expand All @@ -100,6 +104,9 @@ RedHat.PassiveVoice = suggestion
# and there are a significant number of cases where there's no good replacement:
write-good.Weasel = warning

# False failures on `HH:MM:SS [AP]M`:
proselint.DateMidnight = warning


# Enforce all other rules not enforced by default:

Expand Down Expand Up @@ -182,3 +189,4 @@ RedHat.ProductCentricWriting = error
Microsoft.URLFormat = error
RedHat.EmDash = error
RedHat.SmartQuotes = error
alex.OCD = error
146 changes: 104 additions & 42 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#
# SPDX-License-Identifier: MIT

# See the note at the bottom about the "Optimal ordering of instructions".


## Image layers shared between all variants.

Expand All @@ -10,54 +12,33 @@ FROM buildpack-deps:stable AS base
# Defensive shell options:
SHELL ["/bin/bash", "-eu", "-o", "pipefail", "-c"]

# Project constants:
ARG PROJECT_NAMESPACE=rpatterson
ARG PROJECT_NAME=project-structure
# Install operating system packages needed for the image `ENDPOINT`. This is the layer
# in `base` with the longest build time:
RUN \
rm -f /etc/apt/apt.conf.d/docker-clean && \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \
>"/etc/apt/apt.conf.d/keep-cache"
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install --no-install-recommends -y "gosu=1.14-1+b6"

# Least volatile layers first:
# Constant layers, those without variable substitution, where changes don't invalidate
# later build caches:

# Image metadata:
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
LABEL org.opencontainers.image.url="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.documentation="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.source="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.title="Project Structure"
LABEL org.opencontainers.image.description="Project structure foundation or template"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.authors="Ross Patterson <me@rpatterson.net>"
LABEL org.opencontainers.image.vendor="rpatterson.net"
LABEL org.opencontainers.image.base.name="docker.io/library/buildpack-deps"
LABEL org.opencontainers.image.base.name="docker.io/library/buildpack-deps:stable"

ENV PROJECT_NAMESPACE="${PROJECT_NAMESPACE}"
ENV PROJECT_NAME="${PROJECT_NAME}"
# Find the same home directory even when run as another user, for example `root`.
ENV HOME="/home/${PROJECT_NAME}"
WORKDIR "${HOME}"
# Container runtime environment:
ENTRYPOINT [ "entrypoint.sh" ]
CMD [ "bash" ]

# Support for a volume to preserve data between runs and share data between variants:
# TEMPLATE: Add other user `${HOME}/` files to preserved.
RUN mkdir -pv "${HOME}/.local/share/${PROJECT_NAME}/" && \
touch "${HOME}/.local/share/${PROJECT_NAME}/bash_history" && \
ln -snv --relative "${HOME}/.local/share/${PROJECT_NAME}/bash_history" \
"${HOME}/.bash_history"

# Put the `ENTRYPOINT` on the `$PATH`
COPY [ "./bin/entrypoint.sh", "/usr/local/bin/" ]

# Install operating system packages needed for the image `ENDPOINT`:
RUN \
rm -f /etc/apt/apt.conf.d/docker-clean && \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \
>"/etc/apt/apt.conf.d/keep-cache"
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install --no-install-recommends -y "gosu=1.14-1+b6"

# Build-time labels:
ARG VERSION=
LABEL org.opencontainers.image.version=${VERSION}


## Container image for use by end users.

Expand All @@ -67,20 +48,101 @@ FROM base AS user
# TEMPLATE: Add image setup specific to the user image, often installable packages built
# from the project.

# Put the `ENTRYPOINT` on the `$PATH`
COPY --link [ "./bin/entrypoint.sh", "/usr/local/bin/" ]

# Constants that create new build layers:
ARG PROJECT_NAMESPACE=rpatterson
ARG PROJECT_NAME=project-structure
ARG VERSION=

# Image metadata:
LABEL org.opencontainers.image.url="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.documentation="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.source="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.version=${VERSION}

# Container runtime environment:
ENV PROJECT_NAMESPACE="${PROJECT_NAMESPACE}"
ENV PROJECT_NAME="${PROJECT_NAME}"
# Find the same home directory even when run as another user, for example `root`.
ENV HOME="/home/${PROJECT_NAME}"
ENV PATH="${HOME}/.local/bin:${PATH}"
WORKDIR "${HOME}"


## Container image for use by developers.

# Stay as close to the user image as possible for build cache efficiency:
# Stay as close to the user image as possible:
FROM base AS devel

# Least volatile layers first:
# TEMPLATE: Add image setup specific to the development for this project type, often at
# least installing development tools.

# Put the `ENTRYPOINT` on the `$PATH`
COPY --link [ "./bin/entrypoint.sh", "/usr/local/bin/" ]

# Constants that create new build layers:
ARG PROJECT_NAMESPACE=rpatterson
ARG PROJECT_NAME=project-structure
ARG VERSION=

# Image metadata:
LABEL org.opencontainers.image.title="Project Structure Development"
LABEL org.opencontainers.image.description="Project structure foundation or template, development image"
LABEL org.opencontainers.image.url="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.documentation="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.source="https://gitlab.com/${PROJECT_NAMESPACE}/${PROJECT_NAME}"
LABEL org.opencontainers.image.version=${VERSION}

# Container runtime environment:
ENV PROJECT_NAMESPACE="${PROJECT_NAMESPACE}"
ENV PROJECT_NAME="${PROJECT_NAME}"
# Find the same home directory even when run as another user, for example `root`.
ENV HOME="/home/${PROJECT_NAME}"
ENV PATH="${HOME}/.local/bin:${PATH}"
# Remain in the checkout `WORKDIR` and make the build tools the default
# command to run.
ENV PATH="${HOME}/.local/bin:${PATH}"
WORKDIR "/usr/local/src/${PROJECT_NAME}/"

# TEMPLATE: Add image setup specific to the development for this project type, often at
# least installing development tools.

## Optimal ordering of instructions:
#
# A `./Dockerfile` serves two purposes. It expresses the parts shared between more than
# one image. It also expresses how to avoid unnecessary image build time. These two
# purposes can conflict.
#
# Some instructions can both affect building the image *and* affect the container at
# runtime, for example `ENV` and `WORKDIR`. The shared `base` image target should place
# higher in the file such instructions that are the same for both the end-user and
# developer images. But that means that any changes to those shared instructions
# invalidate the build cache of later layers, including the layer that installs
# development packages in the developer image. That's the layer with the longest build
# times in most projects.
#
# Minimizing built times is important given that updating the images is often necessary
# in the inner loop of the development cycle. Unnecessary build time there compounds
# into significant lost developer time. It also hurts developers in less quantifiable
# ways, for example frustration, distraction, and so on, that sap focus, creativity and
# productivity. Given that, minimizing build times is more important than avoiding
# repetition.
#
# To that end, the developer image should place at the bottom of layers all cheap,
# short-running instructions where changes invalidate the build layer cache if at all
# possible. If the end-user image should also include those instructions, this means
# repeating them at the bottom of the end-user image layers. Testing confirms these
# instructions invalidate the build cache for later layers:
#
# - `FROM`
# - `SHELL`
# - `RUN`
# - `ARG`
# - `ENV`
# - `WORKDIR`
# - `COPY`
#
# And confirms these instructions do *not* invalidate the build cache:
#
# - `LABEL`
# - `ENTRYPOINT`
# - `CMD`
Loading

0 comments on commit 3e244ea

Please sign in to comment.