โWhen you want to tweak a Docker image but treat its structure like a sacred temple.โ
I had to make a minor update to an existing Docker image โ just a small edit to the /etc/hosts
file. Easy, right?
But hereโs the catch:
ENTRYPOINT
would kick in immediately.Classic case of โsneak in, do the job, leave no trace.โ
/etc/hosts
โ Add a custom host entry.ENTRYPOINT
and CMD
.docker inspect nginx:latest --format='ENTRYPOINT={{json .Config.Entrypoint}} CMD={{json .Config.Cmd}}'
Letโs say the output was:
ENTRYPOINT=["/docker-entrypoint.sh"]
CMD=["nginx","-g","daemon off;"]
docker create --name temp-container --entrypoint /bin/sh nginx:latest
OR
docker run -itd --name temp-container --entrypoint=sh nginx:latest
docker start temp-container
docker exec -it temp-container /bin/sh
Inside the container:
echo "192.168.1.100 mycustomhost" >> /etc/hosts
exit
docker commit --change 'ENTRYPOINT ["/docker-entrypoint.sh"]' \
--change 'CMD ["nginx","-g","daemon off;"]' \
temp-container nginx:latest-new
docker rm -f temp-container
docker inspect nginx:latest-new --format='ENTRYPOINT={{json .Config.Entrypoint}} CMD={{json .Config.Cmd}}'
docker run --rm nginx:latest-new cat /etc/hosts
docker run --rm nginx:latest-new
Hereโs a teaser for a future post: Iโve built a shell script that automates this entire process โ from inspecting to committing โ for any image.
#!/bin/bash
# Usage: ./docker-image-patcher.sh <image-name> <new-image-tag> <host-entry>
# Example: ./docker-image-patcher.sh nginx:latest nginx:patched "192.168.1.100 mycustomhost"
set -e
IMAGE_NAME="$1"
NEW_IMAGE_TAG="$2"
HOST_ENTRY="$3"
if [[ -z "$IMAGE_NAME" || -z "$NEW_IMAGE_TAG" || -z "$HOST_ENTRY" ]]; then
echo "Usage: $0 <image-name> <new-image-tag> <host-entry>"
exit 1
fi
TEMP_CONTAINER="temp-container-$$"
echo "๐ Inspecting original image: $IMAGE_NAME"
ORIGINAL_ENTRYPOINT=$(docker inspect "$IMAGE_NAME" --format='{{json .Config.Entrypoint}}')
ORIGINAL_CMD=$(docker inspect "$IMAGE_NAME" --format='{{json .Config.Cmd}}')
echo "๐ Original ENTRYPOINT: $ORIGINAL_ENTRYPOINT"
echo "๐ Original CMD: $ORIGINAL_CMD"
echo "๐ง Creating temp container: $TEMP_CONTAINER"
docker create --name "$TEMP_CONTAINER" --entrypoint /bin/sh "$IMAGE_NAME" > /dev/null
echo "๐ Starting and patching /etc/hosts"
docker start "$TEMP_CONTAINER" > /dev/null
docker exec "$TEMP_CONTAINER" sh -c "echo '$HOST_ENTRY' >> /etc/hosts"
echo "๐ฆ Committing new image: $NEW_IMAGE_TAG"
docker commit \
--change "ENTRYPOINT $ORIGINAL_ENTRYPOINT" \
--change "CMD $ORIGINAL_CMD" \
"$TEMP_CONTAINER" "$NEW_IMAGE_TAG" > /dev/null
echo "๐งน Cleaning up temp container"
docker rm -f "$TEMP_CONTAINER" > /dev/null
echo "โ
Image $NEW_IMAGE_TAG created with patched /etc/hosts"
Sometimes, the best kind of Docker change is the one thatโs invisible to the rest of your system.
This technique lets you make surgical tweaks without blowing up the imageโs original purpose โ a powerful skill when you're working with shared base images in large CI/CD pipelines.