-
-
Notifications
You must be signed in to change notification settings - Fork 71
Use Zstd compression for published images to reduce their size and speedup decompression #245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ set +u | |
|
|
||
| DOCKER_TIMEOUT=20 | ||
| DOCKER_PID=-1 | ||
| DOCKER_BUILDX_BUILDER="ha-builder" | ||
| DOCKER_HUB= | ||
| DOCKER_HUB_CHECK=false | ||
| DOCKER_CACHE=true | ||
|
|
@@ -207,6 +208,16 @@ function stop_docker() { | |
| } | ||
|
|
||
|
|
||
| function create_buildx_builder() { | ||
| bashio::log.info "Creating buildx builder: ${DOCKER_BUILDX_BUILDER}..." | ||
| if ! docker inspect "${DOCKER_BUILDX_BUILDER}" >/dev/null 2>&1; then | ||
| if ! docker buildx create --name "${DOCKER_BUILDX_BUILDER}" >/dev/null; then | ||
| bashio::exit.nok "Failed to create buildx builder" | ||
| fi | ||
| fi | ||
| } | ||
|
|
||
|
|
||
| function run_build() { | ||
| local build_dir=$1 | ||
| local repository=$2 | ||
|
|
@@ -218,7 +229,6 @@ function run_build() { | |
| local docker_tags=("${!8}") | ||
| local shadow_repository=${9} | ||
|
|
||
| local push_images=() | ||
| local cache_tag="latest" | ||
| local metadata | ||
| local release="${version}" | ||
|
|
@@ -319,14 +329,41 @@ function run_build() { | |
| dockerfile="${build_dir}/Dockerfile.${build_arch}" | ||
| fi | ||
|
|
||
| # Tag latest | ||
| if bashio::var.true "${DOCKER_LATEST}"; then | ||
| docker_tags+=("latest") | ||
| fi | ||
|
|
||
| # Add additional tags | ||
| for tag_image in "${ADDITIONAL_TAGS[@]}"; do | ||
| docker_tags+=("${tag_image}") | ||
| done | ||
|
|
||
| # Use shadow repository | ||
| if bashio::var.has_value "${shadow_repository}"; then | ||
| shadow_tags=("${shadow_repository}/${image}:${version}") | ||
| for tag_image in "${docker_tags[@]}"; do | ||
| shadow_tags+=("${shadow_repository}/${image}:${tag_image}") | ||
| done | ||
| docker_tags+=("${shadow_tags[@]}") | ||
| fi | ||
|
|
||
| # Tag images | ||
| for tag_image in "${docker_tags[@]}"; do | ||
| docker_cli+=(--tag "${tag_image}") | ||
| done | ||
|
|
||
| # Build image | ||
| bashio::log.info "Run build for ${repository}/${image}:${version} with platform ${docker_platform}" | ||
| ${docker_wrapper} docker buildx build --pull --tag "${repository}/${image}:${version}" \ | ||
| --builder "${DOCKER_BUILDX_BUILDER}" \ | ||
| --platform "${docker_platform}" \ | ||
| --build-arg "BUILD_FROM=${build_from}" \ | ||
| --build-arg "BUILD_VERSION=${version}" \ | ||
| --build-arg "BUILD_ARCH=${build_arch}" \ | ||
| --file "${dockerfile}" \ | ||
| --output "type=image,oci-mediatypes=true,compression=zstd,push=${DOCKER_PUSH}" \ | ||
| --load \ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we push BuildKit, is that even necessary? Maybe it is because of cosign, but cosign has another problem, see below. |
||
| "${docker_cli[@]}" \ | ||
| "${build_dir}" | ||
|
|
||
|
|
@@ -337,61 +374,12 @@ function run_build() { | |
| return 0 | ||
| fi | ||
|
|
||
| push_images+=("${repository}/${image}:${version}") | ||
| bashio::log.info "Finish build for ${repository}/${image}:${version}" | ||
|
|
||
| # Tag latest | ||
| if bashio::var.true "${DOCKER_LATEST}"; then | ||
| docker_tags+=("latest") | ||
| fi | ||
|
|
||
| # Add additional tags | ||
| for tag_image in "${ADDITIONAL_TAGS[@]}"; do | ||
| docker_tags+=("${tag_image}") | ||
| done | ||
|
|
||
| # Tag images | ||
| for tag_image in "${docker_tags[@]}"; do | ||
| bashio::log.info "Create image tag: ${tag_image}" | ||
| docker tag "${repository}/${image}:${version}" "${repository}/${image}:${tag_image}" | ||
| push_images+=("${repository}/${image}:${tag_image}") | ||
| done | ||
|
|
||
| # Use shaddow repository | ||
| if bashio::var.has_value "${shadow_repository}"; then | ||
| bashio::log.info "Generate repository shadow images" | ||
| docker tag "${repository}/${image}:${version}" "${shadow_repository}/${image}:${version}" | ||
| for tag_image in "${docker_tags[@]}"; do | ||
| bashio::log.info "Create shadow-image tag: ${shadow_repository}/${image}:${tag_image}" | ||
| docker tag "${repository}/${image}:${version}" "${shadow_repository}/${image}:${tag_image}" | ||
| push_images+=("${shadow_repository}/${image}:${tag_image}") | ||
| done | ||
| push_images+=("${shadow_repository}/${image}:${version}") | ||
| fi | ||
|
|
||
| # Push images | ||
| if bashio::var.true "${DOCKER_PUSH}"; then | ||
| for i in "${push_images[@]}"; do | ||
| for j in {1..3}; do | ||
| bashio::log.info "Start upload of ${i} (attempt #${j}/3)" | ||
| if docker push "${i}" > /dev/null 2>&1; then | ||
| bashio::log.info "Upload succeeded on attempt #${j}" | ||
| break | ||
| fi | ||
| if [[ "${j}" == "3" ]]; then | ||
| bashio::exit.nok "Upload failed on attempt #${j}" | ||
| else | ||
| bashio::log.warning "Upload failed on attempt #${j}" | ||
| sleep 30 | ||
| fi | ||
| done | ||
| done | ||
|
|
||
| # Singing image (cosign) | ||
| if bashio::var.true "${COSIGN}"; then | ||
| image_digest=$(docker inspect --format='{{index .RepoDigests 0}}' "${repository}/${image}:${version}") | ||
| cosign_sign "${image_digest}" | ||
| fi | ||
| # Sign image (cosign) | ||
| if bashio::var.true "${DOCKER_PUSH}" && bashio::var.true "${COSIGN}"; then | ||
| image_digest=$(docker inspect --format='{{index .RepoDigests 0}}' "${repository}/${image}:${version}") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This stops working with: It does make sense, since we load the image directly from the builder, with that Docker does not know the resulting digest in the repository...
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that this is really a limitation of the graph driver Docker container backend. Using the containerd snapshotter seems to retain the digest By default the containerd snapshotter is not enabled, but this GitHub Action would allow to enable it:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Researching a bit more into it, it seems that containerd snapshotter also supports storing the layers as zstd. From what I understand it will still required buildx to actually create the layer in zstd format, but the import into Docker storage will retain the compression. With that regular docker push can be used to upload zstd compressed layers. It would also make it viable for hassio-addons (refs hassio-addons/workflows#220 (comment)). |
||
| cosign_sign "${image_digest}" | ||
| fi | ||
| } | ||
|
|
||
|
|
@@ -965,6 +953,7 @@ mkdir -p /data | |
| # Setup docker env | ||
| init_crosscompile | ||
| start_docker | ||
| create_buildx_builder | ||
|
|
||
| # Load external repository | ||
| if [ -n "$GIT_REPOSITORY" ]; then | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I was wondering why this is necessary, and now realized this is required so that the
docker-containerBuildKit driver is used. Maybe for clarity lets specify this explicitly here (use--driver docker-container).