Docker image size doesn't make sense

I’ve created a ubuntu:bionic base image on my computer. Originally super large size but I deleted 80% of the content by running container and then committing. If I got to root directory and do “du -sh”, it said disk usage 4.5GB. Curious enough, the size of docker image when I do "docker images’ show 11 GB. After pushing to docker hub, I see that it’s 3.34 GB. So I thought perhaps it cleaned up something before compressing? I ran the new image, deleted some more content, commit, and pushed again. This time, “du–sh” said 3.0 GB, “docker images” still said 11GB and docker hub also 3.34 GB. Clearly it is compressing the 11GB file and not the 3.0GB content I’m expecting. Is there a easy way to “clean up” the image?

Docker images consist of image layers. A file created/added in a layer can not be deleted in another layer.
A “deleted” file is only flagged as such and becomes invisible, though in fact it still exists in a lower image layer. It seems that 11GB is the space the image layers occupy in total, though du -sh only sees what the container is able to see, as it only sees the merged filesystem from top down of the stacked layer. Deleted and replaced files still exist in the lower layers.

If you create images, you should use Dockerfiles to describe the image and follow best practices.

I created a new image where I start from same base then copy all artifacts from the 11 gb image, worked like a charm, image now 3.09 gb, after compress 900mb. Used dockerfile to build.