Introduction
In this lab, you will learn how to use the docker container commit command to create new Docker images from existing containers. We will start by launching and modifying a container, then commit those changes to a new image.
You will also explore how to commit container changes with new configurations, including setting new CMD and EXPOSE instructions, demonstrating the flexibility of creating custom images based on running containers.
Start and modify a container
In this step, you will learn how to start a Docker container and make changes inside it. We will use a simple Ubuntu image to demonstrate the process.
First, let's pull the Ubuntu image. This command downloads the Ubuntu image from Docker Hub to your local machine.
docker pull ubuntu:latest
You should see output indicating that the image is being downloaded. Once the download is complete, you can run a container based on this image.
Now, let's run an interactive container using the Ubuntu image. The -it flags are used to allocate a pseudo-TTY and keep stdin open, allowing you to interact with the container's shell. The --name flag assigns a name to the container, making it easier to reference later.
docker run -it --name my-ubuntu ubuntu:latest /bin/bash
After running this command, you will be inside the container's bash shell. You can verify this by checking the hostname, which will be the container ID.
Inside the container, let's create a simple file. We will use the echo command to write some text into a file named hello.txt in the root directory.
echo "Hello from inside the container!" > /hello.txt
You can verify that the file was created and contains the correct content using the cat command.
cat /hello.txt
You should see the output "Hello from inside the container!".
Now that we have made a change inside the container, let's exit the container's shell.
exit
You are now back in your host machine's terminal. The container is still running in the background. You can verify this by listing the running containers.
docker ps
You should see the my-ubuntu container listed.
Commit container changes to a new image
In the previous step, we made a change inside a running container by creating a file. Now, we will learn how to save these changes as a new Docker image. This process is called committing a container.
Committing a container creates a new image that includes the changes you made to the container's filesystem and configuration. This is useful for creating custom images based on existing ones.
To commit the container, we use the docker commit command. The basic syntax is docker commit [container_name] [new_image_name]. We will commit the my-ubuntu container and name the new image my-ubuntu-modified.
docker commit my-ubuntu my-ubuntu-modified
You should see a long string of characters as output, which is the ID of the newly created image.
Now, let's verify that the new image has been created. We can use the docker images command to list all images on your system.
docker images
You should see my-ubuntu-modified listed in the output, along with the original ubuntu image.
To confirm that the changes were saved in the new image, let's run a new container based on my-ubuntu-modified and check for the file we created in the previous step.
docker run -it --name my-ubuntu-test my-ubuntu-modified /bin/bash
Once inside the new container, check for the existence of the /hello.txt file.
cat /hello.txt
You should see the output "Hello from inside the container!", confirming that the changes were successfully committed to the new image.
Now, exit the container.
exit
Finally, let's clean up the test container we just created.
docker rm -f my-ubuntu-test
Commit container changes with new configurations
In this step, we will explore how to commit container changes and also include new configuration settings for the resulting image. This allows you to define aspects like the default command to run when a container starts or environment variables.
We will continue using the my-ubuntu container from the previous steps. First, let's stop the container as we will be committing its current state.
docker stop my-ubuntu
You should see the container name my-ubuntu printed as output, indicating it has been stopped.
Now, let's commit the container and add a label to the new image. Labels are key-value pairs that can be attached to images to add metadata. We will add a label indicating the version of our modified image. We use the -c flag followed by the configuration instruction.
docker commit -c 'LABEL version="1.0"' my-ubuntu my-ubuntu-labeled
You should see the ID of the newly created image as output.
Let's verify that the new image my-ubuntu-labeled has been created and that the label has been applied. We can use the docker inspect command to view detailed information about the image.
docker inspect my-ubuntu-labeled
The output will be a large JSON object. Look for the "Labels" section within the "Config" block. You should find "version": "1.0" listed there.
Alternatively, you can use docker inspect with filtering to specifically check for the label.
docker inspect --format '{{.Config.Labels}}' my-ubuntu-labeled
This command will output only the labels associated with the image. You should see something like map[version:1.0].
We can also add other configurations during the commit process, such as setting an environment variable. Let's commit the my-ubuntu container again, this time adding an environment variable.
docker commit -c 'ENV MY_VARIABLE="Hello Docker"' my-ubuntu my-ubuntu-env
Verify the new image and the environment variable using docker inspect.
docker inspect --format '{{.Config.Env}}' my-ubuntu-env
You should see output similar to [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MY_VARIABLE=Hello Docker], confirming the environment variable is set.
Commit container changes with new CMD and EXPOSE instructions
In this final step, we will learn how to commit container changes and set the default command (CMD) and exposed ports (EXPOSE) for the new image.
The CMD instruction sets the default command that will be executed when a container is started from the image without specifying a command. The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime.
We will commit the my-ubuntu container again, this time setting a default command to print the content of /hello.txt and exposing port 80.
First, ensure the my-ubuntu container is stopped.
docker stop my-ubuntu
Now, commit the container with the CMD and EXPOSE instructions. Note that the CMD instruction is provided as a JSON array of strings.
docker commit -c 'CMD ["cat", "/hello.txt"]' -c 'EXPOSE 80' my-ubuntu my-ubuntu-final
You should see the ID of the newly created image as output.
Let's verify the CMD and EXPOSE configurations of the new image my-ubuntu-final using docker inspect.
docker inspect --format '{{.Config.Cmd}}' my-ubuntu-final
This should output [cat /hello.txt], confirming the default command is set.
Now, let's check the exposed ports.
docker inspect --format '{{.Config.ExposedPorts}}' my-ubuntu-final
You should see output similar to map[80/tcp:{}], indicating that port 80 is exposed.
Finally, let's run a container from this new image without specifying a command to see if the default CMD works.
docker run --rm my-ubuntu-final
The --rm flag automatically removes the container when it exits. Since the default command is cat /hello.txt, the container should run, print "Hello from inside the container!", and then exit.
You should see "Hello from inside the container!" printed to your terminal.
This demonstrates how you can commit container changes and define the default behavior and network configuration of the resulting image.
Summary
In this lab, you learned how to start and modify a Docker container. You pulled an Ubuntu image, ran an interactive container based on it, created a file inside the container, and then exited the container's shell while keeping the container running.
Subsequently, you learned how to commit the changes made inside a running container to create a new Docker image. This process allows you to save the current state of a container as a reusable image.



