Skip to content

Instantly share code, notes, and snippets.

@dotysan
Last active July 16, 2025 21:33
Show Gist options
  • Select an option

  • Save dotysan/ced5c2b24fdc5b52be8c10443473a4ca to your computer and use it in GitHub Desktop.

Select an option

Save dotysan/ced5c2b24fdc5b52be8c10443473a4ca to your computer and use it in GitHub Desktop.
Finds ancient docker images with fake creation and sets to most likely timestamp.
#! /usr/bin/env bash
#
# Finds ancient docker images with fake creation and sets to most likely timestamp.
#
set -e
set -u
set -x
main() {
docker images --format='{{.CreatedAt}}\t{{.ID}}\t{{.Repository}}\t{{.Tag}}' |
grep -v ^2 |
while IFS=$'\t' read -r created iid repo tag
do echo "Found ancient image: $repo:$tag ($iid) created $created"
fix_image_ctime "$repo:$tag" "$iid"
done
}
fix_image_ctime() {
local image="$1"
local old_id="$2"
local lastmt=$(get_last_mtime "$image")
lastmt=$(date -u -d "@$lastmt" +%Y-%m-%dT%H:%M:%SZ)
if [[ $lastmt =~ ^([0-9]{4}-[0-9]{2}-[0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})Z$ ]]
then
local iso_timestamp="$lastmt"
else
echo "ERROR: No timestamp found: $lastmt"
exit 1
fi >&2
mkdir -p image-tmp
docker save "$image" |tar -xf - -C image-tmp
local conf=$(jq --raw-output '.[0].Config' image-tmp/manifest.json)
jq ".created = \"$iso_timestamp\"" "image-tmp/$conf" >new-config.json
local new_digest
read -r new_digest _ < <(sha256sum new-config.json)
local new_conf="blobs/sha256/$new_digest"
mv new-config.json "image-tmp/$new_conf"
jq ".[] |= (.Config = \"$new_conf\")" image-tmp/manifest.json > image-tmp/new-manifest.json
mv image-tmp/new-manifest.json image-tmp/manifest.json
rm "image-tmp/$conf"
tar -C image-tmp -cf - . |docker load
rm -fr image-tmp
docker rmi "$old_id" ||:
}
get_last_mtime() {
local image="$1"
docker run --rm --user 0 --entrypoint /bin/bash "$image" -c \
"TZ=UTC find /var -mount -type f -mmin +1 -printf '%T@\n' |sort -nr |sed 1q"
}
main
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment