Docker Community Forums

Share and learn in the Docker community.

Why is `docker commit` not copying this change into a new image?

(Hlubovacdas) #1

The change in question is the one made within a system-protected file, for which the container had to be launched in privileged mode. That change does survive container restarts though, but it does not seem to get carried over to the target image of “docker commit”.


The docker commit command is supposed to persist the complete current state of the file-system of a container (whether running or stopped) and create an image with those contents, which, as a layer, is based on the same image as the said container was launched from. In one particular case, this isn’t working.

Here are steps to reproduce it:

1 - This launches a container based on public "alpine", runs in in privileged mode, because it has to change a system-protected setting (tcp_keepalive_time, from the default 7200 to 300):

docker run --name alpine-tcp -it --privileged --sysctl "net.ipv4.tcp_keepalive_time=300" --entrypoint sh alpine:latest

  • At this point, a shell is presented, and it’s easy to verify the above change: cat /proc/sys/net/ipv4/tcp_keepalive_time.

  • If you were to launch this image without --sysctl "net.ipv4.tcp_keepalive_time=300" argument, and then execute this cat command, you’d get 7200 (instead of 300), which is the default (irrelevant, but it’s a value expressed in seconds, equivalent to 2 hours.

  • Other changes can be made, to demonstrate that docker commit does carry those over; e.g:

touch myfile

adduser test

2 - This command dumps the content of the above created alpine-tcp container into an image, creating one named local/alpine:optimized-tcp:

docker commit alpine-tcp local/alpine:optimized-tcp

3 - This launches another container based on the newly created local/alpine:optimized-tcp image:

docker run --name alpine-tcp-copy -it --rm --entrypoint sh local/alpine:optimized-tcp

  • This new container should now contain all changes created within alpine-tcp container; verify:

ls myfile

id testuser

cat /proc/sys/net/ipv4/tcp_keepalive_time

However, the “keepalive” change prints the default value of 7200, whereas 300 is expected. Why would docker-commit skip this, and is there a work-around? Even though the change is over a specially protected file, it can obviously be read, as the interactive command proves.

Thank you.