How do I create a Docker image from a container without configuration changes?
-
I am aware of two ways of creating Docker images:
- Build the image using a Dockerfile
- Use https://docs.docker.com/engine/reference/commandline/commit/ against a running container with changes.
I find changing a Dockerfile each time I need image changes to be awfully inconvenient. Instead I have taken to launching ephemeral containers with
docker run
, installing packages I need on the fly with sudo, then committing the image.I didn't realize however there is a footgun involved in this approach, especially if you frequently use and switch up https://docs.docker.com/engine/reference/commandline/run/ hacks. I launch containers with changing bind mounts, environment variables, differing networks, etc. A lot of that seems to be considered part of the configuration of the container, and is committed in https://docs.docker.com/engine/reference/commandline/commit/ alongside actual filesystem changes.
For example if you do:
docker run --env FOO=BAR --name container_name ubuntu:focal docker commit container_name new_image docker run -it new_image echo $FOO
You will see that the env variable FOO is now a part of new_image.
This creates some awfully confusing situations, as I consider arguments to https://docs.docker.com/engine/reference/commandline/run/ to be as https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#create-ephemeral-containers as the container it creates. I am only concerned about persisting package installs.
I would like to commit just the actual image, just the file system changes. Is there any way to do that?
-
Share us an example of your recurring "image changes". I think your problem is not with docker, is with the architecture of your application.
- Data changes should be handled using a database not the file system.
- Source code changes, should be managed with a git repository and the respective new build, generating a new image version ready to be deployed
- Infrastructure changes should be ... That's what Docker was created for. You should modify the Dockerfile, push the changes, build a new image, etc
- Configurations should be managed with environment variables manually injected at docker run or using some external service like consul, configurator, etc
- If your application needs to upload or download files like images, reports, etc, you should use a specialized service like aws s3, gcp Filestore, some open source, etc
As you can see, you don't need a huge native backup with docker commit.