Skip to content

Commit bb9f990

Browse files
author
alxndrsn
committed
Dockerignore: convert to whitelist
* 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
1 parent 60b354e commit bb9f990

File tree

3 files changed

+148
-2
lines changed

3 files changed

+148
-2
lines changed

.dockerignore

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,28 @@
1-
node_modules
2-
npm-debug.log
1+
**
2+
3+
!/docs/
4+
!/files/
5+
!/test/files/
6+
7+
!/client/.browserslistrc
8+
!/client/.eslintrc.js
9+
!/client/.tx/config
10+
!/client/icomoon.json
11+
!/client/jsconfig.json
12+
!/client/package.json
13+
!/client/package-lock.json
14+
!/client/vue.config.js
15+
!/client/bin/
16+
!/client/docs/
17+
!/client/public/
18+
!/client/src/
19+
!/client/transifex/
20+
21+
!/server/.npmrc
22+
!/server/package.json
23+
!/server/package-lock.json
24+
!/server/Makefile
25+
!/server/pm2.config.js
26+
!/server/config/
27+
!/server/docs/
28+
!/server/lib/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Test docker context
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
build:
9+
timeout-minutes: 3
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
with:
14+
fetch-depth: 0
15+
fetch-tags: true
16+
submodules: recursive
17+
# Some reasonable boundaries; these may change in future. Numbers outside
18+
# these bounds indicate a misconfiguration, and should be investigated.
19+
- run: ./test/check-docker-context --min-size 2000 --max-size 15000 --min-count 500 --max-count 1000

test/check-docker-context

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/bin/bash -eu
2+
set -o pipefail
3+
log() { echo "[$(basename "$0")] $*"; }
4+
5+
# See: https://stackoverflow.com/a/71751097
6+
7+
while [[ $# -gt 0 ]]; do
8+
case "$1" in
9+
--report) skip_size=true; skip_count=true ;;
10+
11+
--min-size) shift;min_size="$1" ;;
12+
--max-size) shift;max_size="$1" ;;
13+
--skip-size) skip_size=true ;;
14+
15+
--min-count) shift;min_count="$1" ;;
16+
--max-count) shift;max_count="$1" ;;
17+
--skip-count) skip_count=true ;;
18+
19+
*) log "!!! Unrecognised arg: $1"; exit 1 ;;
20+
esac
21+
shift
22+
done
23+
24+
tmp="$(mktemp)"
25+
26+
log "Building docker image..."
27+
(
28+
docker build --no-cache --progress plain --file - . 2>&1 <<EOF
29+
FROM busybox
30+
COPY . /build-context
31+
WORKDIR /build-context
32+
RUN find . -type f
33+
RUN du -s .
34+
EOF
35+
) | tee "$tmp"
36+
37+
vars="$(awk '
38+
/ DONE / { stage="" }
39+
40+
/RUN find \./ { stage="files" }
41+
/RUN du -s .$/ { stage="size" }
42+
43+
stage == "files" { ++file_count }
44+
stage == "size" { total_size=$3 }
45+
46+
/writing image/ { image_hash=$4 }
47+
48+
END {
49+
print "file_count: " file_count "\n"
50+
print "total_size: " total_size "\n"
51+
print "image_hash: " image_hash "\n"
52+
}
53+
' "$tmp")"
54+
55+
56+
file_count="$(echo "$vars" | grep file_count | cut -d: -f2)"
57+
total_size="$(echo "$vars" | grep total_size | cut -d: -f2)"
58+
docker_img="$(echo "$vars" | grep image_hash | cut -d: -f3)"
59+
60+
cleanup() {
61+
log "Removing docker image..."
62+
docker image rm "$docker_img" >/dev/null
63+
}
64+
throw_err() {
65+
log "!!!"
66+
log "!!! $* !!!"
67+
log "!!!"
68+
cleanup
69+
exit 1
70+
}
71+
72+
for_humans() {
73+
local size="$1"
74+
if [[ "$size" -gt 999999 ]]; then
75+
log "$((size / 1000000)) GB"
76+
else
77+
log "$((size / 1000)) MB"
78+
fi
79+
}
80+
81+
log "File count: $file_count"
82+
if [[ "${skip_count-}" != "true" ]]; then
83+
if [[ "$file_count" -lt "$min_count" ]] || [[ "$file_count" -gt "$max_count" ]]; then
84+
throw_err "This is a surprising number of files - expected between $min_count and $max_count"
85+
fi
86+
fi
87+
88+
log "Total size: $(for_humans "$total_size")"
89+
if [[ "${skip_size-}" != "true" ]]; then
90+
# N.B. busybox `du` outputs in kB
91+
# See: https://www.busybox.net/downloads/BusyBox.html#du
92+
expected="- expected between $(for_humans "$min_size") and $(for_humans "$max_size")"
93+
if [[ "$total_size" -lt "$min_size" ]]; then
94+
throw_err "This is a surprisingly small total size $expected"
95+
elif [[ "$total_size" -gt "$max_size" ]]; then
96+
throw_err "This is a surprisingly large total size $expected"
97+
fi
98+
fi
99+
100+
cleanup
101+
log "Everything looks OK."

0 commit comments

Comments
 (0)