Skip to content

Commit

Permalink
Dockerignore: convert to whitelist
Browse files Browse the repository at this point in the history
* convert dockerignore from blacklist-based to whitelist
* decrease docker build context size significantly
* make docker builds less dependent on local state (e.g. local node_modules in submodules)
* add script for checking docker build context
* add CI tests to monitor if surprisingly large changes are made to the build context
  • Loading branch information
alxndrsn committed Oct 5, 2024
1 parent 60b354e commit bb9f990
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
30 changes: 28 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
node_modules
npm-debug.log
**

!/docs/
!/files/
!/test/files/

!/client/.browserslistrc
!/client/.eslintrc.js
!/client/.tx/config
!/client/icomoon.json
!/client/jsconfig.json
!/client/package.json
!/client/package-lock.json
!/client/vue.config.js
!/client/bin/
!/client/docs/
!/client/public/
!/client/src/
!/client/transifex/

!/server/.npmrc
!/server/package.json
!/server/package-lock.json
!/server/Makefile
!/server/pm2.config.js
!/server/config/
!/server/docs/
!/server/lib/
19 changes: 19 additions & 0 deletions .github/workflows/test-docker-context.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Test docker context

on:
push:
pull_request:

jobs:
build:
timeout-minutes: 3
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
submodules: recursive
# Some reasonable boundaries; these may change in future. Numbers outside
# these bounds indicate a misconfiguration, and should be investigated.
- run: ./test/check-docker-context --min-size 2000 --max-size 15000 --min-count 500 --max-count 1000
101 changes: 101 additions & 0 deletions test/check-docker-context
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/bash -eu
set -o pipefail
log() { echo "[$(basename "$0")] $*"; }

# See: https://stackoverflow.com/a/71751097

while [[ $# -gt 0 ]]; do
case "$1" in
--report) skip_size=true; skip_count=true ;;

--min-size) shift;min_size="$1" ;;
--max-size) shift;max_size="$1" ;;
--skip-size) skip_size=true ;;

--min-count) shift;min_count="$1" ;;
--max-count) shift;max_count="$1" ;;
--skip-count) skip_count=true ;;

*) log "!!! Unrecognised arg: $1"; exit 1 ;;
esac
shift
done

tmp="$(mktemp)"

log "Building docker image..."
(
docker build --no-cache --progress plain --file - . 2>&1 <<EOF
FROM busybox
COPY . /build-context
WORKDIR /build-context
RUN find . -type f
RUN du -s .
EOF
) | tee "$tmp"

vars="$(awk '
/ DONE / { stage="" }
/RUN find \./ { stage="files" }
/RUN du -s .$/ { stage="size" }
stage == "files" { ++file_count }
stage == "size" { total_size=$3 }
/writing image/ { image_hash=$4 }
END {
print "file_count: " file_count "\n"
print "total_size: " total_size "\n"
print "image_hash: " image_hash "\n"
}
' "$tmp")"


file_count="$(echo "$vars" | grep file_count | cut -d: -f2)"
total_size="$(echo "$vars" | grep total_size | cut -d: -f2)"
docker_img="$(echo "$vars" | grep image_hash | cut -d: -f3)"

cleanup() {
log "Removing docker image..."
docker image rm "$docker_img" >/dev/null
}
throw_err() {
log "!!!"
log "!!! $* !!!"
log "!!!"
cleanup
exit 1
}

for_humans() {
local size="$1"
if [[ "$size" -gt 999999 ]]; then
log "$((size / 1000000)) GB"
else
log "$((size / 1000)) MB"
fi
}

log "File count: $file_count"
if [[ "${skip_count-}" != "true" ]]; then
if [[ "$file_count" -lt "$min_count" ]] || [[ "$file_count" -gt "$max_count" ]]; then
throw_err "This is a surprising number of files - expected between $min_count and $max_count"
fi
fi

log "Total size: $(for_humans "$total_size")"
if [[ "${skip_size-}" != "true" ]]; then
# N.B. busybox `du` outputs in kB
# See: https://www.busybox.net/downloads/BusyBox.html#du
expected="- expected between $(for_humans "$min_size") and $(for_humans "$max_size")"
if [[ "$total_size" -lt "$min_size" ]]; then
throw_err "This is a surprisingly small total size $expected"
elif [[ "$total_size" -gt "$max_size" ]]; then
throw_err "This is a surprisingly large total size $expected"
fi
fi

cleanup
log "Everything looks OK."

0 comments on commit bb9f990

Please sign in to comment.