Update Docker image when there are no changes to Dockerfile - docker

Let's say I created a docker image using a command like
docker build -t myimage .
In the current directory where I built the image, I have
ls
Dockerfile
myscript.py
Later, I made changes to ONLY the "myscript.py" file. How do I update the image without needing to rebuild?

Related

docker image ls is not showing the installed base images ("FROM" images)

I have the following Dockerfile and as you can see I'm using python:3.10.4 as a base image
FROM python:3.10.4
WORKDIR /app
COPY . .
CMD ["python", "bmi.py"]
After I build the image using docker build the image built successfully and I can see it when I list the images.
however the base image which is python with the tag 3.10.4 is not showing
note that when I build another image of my Dockerfile, I can see from the output that the base image python:3.10.4 is loaded from the cache.
And that means the base image python:3.10.4 is installed and cached successfully but why it is not showing when I list the images, even when I use the -a flag, like the following
docker image ls -a
my docker version is Docker version 20.10.13, build a224086
my OS is windows 10
It looks like you're using Docker buildkit.
While the traditional docker build mechanism would pull referenced images into the local image collection, buildkit has its own caching mechanism and the images it pulls won't show up in the output of docker image ls.

docker image size getting doubled

I have a question about docker. If I do
docker build -t my_image .
(after a few updates)
docker build -t my_image .
Then, the size of my_image is not changed, when I check with 'docker images'.
However, if I do
docker build -t my_image .
docker save -o my_image.tar my_image
(after a few updates)
docker build -t my_image .
then, the size of my image is doubled. It looks like a new image contains both the old and the new one.
Does anybody know why this happens, and how to resolve this issue?
The save -o command should output a .tar file in your directory.
If you in your Dockerfile has something like ADD . /app in it, this saved image will also get added, and the image size be doubled because of it.
What you could do is make sure that you do not add the saved my_image.tar when building the image, either by adding some more selection as to what is included in the image, or by saving the .tar somewhere else.

Modifying a docker image

I have recently started working on docker. I have downloaded a docker image and I want to change it in a way so that I can copy a folder with its contents from my local into that image or may be edit any file in the image.
I thought if I can extract the image somehow, do the changes and then create one image. Not sure if it will work like that. I tried looking for options but couldn't find a promising solution to it.
The current Dockerfile for the image is somewhat like this:
FROM abc/def
MAINTAINER Humpty Dumpty <#hd>
RUN sudo apt-get install -y vim
ADD . /home/humpty-dumpty
WORKDIR /home/humpty-dumpty
RUN cd lib && make
CMD ["bash"]
Note:- I am looking for an easy and clean way to change the existing image only and not to create a new image with the changes.
As an existing docker image cannot be changed what I did was that I created a dockerfile for a new docker image based on my original docker image for its contents and modified it to include test folder from local in the new image.
This link was helpful Build your own image - Docker Documentation
FROM abc/def:latest
The above line in docker file tells Docker which image your image is based on. So, the contents from parent image are copied to new image
Finally, for including the test folder on local drive I added below command in my docker file
COPY test /home/humpty-dumpty/test
and the test folder was added in that new image.
Below is the dockerfile used to create the new image from the existing one.
FROM abc/def:latest
# Extras
RUN sudo apt-get install -y vim
# copies local folder into the image
COPY test /home/humpty-dumpty/test
Update:- For editing a file in the running docker image, we can open that file using vim editor installed through the above docker file
vim <filename>
Now, the vim commands can be used to edit and save the file.
You don't change existing images, images are marked with a checksum and are considered read-only. Containers that use an image point to the same files on the filesystem, adding on their on RW layer for the container, and therefore depend on the image being unchanged. Layer caching also adds to this dependency.
Because of the layered filesystem and caching, creating a new image with just your one folder addition will only add a layer with that addition, and not a full copy of a new image. Therefore, the easy/clean/correct way is to create a new image using a Dockerfile.
First of all, I will not recommend messing with other image. It would be better if you can create your own. Moving forward, You can use copy command to add folder from host machine to the docker image.
COPY <src> <dest>
The only caveat is <src> path must be inside the context of the build; you cannot COPY ../something /something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon.
FROM abc/def
MAINTAINER Humpty Dumpty <#hd>
RUN sudo apt-get install -y vim
// Make sure you already have /home/humpty-dumpty directory
// if not create one
RUN mkdir -p /home/humpty-dumpty
COPY test /home/humpty-dumpty/ // This will add test directory to home/humpty-dumpty
WORKDIR /home/humpty-dumpty
RUN cd lib && make
CMD ["bash"]
I think you can use the docker cp command to make changes to the container which is build from your docker image and then commit the changes.
Here is a reference,
Guide for docker cp:
https://docs.docker.com/engine/reference/commandline/cp/
Guide for docker commit: https://docs.docker.com/engine/reference/commandline/container_commit/
Remember, docker image is a ready only so you cannot make any changes to that. The only way is to modify your docker file and recreate the image but in that case you lose the data(if not mounted on docker volume ). But you can make changes to container which is not ready only.

Are Dockerfiles stored on my machine?

When I run the command:
docker run dockerinaction/hello_world
The first time the following scenario plays out:
The dockerinaction/hello_world Dockerfile can be seen below:
FROM busybox:latest
CMD ["echo", "hello world"]
So from the wording:
Docker searches Docker Hub for the image
There are several things I'm curious about:
Is the image dockerinaction/hello_world?
Does this image reference another image named busybox:latest?
What about the Dockerfile is that on my machine somewhere?
Answers to each bulleted question, in corresponding order:
Yes, the image is dockerinaction/hello_world.
Yes, the image does reference busybox:latest, and builds upon it.
No, the Dockerfile is not stored on your machine. The docker run command is downloading a compressed version of the built Docker image that it found on Docker Hub. In some ways, you can think of the Dockerfile as the source code and the built image as the binary.
If you wanted to, you could write your own Dockerfile with the following contents:
FROM busybox:latest
CMD ["echo", "hello world"]
Then, in the directory containing that file (named Dockerfile), you could:
$ docker build -t my-hello-world:latest .
$ docker run my-hello-world:latest
The docker build command builds the Dockerfile, which in this case is stored on your machine. The built Docker image is tagged as my-hello-world:latest, and is only available on your machine (where it was built) unless you push it somewhere. You can run the built image from your machine by referring to the tag in the docker run command, as in the second line above.

Should files from a base Docker image be present in a derived image?

I'm creating a Dockerfile that uses a base image: dockerfile/rabbitmq.
In the Dockerfile for rabbitmq there's a line to install a script into the image:
ADD bin/rabbitmq-start /usr/local/bin/
In my Dockerfile I don't have this line. I have my own ADD lines.
When I run the image all the rabbitmq binaries and config are there, along with my stuff, but there's no rabbitmq-start script anywhere.
Why isn't it present in my image? (If I run the base image dockerfile/rabbitmq the file is there, of course.) Are ADD's not "inherited" to derived images?
Seems to work for me:
I cloned dockerfile/ubuntu and built that locally,
I cloned dockerfile/rabbitmq and built that locally,
I cloned your repository and built that locally.
Booting a shell in your image:
docker run -it --rm gzoller/world bash
I see both the rabbitmq-start script added by the rabbitmq image as well as the start script installed in your image:
[ root#d0044b91278e:/data ]$ ls /usr/local/bin/
rabbitmq-start start

Resources