feat: benchmark init [SKIP CI]

This commit is contained in:
hadestructhor 2025-01-09 15:01:58 +01:00
parent eae6b8a7c2
commit 5d06ab6d2c
13 changed files with 204 additions and 1 deletions

View file

@ -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
@ -579,3 +597,21 @@ C'est la plus grosse optimisation de taille jusqu'à présent ! Une différence
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.
## 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
View 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 |

77
benchmark.nu Normal file
View file

@ -0,0 +1,77 @@
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, 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
$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, benchmark_size: int> = [
['tag', 'image', 'image size', 'median_time', 'max_time', 'min_time', 'benchmark_size'];
[$'($entry.tag)', $'($entry.image)', $"(docker image ls $entry.image | from ssv | get 0 | get SIZE)", ($sum / $benchmark_size), $max, $min, $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 commit -m $"updated README for benchmarks (date now | format date '%+') [CI SKIP]"
git push
return $benchmark
}

BIN
bun.lockb Normal file

Binary file not shown.

View file

@ -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
1 tag image time
2 bun-rspack-dockerfile react-bun-rspack 18sec 945ms 760µs
3 bun-rspack-dockerfile react-bun-rspack 15sec 918ms 50µs 600ns
4 bun-rspack-dockerfile react-bun-rspack 15sec 230ms 637µs 800ns
5 bun-rspack-dockerfile react-bun-rspack 9sec 915ms 109µs 500ns
6 bun-rspack-dockerfile react-bun-rspack 13sec 563ms 494µs 600ns
7 bun-rspack-dockerfile react-bun-rspack 14sec 284ms 133µs 200ns
8 bun-rspack-dockerfile react-bun-rspack 11sec 952ms 666µs 500ns
9 bun-rspack-dockerfile react-bun-rspack 14sec 395ms 323µs 800ns
10 bun-rspack-dockerfile react-bun-rspack 13sec 495ms 284µs 200ns
11 bun-rspack-dockerfile react-bun-rspack 13sec 558ms 48µs 900ns

View file

@ -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
1 tag image time
2 multi-stage-dockerfile react-multistage 1min 23sec 659ms 190µs 400ns
3 multi-stage-dockerfile react-multistage 1min 20sec 118ms 730µs 900ns
4 multi-stage-dockerfile react-multistage 1min 19sec 993ms 425µs 800ns
5 multi-stage-dockerfile react-multistage 1min 33sec 876ms 590µs 700ns
6 multi-stage-dockerfile react-multistage 1min 22sec 528ms 224µs 200ns
7 multi-stage-dockerfile react-multistage 1min 17sec 523ms 564µs 700ns
8 multi-stage-dockerfile react-multistage 1min 23sec 46ms 176µs 500ns
9 multi-stage-dockerfile react-multistage 1min 21sec 976ms 26µs 700ns
10 multi-stage-dockerfile react-multistage 1min 20sec 387ms 777µs 300ns
11 multi-stage-dockerfile react-multistage 1min 22sec 425ms 531µs 200ns

View file

@ -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
1 tag image time
2 nginx-alpine-dockerfile react-nginx-alpine 1min 15sec 436ms 655µs 500ns
3 nginx-alpine-dockerfile react-nginx-alpine 1min 15sec 692ms 34µs 200ns
4 nginx-alpine-dockerfile react-nginx-alpine 1min 10sec 203ms 169µs 500ns
5 nginx-alpine-dockerfile react-nginx-alpine 1min 14sec 354ms 534µs 200ns
6 nginx-alpine-dockerfile react-nginx-alpine 1min 14sec 178ms 886µs
7 nginx-alpine-dockerfile react-nginx-alpine 1min 16sec 73ms 856µs 500ns
8 nginx-alpine-dockerfile react-nginx-alpine 1min 13sec 502ms 957µs 900ns
9 nginx-alpine-dockerfile react-nginx-alpine 1min 13sec 350ms 748µs 700ns
10 nginx-alpine-dockerfile react-nginx-alpine 1min 13sec 47ms 575µs 400ns
11 nginx-alpine-dockerfile react-nginx-alpine 1min 12sec 72ms 499µs 900ns

View file

@ -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
1 tag image time
2 nginx-distroless-dockerfile react-nginx-distroless 13sec 590ms 676µs 800ns
3 nginx-distroless-dockerfile react-nginx-distroless 13sec 660ms 562µs 900ns
4 nginx-distroless-dockerfile react-nginx-distroless 13sec 904ms 962µs 300ns
5 nginx-distroless-dockerfile react-nginx-distroless 15sec 282ms 358µs 400ns
6 nginx-distroless-dockerfile react-nginx-distroless 14sec 181ms 862µs 300ns
7 nginx-distroless-dockerfile react-nginx-distroless 13sec 546ms 659µs 100ns
8 nginx-distroless-dockerfile react-nginx-distroless 12sec 919ms 500µs 400ns
9 nginx-distroless-dockerfile react-nginx-distroless 14sec 34ms 818µs 600ns
10 nginx-distroless-dockerfile react-nginx-distroless 14sec 105ms 866µs 700ns
11 nginx-distroless-dockerfile react-nginx-distroless 14sec 436ms 202µs

View 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
1 tag image time
2 nginx-dockerfile react-nginx 1min 13sec 875ms 818µs 700ns
3 nginx-dockerfile react-nginx 1min 15sec 156ms 568µs 600ns
4 nginx-dockerfile react-nginx 1min 14sec 561ms 386µs 900ns
5 nginx-dockerfile react-nginx 1min 15sec 940ms 93µs 700ns
6 nginx-dockerfile react-nginx 1min 12sec 368ms 122µs
7 nginx-dockerfile react-nginx 1min 14sec 447ms 551µs 600ns
8 nginx-dockerfile react-nginx 1min 13sec 167ms 516µs 900ns
9 nginx-dockerfile react-nginx 1min 14sec 631ms 928µs 300ns
10 nginx-dockerfile react-nginx 1min 13sec 530ms 822µs 800ns
11 nginx-dockerfile react-nginx 1min 17sec 309ms 34µs 900ns

View file

@ -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
1 tag image time
2 node-alpine-dockerfile react-multistage-alpine 1min 30sec 666ms 11µs 600ns
3 node-alpine-dockerfile react-multistage-alpine 1min 20sec 931ms 109µs 800ns
4 node-alpine-dockerfile react-multistage-alpine 1min 21sec 534ms 917µs
5 node-alpine-dockerfile react-multistage-alpine 1min 22sec 748ms 880µs 100ns
6 node-alpine-dockerfile react-multistage-alpine 1min 19sec 256ms 692µs 300ns
7 node-alpine-dockerfile react-multistage-alpine 1min 20sec 481ms 825µs 400ns
8 node-alpine-dockerfile react-multistage-alpine 1min 19sec 184ms 61µs 300ns
9 node-alpine-dockerfile react-multistage-alpine 1min 21sec 982ms 333µs 700ns
10 node-alpine-dockerfile react-multistage-alpine 1min 19sec 915ms 779µs
11 node-alpine-dockerfile react-multistage-alpine 1min 18sec 671ms 55µs 600ns

View 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
1 tag image time
2 simple-dockerfile react-simple 5min 56sec 870ms 91µs 300ns
3 simple-dockerfile react-simple 4min 17sec 655ms 182µs
4 simple-dockerfile react-simple 1min 45sec 427ms 226µs 700ns
5 simple-dockerfile react-simple 1min 38sec 995ms 239µs 400ns
6 simple-dockerfile react-simple 50sec 807ms 693µs 200ns
7 simple-dockerfile react-simple 42sec 761ms 127µs
8 simple-dockerfile react-simple 46sec 352ms 337µs 200ns
9 simple-dockerfile react-simple 48sec 205ms 438µs
10 simple-dockerfile react-simple 42sec 805ms 61µs 200ns
11 simple-dockerfile react-simple 43sec 612ms 381µs 500ns

View file

@ -0,0 +1,2 @@
tag,image,time
bun-rspack-dockerfile,react-bun-rspack,9sec 220ms 258µs 900ns
1 tag image time
2 bun-rspack-dockerfile react-bun-rspack 9sec 220ms 258µs 900ns

View file

@ -0,0 +1,2 @@
tag,image,time
nginx-distroless-dockerfile,react-nginx-distroless,9sec 221ms 865µs 600ns
1 tag image time
2 nginx-distroless-dockerfile react-nginx-distroless 9sec 221ms 865µs 600ns