Pulling the official aws-cli image, I got a huge 374MB image.
docker images | grep amazon
amazon/aws-cli latest abb3d3272080 3 days ago 374MB
It's rather big for a CLI and so I thought: "Maybe I can make it smaller".
Entering Wolfi
Wolfi is a project sponsored by Chainguard. Wolfi is described as:
Wolfi is a stripped-down distro designed for the cloud-native era.
Well, you can think of it like Google's distroless.
The reason I want to select Wolfi is because of a bunch of reasons:
- Better SBOM support. Well, not all the SBOMs are created equally and what's better than building everything from sources and create SBOM from there.
- Multi-arch (amd64, arm64 are must but maybe armv7 as well?)
- Smaller image size.
- Signed and verifiable :)
- Secure. Let's aim for that sweet 0 CVE.
aws-cli v2
aws-cli v2 is powered by a bunch of C project like aws-c-http, aws-c-auth, etc... and so I need to package those first.
What I don't quite understand is AWS's decision to still use Python as frontend for the CLI. And packaging Python packages is like going down the rabbit hole.
I'm going to use melange for packaging. I write melange package's manifest in YAML and melange spits out APK file for me.
Here's what a package build file looks like with melange
package:
name: aws-c-http
version: 0.7.5
epoch: 0
description: AWS C99 implementation of the HTTP/1.1 and HTTP/2 specifications
copyright:
- license: Apache-2.0
environment:
contents:
keyring:
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
repositories:
- https://packages.wolfi.dev/os
- '@local ./packages'
packages:
- aws-c-cal-dev@local
- aws-c-common-dev@local
- aws-c-compression-dev@local
- aws-c-io-dev@local
- build-base
- busybox
- ca-certificates-bundle
- cmake
- s2n-tls-dev@local
- samurai
pipeline:
- uses: fetch
with:
expected-sha512: 90bfd0abfce8727bd4ef6e9a016e6183c2c4349c2d6e4cc02b932f5109ceb3476d79b853e74ca4888b768f44eba9ae953ca5e9b900704a2a3370a200c0168c02
uri: https://github.com/awslabs/aws-c-http/archive/refs/tags/v${{package.version}}.tar.gz
- runs: |
if [ "$CBUILD" != "$CHOST" ]; then
CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux"
fi
CFLAGS="$CFLAGS -flto=auto" \
CXXFLAGS="$CXXFLAGS -flto=auto" \
cmake -B build -G Ninja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INSTALL_LIBDIR=/usr/lib \
-DBUILD_SHARED_LIBS=True \
-DCMAKE_BUILD_TYPE=None \
-DBUILD_TESTING="$(want_check && echo ON || echo OFF)" \
$CMAKE_CROSSOPTS
cmake --build build
- runs: |
DESTDIR="${{targets.destdir}}" cmake --install build
- uses: strip
subpackages:
- name: aws-c-http-dev
pipeline:
- uses: split/dev
- runs: |
mkdir -p "${{targets.subpkgdir}}"/usr/lib
mv "${{targets.destdir}}"/usr/lib/aws-c-http "${{targets.subpkgdir}}"/usr/lib/
dependencies:
runtime:
- aws-c-http
description: aws-c-http dev
I also need to package a bunch of Python libs like py3-certifi
, py3-distro
, etc... because they are not available on Wolfi yet.
Once those are done, I just need to build aws-cli
package, put those APK files in a final image with Chainguard's apko.
Preliminary result
The early result looks very promising. The final image is much smaller. 50% smaller to be precised. And I mean without any optimizations at all. I haven't even split the docs into their own packages yet.
Let's look at it.
186MB vs the original 374MB. A whooping 188MB stripped off from the official aws-cli image. That's 50% size reduction.
Are you sure it's even working :D
Final
I haven't quite done with it yet but you can try it by pulling ghcr.io/tuananh/aws-cli
.
For now, it's still very much work-in-progress so expect things may break here and there :)
Top comments (0)