Last active
December 8, 2020 10:00
-
-
Save allex/0f2925a6140c67bf5379d1cddb748af4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# vim: set ft=sh fdm=manual ts=2 sw=2 sts=2 tw=85 et: | |
# ================================================ | |
# Description: A docker build alternative impl, support squash and interactive build | |
# Usage: | |
# $ docker-build -t foo:1.0.0 -f ./Dockerfile --no-cache (all of native build args) | |
# -i interactive mode to maintain intermediate container | |
# Last Modified: Tue Dec 08, 2020 17:57 | |
# Author: Allex Wang ([email protected]) | |
# GistID: 0f2925a6140c67bf5379d1cddb748af4 | |
# GistURL: https://gist.github.com/allex/0f2925a6140c67bf5379d1cddb748af4 | |
# ================================================ | |
set -euE -o pipefail | |
img_name="" | |
interactive=false | |
args=(" ") | |
while [ $# -gt 0 ]; do | |
v=${2-} | |
case "$1" in | |
-t | --tag) | |
img_name=$v | |
shift | |
;; | |
-i | --interactive) | |
interactive=true | |
;; | |
*) | |
args+=("$1") | |
;; | |
esac | |
shift | |
done | |
[ -n "$img_name" ] || { | |
echo >&2 "-t, --tag <img_name> Name and optionally a tag in the 'name:tag' format" | |
exit 1 | |
} | |
eval set -- "${args[@]}" | |
#### Build intermediate image | |
echo "Step 0: Build intermediate image" | |
tmp_img="tmp.$$" | |
{ | |
docker build -t $tmp_img "$@" | |
echo " --> ${tmp_img}" | |
trap '[ -n "$tmp_img" ] && docker rmi -f "$tmp_img" >/dev/null' 0 1 2 3 9 13 15 | |
} | |
#### Squash image layers | |
echo "Step 1: Squash image layers" | |
intermediate_container=`docker run --net host --rm --entrypoint sh -id "$tmp_img" -l` | |
{ | |
echo " --> Running in ${intermediate_container:0:12}" | |
while true; do docker inspect ${intermediate_container} -f '{{.Id}}' &>/dev/null && break; done | |
if ${interactive}; then | |
docker exec -it ${intermediate_container} sh -l || { echo >&2 "build abort."; exit 1; } | |
fi | |
} | |
#### Export as dist image | |
echo "Step 2: Export intermediate container to image '${img_name}'" | |
{ | |
[ -n "${img_name}" ] || { | |
read -p "Enter new image name (in the 'name:tag' format) " img_name || exit 1 | |
} | |
cfg=`docker inspect --format='{{if .Config.Labels}}LABEL {{range $k, $v := .Config.Labels}}{{$k}}="{{$v}}" {{end}}{{end}} | |
{{range .Config.Env}}ENV {{println .}}{{end}} | |
CMD [{{range $i, $v := .Config.Cmd}}{{if $i}}, {{end}}"{{$v}}"{{end}}] | |
ENTRYPOINT [{{range $i, $v := .Config.Entrypoint}}{{if $i}}, {{end}}{{printf "\"%s\"" .}}{{end}}] | |
{{if .Config.Volumes}}VOLUME [{{$index := 0}}{{range $k, $v := .Config.Volumes}}{{if $index}}, {{else}}{{$index = 1}}{{end}}{{printf "\"%s\"" $k}}{{end}}]{{end}} | |
' "${tmp_img}"` | |
cat <<DOC | |
inspect image config: | |
~~~ | |
$cfg | |
~~~ | |
DOC | |
image_id=`docker export ${intermediate_container} | \ | |
docker import -m 'squash build' -c "$cfg" - ${img_name}` | |
echo " --> ${image_id#*:}" | |
} | |
echo "Removing intermediate container ${intermediate_container:0:12}" | |
docker kill ${intermediate_container} >/dev/null | |
docker images |grep "<none>" |awk '{print $3}' |xargs -I{} docker rmi -f {} > /dev/null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment