feat: benchmark init [SKIP CI]
This commit is contained in:
parent
eae6b8a7c2
commit
55137c2b62
14 changed files with 208 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,6 +6,7 @@
|
|||
# Dist
|
||||
node_modules
|
||||
dist/
|
||||
/build_results_*
|
||||
|
||||
# IDE
|
||||
.vscode/*
|
||||
|
|
38
README.md
38
README.md
|
@ -289,6 +289,24 @@ This is the biggest optimization in image size to date! A 1 998,2 MB less than
|
|||
I personally love distroless images. I've seen people say that you can debug them less, and not having basic tools like a shell is contraining, but I personally think it's not needed.
|
||||
You can simply build both a distroless and alpine image of your same code, then when there's a need to debug, scitch the container image for the alpine version. Or even better, use distroless images in production environments and alpines in development environments.
|
||||
|
||||
### Benchmark of build times using docker build --no-cache
|
||||
|
||||
Here's the link to the result of the benchmark made to recreate the image 10 times for each branch that contains each optimization:
|
||||
[benchmark.md](./benchmark.md)
|
||||
|
||||
The nushell script used to generate this benchmark is [benchmark.nu](./benchmark.nu).
|
||||
|
||||
You can execute the following command to run the build 100 times on each branch:
|
||||
```shell
|
||||
nu benchmark.nu 100
|
||||
```
|
||||
|
||||
By default the script runs 5 builds.
|
||||
|
||||
The build results can be found in the folder `build_results` in csv format.
|
||||
|
||||
Each branch that was benchmarked has a file associated named like `simple-dockerfile.csv` for the `simple-dockerfile` branch.
|
||||
|
||||
# Français
|
||||
|
||||
|
||||
|
@ -578,4 +596,22 @@ Et voici la taille des images juste ici :
|
|||
C'est la plus grosse optimisation de taille jusqu'à présent ! Une différence de 1 998,2 MB de moins que l'image original, c'est 63,83 fois plus petit!!! C'est une réduction folle de 98,43% ! Et le meilleur dans tout ça? L'application est beaucoup plus sécurisé !!!!!
|
||||
|
||||
Personnellement j'adore les images distroless. J'ai vu certaines personnes dire qu'elles sont moins débuggable en n'ayant aucun outil basique comme un bash mais je pense que ce n'est pas nécessaire.
|
||||
Vous pouvez tout simplement construire une image alpine et distroless de votre application, puis remplacer votre image distroless par l'alpine pour débugger en cas de bug. Ou encore mieux et ce que je fais personnelelement, utiliser une image alpine en environnement de développement et distroless en production.
|
||||
Vous pouvez tout simplement construire une image alpine et distroless de votre application, puis remplacer votre image distroless par l'alpine pour débugger en cas de bug. Ou encore mieux et ce que je fais personnelelement, utiliser une image alpine en environnement de développement et distroless en production.
|
||||
|
||||
## Benchmark temps de build avec docker build --no-cache
|
||||
|
||||
Voici le lien du benchmark réalisé pour chaque branche en lançant la construction des conteneurs 10 fois:
|
||||
[benchmark.md](./benchmark.md)
|
||||
|
||||
Le script nushell pour générer ce benchmark se trouve dans [benchmark.nu](./benchmark.nu)
|
||||
|
||||
Vous pouvez l'exécuter en lançant la commande suivante, pour lancer 100 build de chaque docker:
|
||||
```shell
|
||||
nu benchmark.nu 100
|
||||
```
|
||||
|
||||
Par défaut le script lance 5 build de chaque image.
|
||||
|
||||
Les résultats de build peuvent être trouvé dans le dossier `build_results` sous le format csv.
|
||||
|
||||
Chaque branche qui a été benchmarké possède un fichier associé sous nommé par exemple `simple-dockerfile.csv` pour la branche `simple-dockerfile`.
|
||||
|
|
9
benchmark.md
Normal file
9
benchmark.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
| tag | image | image size | median_time | max_time | min_time | benchmark_size |
|
||||
| --------------------------- | ----------------------- | ---------- | ----------------------------- | ----------------------------- | ----------------------------- | -------------- |
|
||||
| simple-dockerfile | react-simple | 1.98GB | 1min 49sec 349ms 177µs 750ns | 5min 56sec 870ms 91µs 300ns | 42sec 761ms 127µs | 10 |
|
||||
| multi-stage-dockerfile | react-multistage | 1.59GB | 1min 22sec 553ms 523µs 840ns | 1min 33sec 876ms 590µs 700ns | 1min 17sec 523ms 564µs 700ns | 10 |
|
||||
| node-alpine-dockerfile | react-multistage-alpine | 207MB | 1min 21sec 537ms 266µs 580ns | 1min 30sec 666ms 11µs 600ns | 1min 18sec 671ms 55µs 600ns | 10 |
|
||||
| nginx-dockerfile | react-nginx | 280MB | 1min 14sec 498ms 884µs 440ns | 1min 17sec 309ms 34µs 900ns | 1min 12sec 368ms 122µs | 10 |
|
||||
| nginx-alpine-dockerfile | react-nginx-alpine | 67.7MB | 1min 13sec 791ms 291µs 780ns | 1min 16sec 73ms 856µs 500ns | 1min 10sec 203ms 169µs 500ns | 10 |
|
||||
| bun-rspack-dockerfile | react-bun-rspack | 66.5MB | 14sec 125ms 850µs 910ns | 18sec 945ms 760µs | 9sec 915ms 109µs 500ns | 10 |
|
||||
| nginx-distroless-dockerfile | react-nginx-distroless | 31.8MB | 13sec 966ms 346µs 950ns | 15sec 282ms 358µs 400ns | 12sec 919ms 500µs 400ns | 10 |
|
80
benchmark.nu
Normal file
80
benchmark.nu
Normal file
|
@ -0,0 +1,80 @@
|
|||
def main [benchmark_size:int=5] -> table {
|
||||
let date = date now | format date '%F_%H-%M-%S'
|
||||
let res_dir = $'build_results_($date)'
|
||||
mkdir $res_dir
|
||||
let bench = [
|
||||
['tag', 'image'];
|
||||
['simple-dockerfile', 'react-simple'],
|
||||
['multi-stage-dockerfile', 'react-multistage'],
|
||||
['node-alpine-dockerfile', 'react-multistage-alpine'],
|
||||
['nginx-dockerfile', 'react-nginx'],
|
||||
['nginx-alpine-dockerfile', 'react-nginx-alpine'],
|
||||
['bun-rspack-dockerfile', 'react-bun-rspack'],
|
||||
['nginx-distroless-dockerfile', 'react-nginx-distroless']
|
||||
]
|
||||
|
||||
let images = [
|
||||
'node:18',
|
||||
'node:18-alpine'
|
||||
'nginx',
|
||||
'nginx:stable-alpine',
|
||||
'oven/bun',
|
||||
'cgr.dev/chainguard/nginx'
|
||||
]
|
||||
|
||||
echo 'Pulling all docker images in advance'
|
||||
echo ''
|
||||
|
||||
for entry in $images {
|
||||
docker pull $entry
|
||||
echo ''
|
||||
}
|
||||
echo ''
|
||||
|
||||
mut benchmark: table<tag: string, image: string, 'image size': string, median_time: duration, max_time: duration, min_time: duration, total_time: duration, benchmark_size: int> = []
|
||||
|
||||
for entry: record<tag: string, image:string> in $bench {
|
||||
echo $'Switching to branch ($entry.tag)'
|
||||
echo ''
|
||||
git checkout $entry.tag
|
||||
mut sum = 0ns
|
||||
mut max = 0ns
|
||||
mut min = 0ns
|
||||
mut csv_results = []
|
||||
for i in 1..$benchmark_size {
|
||||
echo $'Build ($i) out of ($benchmark_size) for branch ($entry.tag)'
|
||||
let time = $'(timeit {docker build --no-cache -t $entry.image .})' | into duration
|
||||
docker image rm $'($entry.image)'
|
||||
docker builder prune -af
|
||||
$sum += $time
|
||||
|
||||
if $max == 0ns or $time >= $max {
|
||||
$max = $time
|
||||
}
|
||||
if $min == 0ns or $time <= $min {
|
||||
$min = $time
|
||||
}
|
||||
$csv_results = ($csv_results ++ [['tag', 'image', 'time']; [$entry.tag, $entry.image, $time]])
|
||||
}
|
||||
let row table<tag: string, image: string, 'image size': string, median_time: duration, max_time: duration, min_time: duration, total_time: duration, benchmark_size: int> = [
|
||||
['tag', 'image', 'image size', 'median_time', 'max_time', 'min_time', 'total_time', 'benchmark_size'];
|
||||
[$'($entry.tag)', $'($entry.image)', $"(docker image ls $entry.image | from ssv | get 0 | get SIZE)", ($sum / $benchmark_size), $max, $min, $sum, $benchmark_size]
|
||||
]
|
||||
echo $'Finieshed building ($benchmark_size) images for branch ($entry.tag)'
|
||||
echo $'Results for branch ($entry.tag):'
|
||||
echo $csv_results
|
||||
$benchmark = ($benchmark ++ $row)
|
||||
$csv_results | to csv | save -f $'./($res_dir)/($entry.tag).csv'
|
||||
|
||||
echo ''
|
||||
}
|
||||
|
||||
git checkout main
|
||||
$benchmark | to md --pretty | save -f benchmark.md
|
||||
cp -rf $'./($res_dir)/' $'./build_results'
|
||||
rm -rf $'./($res_dir)'
|
||||
git add .
|
||||
git commit -m $"updated README for benchmarks (date now | format date '%+') [CI SKIP]"
|
||||
git push
|
||||
return $benchmark
|
||||
}
|
BIN
bun.lockb
Normal file
BIN
bun.lockb
Normal file
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
bun-rspack-dockerfile,react-bun-rspack,18sec 945ms 760µs
|
||||
bun-rspack-dockerfile,react-bun-rspack,15sec 918ms 50µs 600ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,15sec 230ms 637µs 800ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,9sec 915ms 109µs 500ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,13sec 563ms 494µs 600ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,14sec 284ms 133µs 200ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,11sec 952ms 666µs 500ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,14sec 395ms 323µs 800ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,13sec 495ms 284µs 200ns
|
||||
bun-rspack-dockerfile,react-bun-rspack,13sec 558ms 48µs 900ns
|
|
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
multi-stage-dockerfile,react-multistage,1min 23sec 659ms 190µs 400ns
|
||||
multi-stage-dockerfile,react-multistage,1min 20sec 118ms 730µs 900ns
|
||||
multi-stage-dockerfile,react-multistage,1min 19sec 993ms 425µs 800ns
|
||||
multi-stage-dockerfile,react-multistage,1min 33sec 876ms 590µs 700ns
|
||||
multi-stage-dockerfile,react-multistage,1min 22sec 528ms 224µs 200ns
|
||||
multi-stage-dockerfile,react-multistage,1min 17sec 523ms 564µs 700ns
|
||||
multi-stage-dockerfile,react-multistage,1min 23sec 46ms 176µs 500ns
|
||||
multi-stage-dockerfile,react-multistage,1min 21sec 976ms 26µs 700ns
|
||||
multi-stage-dockerfile,react-multistage,1min 20sec 387ms 777µs 300ns
|
||||
multi-stage-dockerfile,react-multistage,1min 22sec 425ms 531µs 200ns
|
|
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 15sec 436ms 655µs 500ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 15sec 692ms 34µs 200ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 10sec 203ms 169µs 500ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 14sec 354ms 534µs 200ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 14sec 178ms 886µs
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 16sec 73ms 856µs 500ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 13sec 502ms 957µs 900ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 13sec 350ms 748µs 700ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 13sec 47ms 575µs 400ns
|
||||
nginx-alpine-dockerfile,react-nginx-alpine,1min 12sec 72ms 499µs 900ns
|
|
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,13sec 590ms 676µs 800ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,13sec 660ms 562µs 900ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,13sec 904ms 962µs 300ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,15sec 282ms 358µs 400ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,14sec 181ms 862µs 300ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,13sec 546ms 659µs 100ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,12sec 919ms 500µs 400ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,14sec 34ms 818µs 600ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,14sec 105ms 866µs 700ns
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,14sec 436ms 202µs
|
|
11
test/build_results_2025-01-09_13-42-07/nginx-dockerfile.csv
Normal file
11
test/build_results_2025-01-09_13-42-07/nginx-dockerfile.csv
Normal file
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
nginx-dockerfile,react-nginx,1min 13sec 875ms 818µs 700ns
|
||||
nginx-dockerfile,react-nginx,1min 15sec 156ms 568µs 600ns
|
||||
nginx-dockerfile,react-nginx,1min 14sec 561ms 386µs 900ns
|
||||
nginx-dockerfile,react-nginx,1min 15sec 940ms 93µs 700ns
|
||||
nginx-dockerfile,react-nginx,1min 12sec 368ms 122µs
|
||||
nginx-dockerfile,react-nginx,1min 14sec 447ms 551µs 600ns
|
||||
nginx-dockerfile,react-nginx,1min 13sec 167ms 516µs 900ns
|
||||
nginx-dockerfile,react-nginx,1min 14sec 631ms 928µs 300ns
|
||||
nginx-dockerfile,react-nginx,1min 13sec 530ms 822µs 800ns
|
||||
nginx-dockerfile,react-nginx,1min 17sec 309ms 34µs 900ns
|
|
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 30sec 666ms 11µs 600ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 20sec 931ms 109µs 800ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 21sec 534ms 917µs
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 22sec 748ms 880µs 100ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 19sec 256ms 692µs 300ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 20sec 481ms 825µs 400ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 19sec 184ms 61µs 300ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 21sec 982ms 333µs 700ns
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 19sec 915ms 779µs
|
||||
node-alpine-dockerfile,react-multistage-alpine,1min 18sec 671ms 55µs 600ns
|
|
11
test/build_results_2025-01-09_13-42-07/simple-dockerfile.csv
Normal file
11
test/build_results_2025-01-09_13-42-07/simple-dockerfile.csv
Normal file
|
@ -0,0 +1,11 @@
|
|||
tag,image,time
|
||||
simple-dockerfile,react-simple,5min 56sec 870ms 91µs 300ns
|
||||
simple-dockerfile,react-simple,4min 17sec 655ms 182µs
|
||||
simple-dockerfile,react-simple,1min 45sec 427ms 226µs 700ns
|
||||
simple-dockerfile,react-simple,1min 38sec 995ms 239µs 400ns
|
||||
simple-dockerfile,react-simple,50sec 807ms 693µs 200ns
|
||||
simple-dockerfile,react-simple,42sec 761ms 127µs
|
||||
simple-dockerfile,react-simple,46sec 352ms 337µs 200ns
|
||||
simple-dockerfile,react-simple,48sec 205ms 438µs
|
||||
simple-dockerfile,react-simple,42sec 805ms 61µs 200ns
|
||||
simple-dockerfile,react-simple,43sec 612ms 381µs 500ns
|
|
2
test/bun-rspack-dockerfile.csv
Normal file
2
test/bun-rspack-dockerfile.csv
Normal file
|
@ -0,0 +1,2 @@
|
|||
tag,image,time
|
||||
bun-rspack-dockerfile,react-bun-rspack,9sec 220ms 258µs 900ns
|
|
2
test/nginx-distroless-dockerfile.csv
Normal file
2
test/nginx-distroless-dockerfile.csv
Normal file
|
@ -0,0 +1,2 @@
|
|||
tag,image,time
|
||||
nginx-distroless-dockerfile,react-nginx-distroless,9sec 221ms 865µs 600ns
|
|
Loading…
Reference in a new issue