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”.
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:
If you were to launch this image without
--sysctl "net.ipv4.tcp_keepalive_time=300"argument, and then execute this
catcommand, 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 commitdoes carry those over; e.g:
2 - This command dumps the content of the above created
alpine-tcp container into an image, creating one named
docker commit alpine-tcp local/alpine:optimized-tcp
3 - This launches another container based on the newly created
docker run --name alpine-tcp-copy -it --rm --entrypoint sh local/alpine:optimized-tcp
- This new container should now contain all changes created within
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.